private static SyntaxNode GetContainingMember(SyntaxNode oldNode) { foreach (var node in oldNode.Ancestors()) { switch (node.Kind()) { case SyntaxKind.ParenthesizedLambdaExpression: case SyntaxKind.SimpleLambdaExpression: case SyntaxKind.AnonymousMethodExpression: if ((node as AnonymousFunctionExpressionSyntax)?.AsyncKeyword.Kind() != SyntaxKind.AsyncKeyword) { return node; } break; case SyntaxKind.MethodDeclaration: if ((node as MethodDeclarationSyntax)?.Modifiers.Any(SyntaxKind.AsyncKeyword) == false) { return node; } break; default: continue; } } return null; }
private static SyntaxNode GetContainingMember(SyntaxNode oldNode) { var parenthesizedLambda = oldNode .Ancestors() .FirstOrDefault(n => n.IsKind(SyntaxKind.ParenthesizedLambdaExpression)); if (parenthesizedLambda != null) { return(parenthesizedLambda); } var simpleLambda = oldNode .Ancestors() .FirstOrDefault(n => n.IsKind(SyntaxKind.SimpleLambdaExpression)); if (simpleLambda != null) { return(simpleLambda); } return(oldNode .Ancestors() .FirstOrDefault(n => n.IsKind(SyntaxKind.MethodDeclaration))); }
/// <summary> /// Returns the full qualifier name of the given syntax node. /// </summary> /// <param name="syntaxNode">SyntaxNode</param> /// <returns>string</returns> private string GetFullQualifierNameOfSyntaxNode(SyntaxNode syntaxNode) { string result = string.Empty; if (syntaxNode == null) { return(result); } SyntaxNode ancestor = null; while ((ancestor = syntaxNode.Ancestors().Where(val => val is ClassDeclarationSyntax).FirstOrDefault()) != null) { result = (ancestor as ClassDeclarationSyntax).Identifier.ValueText + "." + result; syntaxNode = ancestor; } ancestor = null; while ((ancestor = syntaxNode.Ancestors().Where(val => val is NamespaceDeclarationSyntax).FirstOrDefault()) != null) { result = (ancestor as NamespaceDeclarationSyntax).Name + "." + result; syntaxNode = ancestor; } return(result); }
private static bool CheckPublicMethodOrField(SyntaxNode genericType) { var field = genericType?.Ancestors <FieldDeclarationSyntax>().FirstOrDefault(); var method = genericType?.Ancestors <MethodDeclarationSyntax>().FirstOrDefault(); var property = genericType?.Ancestors <PropertyDeclarationSyntax>().FirstOrDefault(); if (field != null) { if (!(field.Modifiers.ToString().Contains(PublicModifier) || field.Modifiers.ToString().Contains(ProtectedModifier))) { return(true); } } if (method != null) { if (!(method.Modifiers.ToString().Contains(PublicModifier) || method.Modifiers.ToString().Contains(ProtectedModifier))) { return(true); } } if (property != null) { if (!(property.Modifiers.ToString().Contains(PublicModifier) || property.Modifiers.ToString().Contains(ProtectedModifier))) { return(true); } } return(false); }
internal static bool IsNested(this SyntaxNode node) { if (node == null) { throw new ArgumentNullException("Object reference not set to an instance of an object"); } return(node.Ancestors().Any() && node.Ancestors().Any(n => n.IsKind(SyntaxKind.ClassDeclaration) || n.IsKind(SyntaxKind.StructDeclaration))); }
public static Maybe <BlockSyntax> GetBodyOfMethodThatContainsExpression(SyntaxNode expression) { return(expression .Ancestors() .OfType <MethodDeclarationSyntax>() .FirstOrNoValue() .ChainValue(x => x.Body) .ValueOrMaybe(() => expression.Ancestors().OfType <AccessorDeclarationSyntax>().FirstOrNoValue() .ChainValue(x => x.Body))); }
protected override bool IsObjectConstructionForTemporaryObject(SyntaxNode node) { if (node == null) { return(false); } SyntaxKind kind = node.Kind(); if (kind != SyntaxKind.ObjectCreationExpression) { return(false); } foreach (SyntaxNode ancestor in node.Ancestors()) { SyntaxKind k = ancestor.Kind(); if (k == SyntaxKind.SimpleAssignmentExpression || k == SyntaxKind.VariableDeclarator) { return(false); } } return(true); }
/// <summary> /// Determines whether the node is being used as part of an expression tree /// i.e. whether it is part of lambda being assigned to System.Linq.Expressions.Expression[TDelegate]. /// This could be a local declaration, an assignment, a field, or a property /// </summary> public static bool IsInExpressionTree(this SyntaxNode node, SemanticModel semanticModel) { // Possible ancestors: // * VariableDeclarationSyntax (for local variable or field), // * PropertyDeclarationSyntax, // * SimpleAssigmentExpression foreach (var n in node.Ancestors()) { switch (n.Kind()) { case SyntaxKind.FromClause: case SyntaxKind.LetClause: case SyntaxKind.JoinClause: case SyntaxKind.JoinIntoClause: case SyntaxKind.WhereClause: case SyntaxKind.OrderByClause: case SyntaxKind.SelectClause: case SyntaxKind.GroupClause: // For those clauses, we don't know how to differentiate an expression tree from a delegate, // so we assume we are in the (more restricted) expression tree return(true); case SyntaxKind.SimpleLambdaExpression: case SyntaxKind.ParenthesizedLambdaExpression: return(semanticModel.GetTypeInfo(n).ConvertedType?.OriginalDefinition.Is(KnownType.System_Linq_Expressions_Expression_T) ?? false); default: continue; } } return(false); }
// Find the Method and Class that uees the MD5 private string FindAncestors(SyntaxNode node) { var ancestors = node.Ancestors(); foreach (var ancestor in ancestors) { var type = ancestor.GetType(); if (type.Equals(typeof(ClassDeclarationSyntax))) { if (node.GetType().Equals(typeof(MethodDeclarationSyntax))) { return((node as MethodDeclarationSyntax).Identifier.Text); } if (node.GetType().Equals(typeof(FieldDeclarationSyntax)) || node.GetType().Equals(typeof(PropertyDeclarationSyntax)) || node.GetType().Equals(typeof(InvocationExpressionSyntax))) { return((ancestor as ClassDeclarationSyntax).Identifier.Text); } } if (type.Equals(typeof(MethodDeclarationSyntax))) { var methodDeclarationSyntax = ancestor as MethodDeclarationSyntax; return(methodDeclarationSyntax.Identifier.Text); } } return(""); }
static IEnumerable <Accessibility> GetPossibleAccessibilities(SemanticModel model, ISymbol member, SyntaxNode declaration, CancellationToken cancellationToken) { IEnumerable <Accessibility> result = null; var containingType = member.ContainingType; if (containingType == null) { result = notContained; } else if (containingType.IsValueType) { result = containedInValueType; } else { result = containedInClass; if (member.IsAccessorMethod()) { var propertyDeclaration = declaration.Ancestors().OfType <PropertyDeclarationSyntax>().FirstOrDefault(); if (propertyDeclaration != null) { var property = model.GetDeclaredSymbol(propertyDeclaration, cancellationToken); result = result.Where(a => a < property.DeclaredAccessibility); } } } return(result.Where(a => a != member.DeclaredAccessibility)); }
private static IEnumerable <NameSyntax> StaticClassesInScope(SyntaxNode node) { foreach (SyntaxNode ancestor in node.Ancestors()) { SyntaxKind kind = ancestor.Kind(); if (kind == SyntaxKind.NamespaceDeclaration) { var namespaceDeclaration = (NamespaceDeclarationSyntax)ancestor; foreach (NameSyntax name in namespaceDeclaration.Usings.StaticClasses()) { yield return(name); } } else if (kind == SyntaxKind.CompilationUnit) { var compilationUnit = (CompilationUnitSyntax)ancestor; foreach (NameSyntax name in compilationUnit.Usings.StaticClasses()) { yield return(name); } } } }
public CodeRefactoring GetRefactoring(IDocument document, TextSpan textSpan, CancellationToken cancellationToken) { SyntaxNode root = (SyntaxNode)document.GetSyntaxRoot(cancellationToken); SyntaxToken token = root.FindToken(textSpan.Start, findInsideTrivia: true); SyntaxNode parent = token.Parent; if (parent == null) { return(null); } // Verify is the selected an if or else token or expression within if condition if (((token.Kind == SyntaxKind.IfKeyword || token.Kind == SyntaxKind.ElseKeyword) && token.Span.Start <= textSpan.End && textSpan.End <= token.Span.End) || (parent.Ancestors().OfType <IfStatementSyntax>().Where(n => n.Condition.DescendantNodesAndSelf().Contains(parent)).Count() != 0)) { IfStatementSyntax ifStatement = parent.FirstAncestorOrSelf <IfStatementSyntax>(); if (ifStatement == null) { return(null); } // If the IfStatement has some errors, then no refactoring should take place if (ifStatement.HasDiagnostics) { return(null); } // If ElseClause is missing, then this refactoring does not apply if (ifStatement.Else == null) { return(null); } // If ElseClause contains another IfStatement, then it should not have another ElseClause, because there are multiple conditions then // Consider: // if (condition) {} else if (second condition) {} else if (third condition) {} if (ifStatement.Else.Statement is IfStatementSyntax) { IfStatementSyntax elseClauseIf = (IfStatementSyntax)ifStatement.Else.Statement; if (elseClauseIf.Else != null) { return(null); } } // Finally, we have suitable candidate for Reverse Conditional // Considers: // (a) if (condition) {} else {} // (b) if (condition) {} else if (second condition) {} return(new CodeRefactoring( new[] { new ReverseConditionalAction(document, ifStatement) } , ifStatement.Condition.Span)); } return(null); }
/// <summary> /// Determines whether the node is being used as part of an expression tree /// i.e. whether it is part of lamba being assigned to System.Linq.Expressions.Expression[TDelegate]. /// This could be a local declaration, an assignment, a field, or a property /// </summary> public static bool IsInExpressionTree(this SyntaxNode node, SemanticModel semanticModel) { // Possible ancestors: // * VariableDeclarationSyntax (for local variable or field), // * PropertyDeclarationSyntax, // * SimpleAssigmentExpression var potentialExpressionNode = node.Ancestors().FirstOrDefault(ancestor => ancestor is VariableDeclarationSyntax || ancestor is PropertyDeclarationSyntax || ancestor is AssignmentExpressionSyntax); SyntaxNode typeIdentifiedNode = null; switch (potentialExpressionNode) { case VariableDeclarationSyntax varDecl: typeIdentifiedNode = varDecl.Type; break; case PropertyDeclarationSyntax propDecl: typeIdentifiedNode = propDecl.Type; break; case AssignmentExpressionSyntax assignExpr: typeIdentifiedNode = assignExpr.Left; break; default: return(false); } return(typeIdentifiedNode?.IsKnownType(KnownType.System_Linq_Expressions_Expression_T, semanticModel) ?? false); }
internal static LocalSymbol MakeLocalSymbolWithEnclosingContext( Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind kind, SyntaxNode nodeToBind, SyntaxNode forbiddenZone) { Debug.Assert( nodeToBind.Kind() == SyntaxKind.CasePatternSwitchLabel || nodeToBind.Kind() == SyntaxKind.ThisConstructorInitializer || nodeToBind.Kind() == SyntaxKind.BaseConstructorInitializer || nodeToBind.Kind() == SyntaxKind.PrimaryConstructorBaseType || // initializer for a record constructor nodeToBind.Kind() == SyntaxKind.SwitchExpressionArm || nodeToBind.Kind() == SyntaxKind.ArgumentList && (nodeToBind.Parent is ConstructorInitializerSyntax || nodeToBind.Parent is PrimaryConstructorBaseTypeSyntax) || nodeToBind.Kind() == SyntaxKind.GotoCaseStatement || // for error recovery nodeToBind.Kind() == SyntaxKind.VariableDeclarator && new[] { SyntaxKind.LocalDeclarationStatement, SyntaxKind.ForStatement, SyntaxKind.UsingStatement, SyntaxKind.FixedStatement }. Contains(nodeToBind.Ancestors().OfType <StatementSyntax>().First().Kind()) || nodeToBind is ExpressionSyntax); Debug.Assert(!(nodeToBind.Kind() == SyntaxKind.SwitchExpressionArm) || nodeBinder is SwitchExpressionArmBinder); // https://github.com/dotnet/roslyn/issues/62039: Allow 'scoped' modifier. return(typeSyntax?.IsVar != false && kind != LocalDeclarationKind.DeclarationExpressionVariable ? new LocalSymbolWithEnclosingContext(containingSymbol, scopeBinder, nodeBinder, typeSyntax, identifierToken, kind, nodeToBind, forbiddenZone) : new SourceLocalSymbol(containingSymbol, scopeBinder, false, typeSyntax, identifierToken, kind, hasScopedModifier: false)); }
protected override bool CanAddImportForType(Diagnostic diagnostic, ref SyntaxNode node) { switch (diagnostic.Id) { case CS0103: case CS0246: case CS0305: case CS0308: case CS0122: case CS0307: case CS0616: case CS1003: case CS1580: case CS1581: break; case CS1002: //// only lookup errors inside ParenthesizedLambdaExpression e.g., () => { ... } if (node.Ancestors().OfType <ParenthesizedLambdaExpressionSyntax>().Any()) { if (node is SimpleNameSyntax) { break; } else if (node is BlockSyntax || node is MemberAccessExpressionSyntax || node is BinaryExpressionSyntax) { var last = node.DescendantNodes().OfType <SimpleNameSyntax>().LastOrDefault(); if (!TryFindStandaloneType(ref node)) { node = node.DescendantNodes().OfType <SimpleNameSyntax>().FirstOrDefault(); } else { node = last; } } } else { return(false); } break; case CS1574: case CS1584: var cref = node as QualifiedCrefSyntax; if (cref != null) { node = cref.Container; } break; default: return(false); } return(TryFindStandaloneType(ref node)); }
private Task <Solution> RemoveConditionAsync(Document document, SyntaxNode root, SyntaxNode statement) { var ifStatement = statement.Ancestors().OfType <IfStatementSyntax>().First(); var blockStatement = ifStatement.Else?.Statement as BlockSyntax; // no else var newRoot = root.RemoveNode(ifStatement, SyntaxRemoveOptions.KeepNoTrivia) .WithAdditionalAnnotations(Formatter.Annotation); // else with braces if (blockStatement != null) { newRoot = root.ReplaceNode(ifStatement, blockStatement.Statements) .WithAdditionalAnnotations(Formatter.Annotation); } // else without braces if (ifStatement.Else != null && blockStatement == null) { newRoot = root.ReplaceNode(ifStatement, ifStatement.Else.Statement) .WithAdditionalAnnotations(Formatter.Annotation); } var newDocument = document.WithSyntaxRoot(newRoot); return(Task.FromResult(newDocument.Project.Solution)); }
/// <summary> /// Make a local variable symbol whose type can be inferred (if necessary) by binding and enclosing construct. /// </summary> internal static LocalSymbol MakeLocalSymbolWithEnclosingContext( Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind kind, SyntaxNode nodeToBind, SyntaxNode forbiddenZone) { Debug.Assert( nodeToBind.Kind() == SyntaxKind.CasePatternSwitchLabel || nodeToBind.Kind() == SyntaxKind.ThisConstructorInitializer || nodeToBind.Kind() == SyntaxKind.BaseConstructorInitializer || nodeToBind.Kind() == SyntaxKind.SwitchExpressionArm || nodeToBind.Kind() == SyntaxKind.ArgumentList && nodeToBind.Parent is ConstructorInitializerSyntax || nodeToBind.Kind() == SyntaxKind.VariableDeclarator && new[] { SyntaxKind.LocalDeclarationStatement, SyntaxKind.ForStatement, SyntaxKind.UsingStatement, SyntaxKind.FixedStatement }. Contains(nodeToBind.Ancestors().OfType <StatementSyntax>().First().Kind()) || nodeToBind is ExpressionSyntax); Debug.Assert(!(nodeToBind.Kind() == SyntaxKind.SwitchExpressionArm) || nodeBinder is SwitchExpressionArmBinder); return(typeSyntax?.IsVar != false && kind != LocalDeclarationKind.DeclarationExpressionVariable ? new LocalSymbolWithEnclosingContext(containingSymbol, scopeBinder, nodeBinder, typeSyntax, identifierToken, kind, nodeToBind, forbiddenZone) : new SourceLocalSymbol(containingSymbol, scopeBinder, false, typeSyntax, identifierToken, kind)); }
public SyntaxTriviaList GetLeadingWhiteSpaceForExpression(SyntaxNode nearbyNode) { string _tabSpace = " "; SyntaxTriviaList leadingWhiteSpace; //SyntaxTriviaList endingWhiteSpace; if (nearbyNode == null) { return(new SyntaxTriviaList()); } SyntaxNode parentBlock = null; if (!(nearbyNode is BlockSyntax)) { parentBlock = nearbyNode.Ancestors().FirstOrDefault(x => x is BlockSyntax); } else { parentBlock = nearbyNode; } if (parentBlock == null) { return(nearbyNode.GetTrailingTrivia()); } leadingWhiteSpace = parentBlock.GetLeadingTrivia() .Where(t => t.Kind() == SyntaxKind.WhitespaceTrivia) .ToSyntaxTriviaList() .Add(SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, _tabSpace)); return(leadingWhiteSpace); //if (nearbyNode == null) // return new SyntaxTriviaList(); //if (nearbyNode.Kind() == SyntaxKind.PropertyDeclaration || // nearbyNode.Kind() == SyntaxKind.MethodDeclaration || // nearbyNode.Kind() == SyntaxKind.FieldDeclaration || // nearbyNode.Kind() == SyntaxKind.ConstructorDeclaration //) //{ // leadingWhiteSpace = nearbyNode.GetLeadingTrivia().Where(t => // t.Kind() == SyntaxKind.WhitespaceTrivia).ToSyntaxTriviaList(); // //endingWhiteSpace = addingTo.GetTrailingTrivia().Where(t => // // t.Kind() == SyntaxKind.WhitespaceTrivia).ToSyntaxTriviaList(); //} //else //{ // leadingWhiteSpace = nearbyNode.GetLeadingTrivia() // .Where(t => t.Kind() == SyntaxKind.WhitespaceTrivia) // .ToSyntaxTriviaList() // .Add(SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, _tabSpace)); // //endingWhiteSpace = addingTo.GetTrailingTrivia().Where(t => // // t.Kind() == SyntaxKind.WhitespaceTrivia).ToSyntaxTriviaList(); //} //return leadingWhiteSpace; }
/// <summary> /// Ancestors /// </summary> public static IList <T> Ancestors <T>(this SyntaxNode syntaxNode) { return(syntaxNode? .Ancestors()? .OfType <T>() .ToList()); }
private static void AddNode(ItemCollection items, SyntaxNode node, string prefix) { var tooltip = string.Join(Environment.NewLine, node.GetDiagnostics().Select(x => x.ToString())); var treeViewItem = new TreeViewItem { Background = (node.ContainsDiagnostics) ? Brushes.Pink : Brushes.Transparent, Foreground = (node.IsToken) ? Brushes.DarkGreen : (node.Ancestors().Any(a => a.IsToken) ? Brushes.DarkRed : Brushes.Blue), Header = $"{prefix}{node.Kind} [{node.SourceRange.Start}..{node.SourceRange.End})", ToolTip = string.IsNullOrEmpty(tooltip) ? null : tooltip, Tag = node }; foreach (var childNode in node.ChildNodes) { AddNode(treeViewItem.Items, childNode, string.Empty); } if (node.IsToken) { var token = (SyntaxToken)node; foreach (var childNode in token.LeadingTrivia) { AddNode(treeViewItem.Items, childNode, "Lead: "); } foreach (var childNode in token.TrailingTrivia) { AddNode(treeViewItem.Items, childNode, "Trail: "); } } items.Add(treeViewItem); }
public static bool IsInDebugInvocation(this SyntaxNode node, SemanticModel sm) { return(node.Ancestors().Any((parent) => { if (parent is ThrowStatementSyntax) { return true; } if (parent is InvocationExpressionSyntax) { var method = sm.GetSymbolInfo(parent).Symbol as IMethodSymbol; var type = method?.ContainingType; if ((type?.Name?.Equals("Debug") == true && type?.ContainingNamespace?.ToString().Equals("UnityEngine") == true) || (type?.Name?.Equals("ILogSystem") == true && type?.ContainingNamespace?.ToString().Equals("X2Interface") == true)) { return true; } } return false; })); }
private static SyntaxNode GetContainingMember(SyntaxNode oldNode) { foreach (var node in oldNode.Ancestors()) { switch (node.Kind()) { case SyntaxKind.ParenthesizedLambdaExpression: case SyntaxKind.SimpleLambdaExpression: case SyntaxKind.AnonymousMethodExpression: if ((node as AnonymousFunctionExpressionSyntax)?.AsyncKeyword.Kind() != SyntaxKind.AsyncKeyword) { return(node); } break; case SyntaxKind.MethodDeclaration: if ((node as MethodDeclarationSyntax)?.Modifiers.Any(SyntaxKind.AsyncKeyword) == false) { return(node); } break; default: continue; } } return(null); }
public static SyntaxNode GetContainingMethod(this SyntaxNode node) { if (node == null) { throw new ArgumentNullException(nameof(node)); } foreach (SyntaxNode ancestor in node.Ancestors()) { switch (ancestor.Kind()) { case SyntaxKind.MethodDeclaration: case SyntaxKind.SimpleLambdaExpression: case SyntaxKind.ParenthesizedLambdaExpression: case SyntaxKind.AnonymousMethodExpression: { return(ancestor); } case SyntaxKind.PropertyDeclaration: case SyntaxKind.IndexerDeclaration: case SyntaxKind.ConstructorDeclaration: case SyntaxKind.DestructorDeclaration: case SyntaxKind.EventDeclaration: case SyntaxKind.ConversionOperatorDeclaration: case SyntaxKind.OperatorDeclaration: case SyntaxKind.IncompleteMember: { break; } } } return(null); }
public override void Visit(SyntaxNode node) { var padding = node.Ancestors().Count(); var prepend = node.ChildNodes().Any() ? "[-]" : "[.]"; var nodetype = node.GetType().FullName; if (nodetype.StartsWith(prefix)) { nodetype = nodetype.Substring(prefix.Length); } var line = new string(' ', padding) + prepend + " " + nodetype; Console.WriteLine(line); //var decl = node as ClassDeclarationSyntax; //if (decl != null && decl.BaseList != null) //{ // Console.Write(new string(' ', padding + 4) + decl.Identifier); // foreach (var n in decl.BaseList.Types.OfType<IdentifierNameSyntax>()) // { // Console.Write(" " + n.Identifier); // } // Console.WriteLine(); //} var attr = node as AttributeSyntax; if (attr != null) { Console.WriteLine(new string(' ', padding + 4) + "> " + attr.Name); foreach (var arg in attr.ArgumentList.Arguments) { var expr = arg.Expression as LiteralExpressionSyntax; //Console.WriteLine(new string(' ', padding + 4) + "> " + arg.NameColon + " " + arg.NameEquals); Console.WriteLine(new string(' ', padding + 4) + "> " + (expr == null ? null : expr.Token.Value)); } } var attr2 = node as IdentifierNameSyntax; if (attr2 != null) { Console.WriteLine(new string(' ', padding + 4) + "T " + attr2.Identifier.GetType()); Console.WriteLine(new string(' ', padding + 4) + "V " + attr2.Identifier); } var x = node as TypeSyntax; if (x != null) { var xtype = x.GetType().FullName; if (xtype.StartsWith(prefix)) { xtype = nodetype.Substring(prefix.Length); } Console.WriteLine(new string(' ', padding + 4) + "> " + xtype); } base.Visit(node); }
static IEnumerable <Using> CheckUsings(SyntaxNode syntaxNode) { var compilationUnit = syntaxNode.Ancestors() .OfType <CompilationUnitSyntax>() .FirstOrDefault(); return(compilationUnit.Usings.Select(y => new Using(y.Name.ToString(), y.Alias?.ToString()))); }
protected override SyntaxNode FindSiblingNodeForReadonlySubstitute(SyntaxNode creationExpression) { var typeDeclarationSyntax = creationExpression.Ancestors() .OfType <TypeDeclarationSyntax>() .FirstOrDefault(); return(typeDeclarationSyntax?.Members.FirstOrDefault()); }
private static bool HasFieldAnsiConsole(SyntaxNode syntaxNode) { var isStatic = syntaxNode .Ancestors() .OfType <MethodDeclarationSyntax>() .First() .Modifiers.Any(i => i.Kind() == SyntaxKind.StaticKeyword); return(syntaxNode .Ancestors().OfType <ClassDeclarationSyntax>() .First() .Members .OfType <FieldDeclarationSyntax>() .Any(i => i.Declaration.Type.NormalizeWhitespace().ToString() == "IAnsiConsole" && (!isStatic ^ i.Modifiers.Any(modifier => modifier.Kind() == SyntaxKind.StaticKeyword)))); }
private static bool HasParameterAnsiConsole(SyntaxNode syntaxNode) { return(syntaxNode .Ancestors().OfType <MethodDeclarationSyntax>() .First() .ParameterList.Parameters .Any(i => i.Type.NormalizeWhitespace().ToString() == "IAnsiConsole")); }
public void AnalyzeNode(SyntaxNode node, SemanticModel semanticModel, Action <Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken) { if (node.Ancestors(). Any(ancestorNode => ancestorNode is ForStatementSyntax || ancestorNode is ForEachStatementSyntax)) { addDiagnostic(Diagnostic.Create(Rule, node.GetLocation())); } }
static IEnumerable <Using> CheckUsings(SyntaxNode syntaxNode) { var compilationUnit = syntaxNode.Ancestors() .OfType <CompilationUnitSyntax>() .FirstOrDefault(); var importClauses = compilationUnit.Imports.SelectMany(x => x.ImportsClauses).OfType <SimpleImportsClauseSyntax>(); return(importClauses.Select(y => new Using(y.Name.ToString(), y.Alias?.ToString()))); }
public static bool IsDescendantOf(this SyntaxNode node, SyntaxKind kind, bool ascendOutOfTrivia = true) { if (node == null) { throw new ArgumentNullException(nameof(node)); } return(node.Ancestors(ascendOutOfTrivia).Any(f => f.IsKind(kind))); }
public override void Visit(SyntaxNode node) { int padding = node.Ancestors().Count(); //To identify leaf nodes vs nodes with children string prepend = node.ChildNodes().Any() ? "[-]" : "[.]"; //Get the type of the node string line = new String(' ', padding) + prepend + " " + node.GetType().ToString(); //Write the line System.Console.WriteLine(line); base.Visit(node); }
/// <summary> /// Try to get the method declaration that is outside of the given node. /// </summary> /// <param name="node"></param> /// <returns></returns> public static SyntaxNode TryGetOutsideMethod(SyntaxNode node) { var methods = node.Ancestors().OfType<MethodDeclarationSyntax>().ToList(); if (methods.Any()) { return methods.First(); } return null; }
/// <summary> /// Make a local variable symbol whose type can be inferred (if necessary) by binding and enclosing construct. /// </summary> internal static LocalSymbol MakeLocalSymbolWithEnclosingContext( Symbol containingSymbol, Binder scopeBinder, Binder nodeBinder, TypeSyntax typeSyntax, SyntaxToken identifierToken, LocalDeclarationKind kind, SyntaxNode nodeToBind, SyntaxNode forbiddenZone) { Debug.Assert( nodeToBind.Kind() == SyntaxKind.CasePatternSwitchLabel || nodeToBind.Kind() == SyntaxKind.ArgumentList && nodeToBind.Parent is ConstructorInitializerSyntax || nodeToBind.Kind() == SyntaxKind.VariableDeclarator && new[] { SyntaxKind.LocalDeclarationStatement, SyntaxKind.ForStatement, SyntaxKind.UsingStatement, SyntaxKind.FixedStatement }. Contains(nodeToBind.Ancestors().OfType<StatementSyntax>().First().Kind()) || nodeToBind is ExpressionSyntax); return typeSyntax.IsVar ? new LocalSymbolWithEnclosingContext(containingSymbol, scopeBinder, nodeBinder, typeSyntax, identifierToken, kind, nodeToBind, forbiddenZone) : new SourceLocalSymbol(containingSymbol, scopeBinder, false, typeSyntax, identifierToken, kind); }
private static void AddNode(ItemCollection items, SyntaxNode node, string prefix) { var tooltip = string.Join(Environment.NewLine, node.GetDiagnostics().Select(x => x.ToString())); var treeViewItem = new TreeViewItem { Background = (node.ContainsDiagnostics) ? Brushes.Pink : Brushes.Transparent, Foreground = (node.IsToken) ? Brushes.DarkGreen : (node.Ancestors().Any(a => a.IsToken) ? Brushes.DarkRed : Brushes.Blue), Header = $"{prefix}{node.Kind} [{node.SourceRange.Start}..{node.SourceRange.End})", ToolTip = string.IsNullOrEmpty(tooltip) ? null : tooltip, Tag = node }; foreach (var childNode in node.ChildNodes) AddNode(treeViewItem.Items, childNode, string.Empty); if (node.IsToken) { var token = (SyntaxToken) node; foreach (var childNode in token.LeadingTrivia) AddNode(treeViewItem.Items, childNode, "Lead: "); foreach (var childNode in token.TrailingTrivia) AddNode(treeViewItem.Items, childNode, "Trail: "); } items.Add(treeViewItem); }
/// <summary> /// Returns the full qualifier name of the given syntax node. /// </summary> /// <param name="syntaxNode">SyntaxNode</param> /// <returns>string</returns> private string GetFullQualifierNameOfSyntaxNode(SyntaxNode syntaxNode) { string result = ""; if (syntaxNode == null) { return result; } SyntaxNode ancestor = null; while ((ancestor = syntaxNode.Ancestors().Where(val => val is ClassDeclarationSyntax).FirstOrDefault()) != null) { result = (ancestor as ClassDeclarationSyntax).Identifier.ValueText + "." + result; syntaxNode = ancestor; } ancestor = null; while ((ancestor = syntaxNode.Ancestors().Where(val => val is NamespaceDeclarationSyntax).FirstOrDefault()) != null) { result = (ancestor as NamespaceDeclarationSyntax).Name + "." + result; syntaxNode = ancestor; } return result; }
/// <summary> /// Gets the default value for the <paramref name="parameter"/>. /// </summary> /// <param name="syntax"> /// A syntax node corresponding to the invocation. /// </param> /// <param name="parameter"> /// A parameter to get the default value for. /// </param> /// <param name="enableCallerInfo"> /// Indicates if caller info is to be enabled when processing this optional parameter. /// The value <see cref="ThreeState.Unknown"/> means the decision is to be made based on the shape of the <paramref name="syntax"/> node. /// </param> /// <remarks> /// DELIBERATE SPEC VIOLATION: When processing an implicit invocation of an <c>Add</c> method generated /// for an element-initializer in a collection-initializer, the parameter <paramref name="enableCallerInfo"/> /// is set to <see cref="ThreeState.True"/>. It means that if the optional parameter is annotated with <see cref="CallerLineNumberAttribute"/>, /// <see cref="CallerFilePathAttribute"/> or <see cref="CallerMemberNameAttribute"/>, and there is no explicit argument corresponding to it, /// we will provide caller information as a value of this parameter. /// This is done to match the native compiler behavior and user requests (see http://roslyn.codeplex.com/workitem/171). This behavior /// does not match the C# spec that currently requires to provide caller information only in explicit invocations and query expressions. /// </remarks> private BoundExpression GetDefaultParameterValue(SyntaxNode syntax, ParameterSymbol parameter, ThreeState enableCallerInfo) { // TODO: Ideally, the enableCallerInfo parameter would be of just bool type with only 'true' and 'false' values, and all callers // explicitly provided one of those values, so that we do not rely on shape of syntax nodes in the rewriter. There are not many immediate callers, // but often the immediate caller does not have the required information, so all possible call chains should be analyzed and possibly updated // to pass this information, and this might be a big task. We should consider doing this when the time permits. TypeSymbol parameterType = parameter.Type; Debug.Assert(parameter.IsOptional); ConstantValue defaultConstantValue = parameter.ExplicitDefaultConstantValue; BoundExpression defaultValue; SourceLocation callerSourceLocation; // For compatibility with the native compiler we treat all bad imported constant // values as default(T). if (defaultConstantValue != null && defaultConstantValue.IsBad) { defaultConstantValue = ConstantValue.Null; } if (parameter.IsCallerLineNumber && ((callerSourceLocation = GetCallerLocation(syntax, enableCallerInfo)) != null)) { int line = callerSourceLocation.SourceTree.GetDisplayLineNumber(callerSourceLocation.SourceSpan); BoundExpression lineLiteral = MakeLiteral(syntax, ConstantValue.Create(line), _compilation.GetSpecialType(SpecialType.System_Int32)); if (parameterType.IsNullableType()) { defaultValue = MakeConversionNode(lineLiteral, parameterType.GetNullableUnderlyingType(), false); // wrap it in a nullable ctor. defaultValue = new BoundObjectCreationExpression( syntax, GetNullableMethod(syntax, parameterType, SpecialMember.System_Nullable_T__ctor), defaultValue); } else { defaultValue = MakeConversionNode(lineLiteral, parameterType, false); } } else if (parameter.IsCallerFilePath && ((callerSourceLocation = GetCallerLocation(syntax, enableCallerInfo)) != null)) { string path = callerSourceLocation.SourceTree.GetDisplayPath(callerSourceLocation.SourceSpan, _compilation.Options.SourceReferenceResolver); BoundExpression memberNameLiteral = MakeLiteral(syntax, ConstantValue.Create(path), _compilation.GetSpecialType(SpecialType.System_String)); defaultValue = MakeConversionNode(memberNameLiteral, parameterType, false); } else if (parameter.IsCallerMemberName && ((callerSourceLocation = GetCallerLocation(syntax, enableCallerInfo)) != null)) { string memberName; switch (_factory.TopLevelMethod.MethodKind) { case MethodKind.Constructor: case MethodKind.StaticConstructor: // See if the code is actually part of a field, field-like event or property initializer and return the name of the corresponding member. var memberDecl = syntax.Ancestors().OfType<MemberDeclarationSyntax>().FirstOrDefault(); if (memberDecl != null) { BaseFieldDeclarationSyntax fieldDecl; if (memberDecl.Kind() == SyntaxKind.PropertyDeclaration) { var propDecl = (PropertyDeclarationSyntax)memberDecl; EqualsValueClauseSyntax initializer = propDecl.Initializer; if (initializer != null && initializer.Span.Contains(syntax.Span)) { memberName = propDecl.Identifier.ValueText; break; } } else if ((fieldDecl = memberDecl as BaseFieldDeclarationSyntax) != null) { memberName = null; foreach (VariableDeclaratorSyntax varDecl in fieldDecl.Declaration.Variables) { EqualsValueClauseSyntax initializer = varDecl.Initializer; if (initializer != null && initializer.Span.Contains(syntax.Span)) { memberName = varDecl.Identifier.ValueText; break; } } if (memberName != null) { break; } } } goto default; default: memberName = _factory.TopLevelMethod.GetMemberCallerName(); break; } BoundExpression memberNameLiteral = MakeLiteral(syntax, ConstantValue.Create(memberName), _compilation.GetSpecialType(SpecialType.System_String)); defaultValue = MakeConversionNode(memberNameLiteral, parameterType, false); } else if (defaultConstantValue == ConstantValue.NotAvailable) { // There is no constant value given for the parameter in source/metadata. if (parameterType.IsDynamic() || parameterType.SpecialType == SpecialType.System_Object) { // We have something like M([Optional] object x). We have special handling for such situations. defaultValue = GetDefaultParameterSpecial(syntax, parameter); } else { // The argument to M([Optional] int x) becomes default(int) defaultValue = new BoundDefaultOperator(syntax, parameterType); } } else if (defaultConstantValue.IsNull && parameterType.IsValueType) { // We have something like M(int? x = null) or M(S x = default(S)), // so replace the argument with default(int?). defaultValue = new BoundDefaultOperator(syntax, parameterType); } else if (parameterType.IsNullableType()) { // We have something like M(double? x = 1.23), so replace the argument // with new double?(1.23). TypeSymbol constantType = _compilation.GetSpecialType(defaultConstantValue.SpecialType); defaultValue = MakeLiteral(syntax, defaultConstantValue, constantType); // The parameter's underlying type might not match the constant type. For example, we might have // a default value of 5 (an integer) but a parameter type of decimal?. defaultValue = MakeConversionNode(defaultValue, parameterType.GetNullableUnderlyingType(), @checked: false, acceptFailingConversion: true); // Finally, wrap it in a nullable ctor. defaultValue = new BoundObjectCreationExpression( syntax, GetNullableMethod(syntax, parameterType, SpecialMember.System_Nullable_T__ctor), defaultValue); } else if (defaultConstantValue.IsNull || defaultConstantValue.IsBad) { defaultValue = MakeLiteral(syntax, defaultConstantValue, parameterType); } else { // We have something like M(double x = 1.23), so replace the argument with 1.23. TypeSymbol constantType = _compilation.GetSpecialType(defaultConstantValue.SpecialType); defaultValue = MakeLiteral(syntax, defaultConstantValue, constantType); // The parameter type might not match the constant type. defaultValue = MakeConversionNode(defaultValue, parameterType, @checked: false, acceptFailingConversion: true); } return defaultValue; }