public static void RecursionTargetExtensionMethodArgumentsStaticInvocation() { var tree = CSharpSyntaxTree.ParseText(@" namespace N { public static class C { public static int P => M(1, 2); public static int M(this int m, int n) => m + n; } }"); var compilation = CSharpCompilation.Create("test", new[] { tree }); var semanticModel = compilation.GetSemanticModel(tree); Assert.AreEqual(true, semanticModel.TryGetNamedType(tree.FindClassDeclaration("C"), CancellationToken.None, out var type)); using var recursion = Recursion.Borrow(type, semanticModel, CancellationToken.None); var argument = tree.FindArgument("1"); var target = recursion.Target(argument).Value; using var walker1 = UsagesWalker.Borrow(target.Symbol, target.Declaration, semanticModel, CancellationToken.None); Assert.AreEqual("m", string.Join(", ", walker1.Usages)); argument = tree.FindArgument("2"); target = recursion.Target(argument).Value; using var walker2 = UsagesWalker.Borrow(target.Symbol, target.Declaration, semanticModel, CancellationToken.None); Assert.AreEqual("n", string.Join(", ", walker2.Usages)); }
public static void RecursionTargetExtensionMethodArgumentsGeneric() { var tree = CSharpSyntaxTree.ParseText(@" namespace N { public static class C { public static bool P => 1.M<int>(2); public static bool M<T>(this T m, T n) => Equals(m, n); } }"); var compilation = CSharpCompilation.Create("test", new[] { tree }); var semanticModel = compilation.GetSemanticModel(tree); Assert.AreEqual(true, semanticModel.TryGetNamedType(tree.FindClassDeclaration("C"), CancellationToken.None, out var type)); using var recursion = Recursion.Borrow(type, semanticModel, CancellationToken.None); var invocation = tree.FindInvocation("1.M<int>(2"); var invocationTarget = recursion.Target(invocation).Value; using var invocationWalker = UsagesWalker.Borrow(invocationTarget.Symbol, invocationTarget.Declaration, semanticModel, CancellationToken.None); Assert.AreEqual("m", string.Join(", ", invocationWalker.Usages)); var argument = tree.FindArgument("2"); var argumentTarget = recursion.Target(argument).Value; using var argumentWalker = UsagesWalker.Borrow(argumentTarget.Symbol, argumentTarget.Declaration, semanticModel, CancellationToken.None); Assert.AreEqual("n", string.Join(", ", argumentWalker.Usages)); }
internal static bool Returns(LocalOrParameter localOrParameter, SemanticModel semanticModel, CancellationToken cancellationToken) { using var recursion = Recursion.Borrow(localOrParameter.Symbol.ContainingType, semanticModel, cancellationToken); using var walker = UsagesWalker.Borrow(localOrParameter, recursion.SemanticModel, recursion.CancellationToken); foreach (var usage in walker.Usages) { if (Returns(usage, recursion)) { return(true); } } return(false); }
internal static bool Stores(LocalOrParameter localOrParameter, SemanticModel semanticModel, CancellationToken cancellationToken, [NotNullWhen(true)] out ISymbol?container) { using var recursion = Recursion.Borrow(localOrParameter.Symbol.ContainingType, semanticModel, cancellationToken); using var walker = UsagesWalker.Borrow(localOrParameter, semanticModel, cancellationToken); foreach (var usage in walker.Usages) { if (Stores(usage, recursion, out container)) { return(true); } } container = null; return(false); }
internal static bool ShouldDispose(LocalOrParameter localOrParameter, SemanticModel semanticModel, CancellationToken cancellationToken) { if (localOrParameter.Symbol is IParameterSymbol parameter && parameter.RefKind != RefKind.None) { return(false); } using var recursion = Recursion.Borrow(localOrParameter.Symbol.ContainingType, semanticModel, cancellationToken); using var walker = UsagesWalker.Borrow(localOrParameter, semanticModel, cancellationToken); foreach (var usage in walker.Usages) { if (Returns(usage, recursion)) { return(false); } if (Assigns(usage, recursion, out _)) { return(false); } if (Stores(usage, recursion, out _)) { return(false); } if (Disposes(usage, recursion)) { return(false); } if (DisposedByReturnValue(usage, recursion, out _)) { return(false); } } return(true); }
public static void RecursionTargetArgumentGeneric() { var tree = CSharpSyntaxTree.ParseText(@" namespace N { public class C { public int P => this.M<int>(1); public T M<T>(T n) => n; } }"); var compilation = CSharpCompilation.Create("test", new[] { tree }); var semanticModel = compilation.GetSemanticModel(tree); Assert.AreEqual(true, semanticModel.TryGetNamedType(tree.FindClassDeclaration("C"), CancellationToken.None, out var type)); using var recursion = Recursion.Borrow(type, semanticModel, CancellationToken.None); var node = tree.FindArgument("1"); var target = recursion.Target(node).Value; using var walker = UsagesWalker.Borrow(target.Symbol, target.Declaration, semanticModel, CancellationToken.None); Assert.AreEqual("n", string.Join(", ", walker.Usages)); }