@@ -35,6 +35,8 @@ public static void Main ()
3535 SuppressInComplex . Test ( ) ;
3636
3737 StateMachinesOnlyReferencedViaReflection . Test ( ) ;
38+ LocalFunctionsReferencedViaReflection . Test ( ) ;
39+ LambdasReferencedViaReflection . Test ( ) ;
3840
3941 ComplexCases . AsyncBodyCallingMethodWithRequires . Test ( ) ;
4042 ComplexCases . GenericAsyncBodyCallingMethodWithRequires . Test ( ) ;
@@ -1257,7 +1259,7 @@ static void TestSuppressionOnLambdaWithNestedLambda ()
12571259 ( ) => MethodWithRequires ( ) ;
12581260 } ;
12591261
1260- lambda ( ) ; // This will produce a warning since the local function has Requires on it
1262+ lambda ( ) ; // This will produce a warning since the lambda has Requires on it
12611263 }
12621264
12631265 [ RequiresUnreferencedCode ( "Suppress in body" ) ]
@@ -1596,13 +1598,204 @@ static async void TestAsyncOnlyReferencedViaReflectionWhichShouldWarn ()
15961598
15971599 [ ExpectedWarning ( "IL2026" , "Requires to suppress" ) ]
15981600 [ ExpectedWarning ( "IL2026" , "Requires to suppress" ) ]
1599- public static void Test ( )
1601+ // Analyzer doesn't emit additional warnings about reflection access to the compiler-generated
1602+ // state machine members.
1603+ [ ExpectedWarning ( "IL2026" , "Requires to suppress" , ProducedBy = ProducedBy . Trimmer ) ]
1604+ [ ExpectedWarning ( "IL2026" , "Requires to suppress" , ProducedBy = ProducedBy . Trimmer ) ]
1605+ static void TestAll ( )
16001606 {
1601- // This is not a 100% reliable test, since in theory it can be marked in any order and so it could happen that the
1602- // user method is marked before the nested state machine gets marked. But it's the best we can do right now.
1603- // (Note that currently linker will mark the state machine first actually so the test is effective).
16041607 typeof ( StateMachinesOnlyReferencedViaReflection ) . RequiresAll ( ) ;
16051608 }
1609+
1610+ [ ExpectedWarning ( "IL2026" , "Requires to suppress" ) ]
1611+ [ ExpectedWarning ( "IL2026" , "Requires to suppress" ) ]
1612+ // NonPublicMethods doesn't warn for members emitted into compiler-generated state machine types.
1613+ static void TestNonPublicMethods ( )
1614+ {
1615+ typeof ( StateMachinesOnlyReferencedViaReflection ) . RequiresNonPublicMethods ( ) ;
1616+ }
1617+
1618+ public static void Test ( )
1619+ {
1620+ TestAll ( ) ;
1621+ TestNonPublicMethods ( ) ;
1622+ }
1623+ }
1624+
1625+ class LocalFunctionsReferencedViaReflection
1626+ {
1627+ [ ExpectedWarning ( "IL2026" , "--TestLocalFunctionWithRequires--" ) ]
1628+ [ ExpectedWarning ( "IL3002" , "--TestLocalFunctionWithRequires--" , ProducedBy = ProducedBy . Analyzer ) ]
1629+ [ ExpectedWarning ( "IL3050" , "--TestLocalFunctionWithRequires--" , ProducedBy = ProducedBy . Analyzer ) ]
1630+ static void TestLocalFunctionWithRequires ( )
1631+ {
1632+ LocalFunction ( ) ;
1633+
1634+ [ RequiresUnreferencedCode ( "--TestLocalFunctionWithRequires--" ) ]
1635+ [ RequiresAssemblyFiles ( "--TestLocalFunctionWithRequires--" ) ]
1636+ [ RequiresDynamicCode ( "--TestLocalFunctionWithRequires--" ) ]
1637+ void LocalFunction ( ) => MethodWithRequires ( ) ;
1638+ }
1639+
1640+ [ ExpectedWarning ( "IL2026" , "LocalFunction" ) ]
1641+ [ ExpectedWarning ( "IL3002" , "LocalFunction" , ProducedBy = ProducedBy . Analyzer ) ]
1642+ [ ExpectedWarning ( "IL3050" , "LocalFunction" , ProducedBy = ProducedBy . Analyzer ) ]
1643+ static void TestLocalFunctionWithClosureWithRequires ( int p = 0 )
1644+ {
1645+ LocalFunction ( ) ;
1646+
1647+ [ RequiresUnreferencedCode ( "--TestLocalFunctionWithClosureWithRequires--" ) ]
1648+ [ RequiresAssemblyFiles ( "--TestLocalFunctionWithClosureWithRequires--" ) ]
1649+ [ RequiresDynamicCode ( "--TestLocalFunctionWithClosureWithRequires--" ) ]
1650+ void LocalFunction ( ) {
1651+ p ++ ;
1652+ MethodWithRequires ( ) ;
1653+ }
1654+ }
1655+
1656+ [ RequiresUnreferencedCode ( "--TestLocalFunctionInMethodWithRequires--" ) ]
1657+ [ RequiresAssemblyFiles ( "--TestLocalFunctionInMethodWithRequires--" ) ]
1658+ [ RequiresDynamicCode ( "--TestLocalFunctionInMethodWithRequires--" ) ]
1659+ static void TestLocalFunctionInMethodWithRequires ( )
1660+ {
1661+ LocalFunction ( ) ;
1662+
1663+ void LocalFunction ( ) => MethodWithRequires ( ) ;
1664+ }
1665+
1666+ [ RequiresUnreferencedCode ( "--TestLocalFunctionWithClosureInMethodWithRequires--" ) ]
1667+ [ RequiresAssemblyFiles ( "--TestLocalFunctionWithClosureInMethodWithRequires--" ) ]
1668+ [ RequiresDynamicCode ( "--TestLocalFunctionWithClosureInMethodWithRequires--" ) ]
1669+ static void TestLocalFunctionWithClosureInMethodWithRequires ( int p = 0 )
1670+ {
1671+ LocalFunction ( ) ;
1672+
1673+ void LocalFunction ( ) {
1674+ p ++ ;
1675+ MethodWithRequires ( ) ;
1676+ }
1677+ }
1678+
1679+ // Warnings for Reflection access to methods with Requires
1680+ [ ExpectedWarning ( "IL2026" , "--TestLocalFunctionInMethodWithRequires--" ) ]
1681+ [ ExpectedWarning ( "IL2026" , "--TestLocalFunctionWithClosureInMethodWithRequires--" ) ]
1682+ // The linker correctly emits warnings about reflection access to local functions with Requires
1683+ // or which inherit Requires from the containing method. The analyzer doesn't bind to local functions
1684+ // so does not warn here.
1685+ [ ExpectedWarning ( "IL2026" , "--TestLocalFunctionWithRequires--" , ProducedBy = ProducedBy . Trimmer ) ]
1686+ [ ExpectedWarning ( "IL2026" , "--TestLocalFunctionWithClosureWithRequires--" , ProducedBy = ProducedBy . Trimmer ) ]
1687+ [ ExpectedWarning ( "IL2026" , "--TestLocalFunctionInMethodWithRequires--" , ProducedBy = ProducedBy . Trimmer ) ]
1688+ [ ExpectedWarning ( "IL2026" , "--TestLocalFunctionWithClosureInMethodWithRequires--" , ProducedBy = ProducedBy . Trimmer ) ]
1689+ static void TestAll ( )
1690+ {
1691+ typeof ( LocalFunctionsReferencedViaReflection ) . RequiresAll ( ) ;
1692+ }
1693+
1694+ // Warnings for Reflection access to methods with Requires
1695+ [ ExpectedWarning ( "IL2026" , "--TestLocalFunctionInMethodWithRequires--" ) ]
1696+ [ ExpectedWarning ( "IL2026" , "--TestLocalFunctionWithClosureInMethodWithRequires--" ) ]
1697+ // NonPublicMethods warns for local functions not emitted into display classes.
1698+ [ ExpectedWarning ( "IL2026" , "--TestLocalFunctionWithRequires--" , ProducedBy = ProducedBy . Trimmer ) ]
1699+ [ ExpectedWarning ( "IL2026" , "--TestLocalFunctionWithClosureWithRequires--" , ProducedBy = ProducedBy . Trimmer ) ]
1700+ [ ExpectedWarning ( "IL2026" , "--TestLocalFunctionInMethodWithRequires--" , ProducedBy = ProducedBy . Trimmer ) ]
1701+ [ ExpectedWarning ( "IL2026" , "--TestLocalFunctionWithClosureInMethodWithRequires--" , ProducedBy = ProducedBy . Trimmer ) ]
1702+ static void TestNonPublicMethods ( )
1703+ {
1704+ typeof ( LocalFunctionsReferencedViaReflection ) . RequiresNonPublicMethods ( ) ;
1705+ }
1706+
1707+ public static void Test ( )
1708+ {
1709+ TestAll ( ) ;
1710+ TestNonPublicMethods ( ) ;
1711+ }
1712+ }
1713+
1714+ class LambdasReferencedViaReflection
1715+ {
1716+ [ ExpectedWarning ( "IL2026" , "--TestLambdaWithRequires--" ) ]
1717+ [ ExpectedWarning ( "IL3002" , "--TestLambdaWithRequires--" , ProducedBy = ProducedBy . Analyzer ) ]
1718+ [ ExpectedWarning ( "IL3050" , "--TestLambdaWithRequires--" , ProducedBy = ProducedBy . Analyzer ) ]
1719+ static void TestLambdaWithRequires ( )
1720+ {
1721+ var lambda =
1722+ [ RequiresUnreferencedCode ( "--TestLambdaWithRequires--" ) ]
1723+ [ RequiresAssemblyFiles ( "--TestLambdaWithRequires--" ) ]
1724+ [ RequiresDynamicCode ( "--TestLambdaWithRequires--" ) ]
1725+ ( ) => MethodWithRequires ( ) ;
1726+
1727+ lambda ( ) ;
1728+ }
1729+
1730+ [ ExpectedWarning ( "IL2026" , "Lambda" ) ]
1731+ [ ExpectedWarning ( "IL3002" , "Lambda" , ProducedBy = ProducedBy . Analyzer ) ]
1732+ [ ExpectedWarning ( "IL3050" , "Lambda" , ProducedBy = ProducedBy . Analyzer ) ]
1733+ static void TestLambdaWithClosureWithRequires ( int p = 0 )
1734+ {
1735+ var lambda =
1736+ [ RequiresUnreferencedCode ( "--TestLambdaWithClosureWithRequires--" ) ]
1737+ [ RequiresAssemblyFiles ( "--TestLambdaWithClosureWithRequires--" ) ]
1738+ [ RequiresDynamicCode ( "--TestLambdaWithClosureWithRequires--" ) ]
1739+ ( ) => {
1740+ p ++ ;
1741+ MethodWithRequires ( ) ;
1742+ } ;
1743+
1744+ lambda ( ) ;
1745+ }
1746+
1747+ [ RequiresUnreferencedCode ( "--TestLambdaInMethodWithRequires--" ) ]
1748+ [ RequiresAssemblyFiles ( "--TestLambdaInMethodWithRequires--" ) ]
1749+ [ RequiresDynamicCode ( "--TestLambdaInMethodWithRequires--" ) ]
1750+ static void TestLambdaInMethodWithRequires ( )
1751+ {
1752+ var lambda = ( ) => MethodWithRequires ( ) ;
1753+
1754+ lambda ( ) ;
1755+ }
1756+
1757+ [ RequiresUnreferencedCode ( "--TestLambdaWithClosureInMethodWithRequires--" ) ]
1758+ [ RequiresAssemblyFiles ( "--TestLambdaWithClosureInMethodWithRequires--" ) ]
1759+ [ RequiresDynamicCode ( "--TestLambdaWithClosureInMethodWithRequires--" ) ]
1760+ static void TestLambdaWithClosureInMethodWithRequires ( int p = 0 )
1761+ {
1762+ var lambda = ( ) => {
1763+ p ++ ;
1764+ MethodWithRequires ( ) ;
1765+ } ;
1766+
1767+ lambda ( ) ;
1768+ }
1769+
1770+ // Warnings for Reflection access to methods with Requires
1771+ [ ExpectedWarning ( "IL2026" , "--TestLambdaInMethodWithRequires--" ) ]
1772+ [ ExpectedWarning ( "IL2026" , "--TestLambdaWithClosureInMethodWithRequires--" ) ]
1773+ // The linker correctly emits warnings about reflection access to lambdas with Requires
1774+ // or which inherit Requires from the containing method. The analyzer doesn't bind to lambdas
1775+ // so does not warn here.
1776+ [ ExpectedWarning ( "IL2026" , "--TestLambdaWithRequires--" , ProducedBy = ProducedBy . Trimmer ) ]
1777+ [ ExpectedWarning ( "IL2026" , "--TestLambdaWithClosureWithRequires--" , ProducedBy = ProducedBy . Trimmer ) ]
1778+ [ ExpectedWarning ( "IL2026" , "--TestLambdaInMethodWithRequires--" , ProducedBy = ProducedBy . Trimmer ) ]
1779+ [ ExpectedWarning ( "IL2026" , "--TestLambdaWithClosureInMethodWithRequires--" , ProducedBy = ProducedBy . Trimmer ) ]
1780+ static void TestAll ( )
1781+ {
1782+ typeof ( LambdasReferencedViaReflection ) . RequiresAll ( ) ;
1783+ }
1784+
1785+ // Warnings for Reflection access to methods with Requires
1786+ [ ExpectedWarning ( "IL2026" , "--TestLambdaInMethodWithRequires--" ) ]
1787+ [ ExpectedWarning ( "IL2026" , "--TestLambdaWithClosureInMethodWithRequires--" ) ]
1788+ // NonPublicMethods doesn't warn for lambdas emitted into display class types.
1789+ static void TestNonPublicMethods ( )
1790+ {
1791+ typeof ( LambdasReferencedViaReflection ) . RequiresNonPublicMethods ( ) ;
1792+ }
1793+
1794+ public static void Test ( )
1795+ {
1796+ TestAll ( ) ;
1797+ TestNonPublicMethods ( ) ;
1798+ }
16061799 }
16071800
16081801 class ComplexCases
0 commit comments