private string GetOutsideTypeQualifiedName(SyntaxNode node) { // Get the name space name enclosing this node. string namespaceName = node.AncestorsAndSelf(). // ancestors whose kind is name space node. Where(n => n.Kind == SyntaxKind.NamespaceDeclaration). // conver to the syntax and get the name. Select(n => (NamespaceDeclarationSyntax)n).First().Name.PlainName; // Get the class name enclosing this node. var classesNames = node.AncestorsAndSelf(). // ancestors whose kind is class node. Where(n => n.Kind == SyntaxKind.ClassDeclaration). // convert each one to the kind class node syntax. Select(n => (ClassDeclarationSyntax)n). // order all the class decs by their length, in decending order. OrderByDescending(n => n.Span.Length). // select their names. Select(n => n.Identifier.ValueText); // Combine all the names to get the scope string. var qualifiedName = namespaceName + "." + StringUtil.ConcatenateAll(".", classesNames); logger.Info(qualifiedName); return qualifiedName; }
public SyntaxToken GenerateUniqueName( SemanticModel semanticModel, SyntaxNode location, SyntaxNode containerOpt, string baseName, Func <ISymbol, bool> filter, IEnumerable <string> usedNames, CancellationToken cancellationToken) { var container = containerOpt ?? location.AncestorsAndSelf().FirstOrDefault( a => BlockFacts.IsExecutableBlock(a) || SyntaxFacts.IsParameterList(a) || SyntaxFacts.IsMethodBody(a)); var candidates = GetCollidableSymbols(semanticModel, location, container, cancellationToken); var filteredCandidates = filter != null?candidates.Where(filter) : candidates; return(GenerateUniqueName(baseName, filteredCandidates.Select(s => s.Name).Concat(usedNames))); }
/// <summary>Adds a XML documentation header to a diagnosted member declaration.</summary> /// <param name="document">The document that includes the diagnostic.</param> /// <param name="diagnostic">The detected disgnostic, that should be fixed.</param> /// <param name="cancellationToken">A cancellation token to cancel the action.</param> /// <returns>A solution including the fixed code.</returns> private static async Task <Solution> AddDocumentationHeaderAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken) { SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken); SyntaxNode syntaxNode = root.FindNode(diagnostic.Location.SourceSpan); MemberDeclarationSyntax targetNode = syntaxNode.AncestorsAndSelf().OfType <MemberDeclarationSyntax>().First(); SyntaxNode newSyntaxNode = DocumentationBuilder.AddCompleteDocumentationHeader(targetNode); Document newDocument = document.WithSyntaxRoot(root.ReplaceNode(targetNode, newSyntaxNode)); // Make sure the document is well formatted newDocument = await Formatter.FormatAsync(newDocument, newDocument.Project.Solution.Options, cancellationToken); return(newDocument.Project.Solution); }
public override IMethodSymbol GetCallerMethodSymbol(SyntaxNode node, SemanticModel semanticModel) { if (node == null) { return(null); } MethodBlockSyntax declaration = node.AncestorsAndSelf().OfType <MethodBlockSyntax>().FirstOrDefault(); if (declaration != null) { return(semanticModel.GetDeclaredSymbol(declaration)); } SubNewStatementSyntax constructor = node.AncestorsAndSelf().OfType <SubNewStatementSyntax>().FirstOrDefault(); if (constructor != null) { return(semanticModel.GetDeclaredSymbol(constructor)); } return(null); }
public async Task <bool> IsAvailableAsync(CancellationToken token) { // Refactoring should be available only on selected nodes, like return statement or return type of the method if (!IsSelectedNodeSuiteableForRefactoring(_selectedNode)) { return(false); } var methodDeclaration = _selectedNode.AncestorsAndSelf().OfType <MethodDeclarationSyntax>().FirstOrDefault(); if (methodDeclaration == null) { // Could be null for constructors, for instance return(false); } return(methodDeclaration.UnwrapReturnTypeIfNeeded(_semanticModel).IsNullable(_semanticModel) && // Task is a special case. Ignore it! There is an assumption that Task should not be null. Adding // this ensures will just pollute the code !methodDeclaration.ReturnType.TypeEquals(typeof(Task), _semanticModel) && !methodDeclaration.IsAbstract() && (!await methodDeclaration.EnsuresReturnValueIsNotNull(_semanticModel, token))); }
private void TrackAssignmentsToLocalsAndPrivateFields(ISymbol symbol, Solution solution, ISet <NodeAndSymbol> trackedNodesAndSymbols) { var referencedSymbols = SymbolFinder.FindReferencesAsync(symbol, solution).Result; foreach (var referencedSymbol in referencedSymbols) { foreach (var referenceLocation in referencedSymbol.Locations) { SyntaxNode node = referenceLocation.Location.SourceTree.GetRoot().FindNode(referenceLocation.Location.SourceSpan); var assignment = node.AncestorsAndSelf().OfType <AssignmentExpressionSyntax>().FirstOrDefault(); if (assignment == null || assignment.Parent is UsingStatementSyntax) { continue; } SemanticModel currentModel = referenceLocation.Document.GetSemanticModelAsync().Result; if (!currentModel.Compilation.ContainsSyntaxTree(referenceLocation.Location.SourceTree)) { continue; } SemanticModel model = currentModel.Compilation.GetSemanticModel(referenceLocation.Location.SourceTree); ISymbol assignedSymbol = model.GetSymbol(assignment.Left); if (assignedSymbol == null || !assignedSymbol.Equals(symbol, SymbolEqualityComparer.Default)) { continue; } if (assignment.Parent.IsKind(SyntaxKind.UsingStatement) || !IsInstantiation(assignment.Right, model)) { continue; } var leftReferencedSymbol = model.GetSymbol(assignment.Left); if (leftReferencedSymbol == null || !leftReferencedSymbol.Equals(symbol, SymbolEqualityComparer.Default)) { continue; } if (IsLocalOrPrivateField(leftReferencedSymbol)) { trackedNodesAndSymbols.Add(new NodeAndSymbol { Node = assignment, Symbol = leftReferencedSymbol }); } } } }
///Todo: register only on namespace public static bool CheckSupport(SyntaxNode node) { bool foundSupportedNameSpace = false; var nsDeclarations = node.AncestorsAndSelf().OfType <NamespaceDeclarationSyntax>(); foreach (var nsd in nsDeclarations) { foundSupportedNameSpace = nsd.Name.ToFullString().ToLowerInvariant().Contains(SupportedNamespace.ToLowerInvariant()); if (foundSupportedNameSpace) { break; } } return(foundSupportedNameSpace); }
public override SyntaxNode FindNodeToUpdate(Document document, SyntaxNode node) { if (_updatableNodeKinds.Contains(node.Kind())) { return(node); } // TODO: file bug about this: var invocation = csnode.Ancestors().FirstOrDefault(a => a.Kind == SyntaxKind.InvocationExpression); var matchingNode = node.AncestorsAndSelf().FirstOrDefault(n => _updatableAncestorKinds.Contains(n.Kind())); if (matchingNode == null) { return(null); } var nodeContainingOriginal = GetNodeContainingTargetNode(matchingNode); if (nodeContainingOriginal == null) { return(null); } return(node.AncestorsAndSelf().Any(n => n == nodeContainingOriginal) ? matchingNode : null); }
public void ComputeRefactoringsForNodeInsideTrivia() { SyntaxNode node = Root.FindNode(Span, findInsideTrivia: true, getInnermostNodeForTie: true); if (node == null) { return; } bool fDirectiveTrivia = false; using (IEnumerator <SyntaxNode> en = node.AncestorsAndSelf().GetEnumerator()) { while (en.MoveNext()) { node = en.Current; Debug.WriteLine(node.Kind().ToString()); if (!fDirectiveTrivia && (node is DirectiveTriviaSyntax directiveTrivia)) { DirectiveTriviaRefactoring.ComputeRefactorings(this, directiveTrivia); SyntaxKind kind = node.Kind(); if (kind == SyntaxKind.RegionDirectiveTrivia || kind == SyntaxKind.EndRegionDirectiveTrivia) { RegionDirectiveTriviaRefactoring.ComputeRefactorings(this); } RemoveAllPreprocessorDirectivesRefactoring.ComputeRefactorings(this); if (kind == SyntaxKind.RegionDirectiveTrivia) { RegionDirectiveTriviaRefactoring.ComputeRefactorings(this, (RegionDirectiveTriviaSyntax)node); } else if (kind == SyntaxKind.EndRegionDirectiveTrivia) { RegionDirectiveTriviaRefactoring.ComputeRefactorings(this, (EndRegionDirectiveTriviaSyntax)node); } fDirectiveTrivia = true; } } } }
public override ITypeSymbol GetEnclosingTypeSymbol(SyntaxNode node, SemanticModel semanticModel) { if (node == null) { return(null); } ClassDeclarationSyntax declaration = node.AncestorsAndSelf().OfType <ClassDeclarationSyntax>().FirstOrDefault(); if (declaration == null) { return(null); } return(semanticModel.GetDeclaredSymbol(declaration)); }
private static async Task <SyntaxNode> ReplacePropertyInSyntaxRootAsync(SyntaxNode propertyDeclarationSyntaxNode, CancellationToken cancellationToken, SemanticModel semanticModel, SyntaxNode root) { var property = propertyDeclarationSyntaxNode.AncestorsAndSelf().OfType <PropertyDeclarationSyntax>().First(); var fieldVariableDeclaratorSyntax = await GetFieldDeclarationSyntaxNodeAsync(property, cancellationToken, semanticModel).ConfigureAwait(false); if (fieldVariableDeclaratorSyntax == null) { return(root); } var fieldReferences = await GetFieldReferencesAsync(fieldVariableDeclaratorSyntax, cancellationToken, semanticModel).ConfigureAwait(false); var nodesToUpdate = fieldReferences.Cast <SyntaxNode>().Union(Enumerable.Repeat(property, 1)).Union(Enumerable.Repeat(fieldVariableDeclaratorSyntax, 1)); var newRoot = FixWithTrackNode(root, property, fieldVariableDeclaratorSyntax, nodesToUpdate); return(newRoot); }
private SyntaxToken GenerateUniqueName( SemanticModel semanticModel, SyntaxNode location, SyntaxNode containerOpt, string baseName, Func <ISymbol, bool> filter, IEnumerable <string> usedNames, CancellationToken cancellationToken) { var syntaxFacts = this.SyntaxFactsService; var container = containerOpt ?? location.AncestorsAndSelf().FirstOrDefault( a => syntaxFacts.IsExecutableBlock(a) || syntaxFacts.IsMethodBody(a)); var candidates = semanticModel.LookupSymbols(location.SpanStart).Concat( semanticModel.GetExistingSymbols(container, cancellationToken)); return(GenerateUniqueName( semanticModel, location, containerOpt, baseName, filter != null ? candidates.Where(filter) : candidates, usedNames, cancellationToken)); }
public static bool CanSafelyMoveLocalToBlock(this ILocalSymbol localSymbol, SyntaxNode currentBlock, SyntaxNode destinationBlock) { if (currentBlock != destinationBlock) { var localFunctionOrMethodDeclaration = currentBlock.AncestorsAndSelf() .FirstOrDefault(node => node.IsKind(SyntaxKind.LocalFunctionStatement) || node.IsKind(SyntaxKind.MethodDeclaration)); var localFunctionStatement = destinationBlock.FirstAncestorOrSelf <LocalFunctionStatementSyntax>(); if (localFunctionOrMethodDeclaration != localFunctionStatement && HasTypeParameterWithName(localFunctionOrMethodDeclaration, localSymbol.Type.Name) && HasTypeParameterWithName(localFunctionStatement, localSymbol.Type.Name)) { return(false); } } return(true);
public SyntaxToken GenerateUniqueName( SemanticModel semanticModel, SyntaxNode location, SyntaxNode containerOpt, string baseName, CancellationToken cancellationToken) { var syntaxFacts = this.SyntaxFactsService; var container = containerOpt ?? location.AncestorsAndSelf().FirstOrDefault( a => syntaxFacts.IsExecutableBlock(a) || syntaxFacts.IsMethodBody(a)); var existingSymbols = semanticModel.GetExistingSymbols(container, cancellationToken); var reservedNames = semanticModel.LookupSymbols(location.SpanStart) .Select(s => s.Name) .Concat(existingSymbols.Select(s => s.Name)); return(syntaxFacts.ToIdentifierToken( NameGenerator.EnsureUniqueness(baseName, reservedNames, syntaxFacts.IsCaseSensitive))); }
private bool DetermineIsInConstructor(SemanticDocument semanticDocument, SyntaxNode simpleName) { if (!ContainingType.OriginalDefinition.Equals(TypeToGenerateIn.OriginalDefinition)) { return(false); } // If we're in an lambda/local function we're not actually 'in' the constructor. // i.e. we can't actually write to read-only fields here. var syntaxFacts = semanticDocument.Document.GetRequiredLanguageService <ISyntaxFactsService>(); if (simpleName.AncestorsAndSelf().Any(n => syntaxFacts.IsAnonymousOrLocalFunction(n))) { return(false); } return(syntaxFacts.IsInConstructor(simpleName)); }
public static bool ContainedInValidType(this SyntaxNode node) { Contract.ThrowIfNull(node); foreach (var ancestor in node.AncestorsAndSelf()) { if (ancestor is TypeDeclarationSyntax) { return(true); } if (ancestor is NamespaceDeclarationSyntax) { return(false); } } return(true); }
private static SyntaxNode Typedef(SyntaxNode node, Scope scope) { var field = node .AncestorsAndSelf() .OfType <FieldDeclarationSyntax>() .FirstOrDefault(); if (field == null) { scope.AddError("xs01", "malformed typedef", node); //td: error, malformed typedef return(node); } if (field.Declaration.Variables.Count != 1) { scope.AddError("xs01", "malformed typedef", node); return(node); } var variable = field .Declaration .Variables[0]; Debug.Assert(variable.Initializer == null || variable.Initializer.IsMissing); var type = RoslynCompiler.UnMark(field.Declaration.Type); var identifier = variable.Identifier; var parentScope = scope.CreateScope <SyntaxToken, SyntaxNode, SemanticModel>(field.Parent); Debug.Assert(parentScope != null); parentScope.set("__tdef" + identifier.ToString(), type); //schedule deletion var document = scope.GetDocument <SyntaxToken, SyntaxNode, SemanticModel>(); document.change(field.Parent, RoslynCompiler.RemoveMember(field)); //return intact return(node); }
public static void ComputeRefactoringsForNodeInsideTrivia(this RefactoringContext context) { SyntaxNode node = context.FindNode(findInsideTrivia: true); if (node == null) { return; } bool fDirectiveTrivia = false; using (IEnumerator <SyntaxNode> en = node.AncestorsAndSelf().GetEnumerator()) { while (en.MoveNext()) { node = en.Current; Debug.WriteLine(node.Kind().ToString()); if (!fDirectiveTrivia) { var directiveTrivia = node as DirectiveTriviaSyntax; if (directiveTrivia != null) { DirectiveTriviaRefactoring.ComputeRefactorings(context, directiveTrivia); if (node.IsKind(SyntaxKind.RegionDirectiveTrivia, SyntaxKind.EndRegionDirectiveTrivia)) { RegionDirectiveTriviaRefactoring.ComputeRefactorings(context); } RemoveAllPreprocessorDirectivesRefactoring.ComputeRefactorings(context); if (node.IsKind(SyntaxKind.RegionDirectiveTrivia, SyntaxKind.EndRegionDirectiveTrivia)) { RegionDirectiveTriviaRefactoring.ComputeRefactorings(context, (RegionDirectiveTriviaSyntax)node); } fDirectiveTrivia = true; } } } } }
private static void ExcludeDisposedAndClosedLocalsAndPrivateFields(SyntaxNode typeDeclaration, SemanticModel semanticModel, ISet <ISymbol> excludedSymbols) { var invocationsAndConditionalAccesses = typeDeclaration .AncestorsAndSelf() .OfType <ExpressionStatementSyntax>() .Where(n => n.Expression.IsKind(SyntaxKind.InvocationExpression) || n.Expression.IsKind(SyntaxKind.ConditionalAccessExpression)) .Select(expr => expr.Expression); foreach (var invocationOrConditionalAccess in invocationsAndConditionalAccesses) { SimpleNameSyntax name = null; ExpressionSyntax expression = null; if (invocationOrConditionalAccess is InvocationExpressionSyntax invocation) { var memberAccessNode = invocation.Expression as MemberAccessExpressionSyntax; name = memberAccessNode?.Name; expression = memberAccessNode?.Expression; } else if (invocationOrConditionalAccess is ConditionalAccessExpressionSyntax conditionalAccess) { if (!(conditionalAccess.WhenNotNull is InvocationExpressionSyntax conditionalInvocation)) { continue; } var memberBindingNode = conditionalInvocation.Expression as MemberBindingExpressionSyntax; name = memberBindingNode?.Name; expression = conditionalAccess.Expression; } if (name == null || !DisposeMethods.Contains(name.Identifier.Text)) { continue; } var referencedSymbol = semanticModel.GetSymbol(expression); if (referencedSymbol != null && IsLocalOrPrivateField(referencedSymbol)) { excludedSymbols.Add(referencedSymbol); } } }
protected override ITypeSymbol GetQueryClauseInfo( SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken ) { var query = node.AncestorsAndSelf().OfType <QueryExpressionSyntax>().First(); if ( InfoBoundSuccessfully( semanticModel.GetQueryClauseInfo(query.FromClause, cancellationToken) ) ) { return(null); } foreach (var clause in query.Body.Clauses) { if ( InfoBoundSuccessfully( semanticModel.GetQueryClauseInfo(clause, cancellationToken) ) ) { return(null); } } if ( InfoBoundSuccessfully( semanticModel.GetSymbolInfo(query.Body.SelectOrGroup, cancellationToken) ) ) { return(null); } var fromClause = query.FromClause; return(semanticModel.GetTypeInfo(fromClause.Expression, cancellationToken).Type); }
public override Task <CodeAction> CalculateActionAsync(Document document, SyntaxNode root, SyntaxNode selectedNode, CancellationToken cancellationToken) { var parentStatement = selectedNode.AncestorsAndSelf().OfType <StatementSyntax>().FirstOrDefault(); if (parentStatement == null) { return(Task.FromResult <CodeAction>(null)); } var childStatements = parentStatement.ChildNodes().OfType <StatementSyntax>().ToList(); if (childStatements.Count != 1) { return(Task.FromResult <CodeAction>(null)); } var block = childStatements.First() as BlockSyntax; if (block == null) { return(Task.FromResult <CodeAction>(null)); } var innerStatements = block.ChildNodes().OfType <StatementSyntax>().ToList(); if (innerStatements.Count != 1) { return(Task.FromResult <CodeAction>(null)); } if (IsElseClauseEscapeCase(innerStatements.First(), parentStatement)) { return(Task.FromResult <CodeAction>(null)); } var action = CodeAction.Create( Resources.RemoveBraces, token => RemoveBracesAsync(document, root, innerStatements.First(), parentStatement, token)); return(Task.FromResult(action)); }
private static SyntaxNode GetNodeForLeadingTrivia(this SyntaxNode node) { foreach (SyntaxNode ancestor in node.AncestorsAndSelf()) { if (ancestor.IsKind(SyntaxKind.IfStatement)) { return(((IfStatementSyntax)ancestor).ParentElse() ?? ancestor); } else if (ancestor.IsMemberDeclaration()) { return(ancestor); } else if (ancestor.IsStatement()) { return(ancestor); } } return(node); }
private static void ExcludeReturnedPassedAndAliasedLocalsAndPrivateFields(SyntaxNode typeDeclaration, SemanticModel semanticModel, ISet <ISymbol> excludedSymbols) { var identifiersAndSimpleMemberAccesses = typeDeclaration .AncestorsAndSelf() .Where(n => n.IsKind(SyntaxKind.IdentifierName) || n.IsKind(SyntaxKind.Argument) || n.IsKind(SyntaxKind.SimpleMemberAccessExpression)); foreach (var identifierOrSimpleMemberAccess in identifiersAndSimpleMemberAccesses) { SyntaxNode expression = null; if (identifierOrSimpleMemberAccess.IsKind(SyntaxKind.IdentifierName)) { expression = (IdentifierNameSyntax)identifierOrSimpleMemberAccess; } else if (identifierOrSimpleMemberAccess.IsKind(SyntaxKind.SimpleMemberAccessExpression)) { var memberAccess = (MemberAccessExpressionSyntax)identifierOrSimpleMemberAccess; if (!memberAccess.Expression.IsKind(SyntaxKind.ThisExpression)) { continue; } expression = memberAccess; } else if (identifierOrSimpleMemberAccess.IsKind(SyntaxKind.Argument)) { expression = identifierOrSimpleMemberAccess as ArgumentSyntax; } if (!IsStandaloneExpression(expression)) { continue; } var referencedSymbol = semanticModel.GetSymbol(expression is ArgumentSyntax ? (expression as ArgumentSyntax).Expression : expression); if (referencedSymbol != null && IsLocalOrPrivateField(referencedSymbol)) { excludedSymbols.Add(referencedSymbol); } } }
private static IEnumerable <ParameterSyntax> GetParametersInScope(SyntaxNode node) { foreach (var ancestor in node.AncestorsAndSelf()) { if (ancestor.IsKind(SyntaxKind.SimpleLambdaExpression)) { yield return(((SimpleLambdaExpressionSyntax)ancestor).Parameter); } else { var parameterList = ancestor.GetParameterList(); if (parameterList != null) { foreach (var parameter in parameterList.Parameters) { yield return(parameter); } } } } }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { Project project = context.Document.Project; TextDocument exceptionsDocument = project.AdditionalDocuments.FirstOrDefault(doc => doc.Name.Equals(AvoidDuplicateCodeAnalyzer.ExceptionsFileName, StringComparison.Ordinal)); if (exceptionsDocument == null) { return; } SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); foreach (Diagnostic diagnostic in context.Diagnostics) { TextSpan diagnosticSpan = diagnostic.Location.SourceSpan; if (root != null) { SyntaxNode syntaxNode = root.FindToken(diagnosticSpan.Start).Parent; if (syntaxNode != null) { MethodDeclarationSyntax methodDeclarationSyntax = syntaxNode.AncestorsAndSelf().OfType <MethodDeclarationSyntax>().FirstOrDefault(); if (methodDeclarationSyntax != null) { string methodName = methodDeclarationSyntax.Identifier.ValueText; string title = $@"Add {methodName} to duplicate code exceptions list"; context.RegisterCodeFix( CodeAction.Create( title: title, createChangedSolution: c => GetFix(exceptionsDocument, methodName, c), equivalenceKey: title), diagnostic); } } } } }
/// <summary> /// Adds "using Task = System.Threading.Tasks.Task;" to the document if it is not already present. /// </summary> /// <param name="syntaxNode">Any syntax node within the document.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <returns>The original <paramref name="syntaxNode"/> given, as it is represented in the updated syntax tree.</returns> internal static async Task<SyntaxNode> AddUsingTaskEqualsDirectiveAsync(SyntaxNode syntaxNode, CancellationToken cancellationToken) { var existingUsings = syntaxNode.AncestorsAndSelf().OfType<UsingDirectiveSyntax>().Concat( syntaxNode.DescendantNodes(n => n is CompilationUnitSyntax || n is NamespaceDeclarationSyntax).OfType<UsingDirectiveSyntax>()); if (existingUsings.Any(u => u.Alias?.Name?.Identifier.ValueText == nameof(Task))) { // The user has already aliased Task. return syntaxNode; } var trackAnnotation = new SyntaxAnnotation(); syntaxNode = syntaxNode.WithAdditionalAnnotations(trackAnnotation); var usingTaskDirective = SyntaxFactory.UsingDirective( QualifyName(Namespaces.SystemThreadingTasks, SyntaxFactory.IdentifierName(nameof(Task)))) .WithAlias(SyntaxFactory.NameEquals(nameof(Task))); var syntaxRoot = (CompilationUnitSyntax)await syntaxNode.SyntaxTree.GetRootAsync(cancellationToken); syntaxRoot = syntaxRoot.AddUsings(usingTaskDirective); return syntaxRoot.GetAnnotatedNodes(trackAnnotation).Single(); }
public static bool CanSafelyMoveLocalToBlock(this ILocalSymbol localSymbol, SyntaxNode currentBlock, SyntaxNode destinationBlock) { if (currentBlock != destinationBlock) { var localFunctionOrMethodDeclaration = currentBlock.AncestorsAndSelf() .FirstOrDefault(node => node.IsKind(SyntaxKind.LocalFunctionStatement) || node.IsKind(SyntaxKind.MethodDeclaration)); var localFunctionStatement = destinationBlock.FirstAncestorOrSelf <LocalFunctionStatementSyntax>(); if (localFunctionOrMethodDeclaration != localFunctionStatement && HasTypeParameterWithName(localFunctionOrMethodDeclaration, localSymbol.Type.Name) && HasTypeParameterWithName(localFunctionStatement, localSymbol.Type.Name)) { return(false); } } return(true); bool HasTypeParameterWithName(SyntaxNode node, string name) { SeparatedSyntaxList <TypeParameterSyntax>?typeParameters; switch (node) { case MethodDeclarationSyntax methodDeclaration: typeParameters = methodDeclaration.TypeParameterList?.Parameters; break; case LocalFunctionStatementSyntax localFunctionStatement: typeParameters = localFunctionStatement.TypeParameterList?.Parameters; break; default: return(false); } return(typeParameters.HasValue && typeParameters.Value.Any(typeParameter => typeParameter.Identifier.ValueText == name)); } }
private static IEnumerable <ExpressionSyntax> GetUnreachableExpressions(SyntaxNode constantExpression, bool constantValue) { // This is ugly with LINQ, hence the loop foreach (var current in constantExpression.AncestorsAndSelf()) { if (current.Parent is ParenthesizedExpressionSyntax) { continue; } var binary = current.Parent as BinaryExpressionSyntax; if (!IsShortcuttingExpression(binary, constantValue)) { break; } if (binary.Left == current) { yield return(binary.Right); } } }
static SyntaxNode GetNewRoot(SyntaxNode root, SyntaxNode node) { var decl = node.AncestorsAndSelf().OfType <LocalDeclarationStatementSyntax>().FirstOrDefault(); if (decl != null) { return(root.RemoveNode(decl, SyntaxRemoveOptions.KeepNoTrivia)); } if (node.Parent.IsKind(SyntaxKind.ElseClause)) { return(root.RemoveNode(node.Parent, SyntaxRemoveOptions.KeepNoTrivia)); } var statement = node as StatementSyntax; if (statement != null) { return(root.RemoveNode(statement, SyntaxRemoveOptions.KeepNoTrivia)); } return(root.RemoveNode(node.Parent, SyntaxRemoveOptions.KeepNoTrivia)); }
private static IEnumerable <ParameterSyntax> GetParametersInScope(SyntaxNode node) { foreach (SyntaxNode ancestor in node.AncestorsAndSelf()) { if (ancestor.IsKind(SyntaxKind.SimpleLambdaExpression)) { yield return(((SimpleLambdaExpressionSyntax)ancestor).Parameter); } else { BaseParameterListSyntax parameterList = GetParameterList(ancestor); if (parameterList != null) { for (int i = 0; i < parameterList.Parameters.Count; i++) { yield return(parameterList.Parameters[i]); } } } } }
private async Task <Solution> UsePropertyAsync(Document document, SyntaxNode statement) { // Create a new property // Using property naming conventions // Including possible initializers // And attributes var variableDeclarator = statement.AncestorsAndSelf().OfType <VariableDeclaratorSyntax>().First(); var fieldStatement = variableDeclarator.AncestorsAndSelf().OfType <FieldDeclarationSyntax>().First(); var variableDeclaration = variableDeclarator.AncestorsAndSelf().OfType <VariableDeclarationSyntax>().First(); var newProperty = SyntaxFactory.PropertyDeclaration(variableDeclaration.Type, variableDeclarator.Identifier) .WithAttributeLists(fieldStatement.AttributeLists) .WithModifiers(fieldStatement.Modifiers) .WithAdditionalAnnotations(Formatter.Annotation) .WithAccessorList( SyntaxFactory.AccessorList( SyntaxFactory.List(new[] { SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)), SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)) }))); if (variableDeclarator.Initializer != null) { newProperty = newProperty.WithInitializer(variableDeclarator.Initializer) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)); } var editor = await DocumentEditor.CreateAsync(document); editor.InsertAfter(statement, newProperty); editor.RemoveNode(variableDeclarator); return(editor.GetChangedDocument().Project.Solution); }
/// <summary> /// Try to get the statement syntax node that is enclosing the given method invocation. /// </summary> /// <param name="invocation"></param> /// <param name="statement"></param> /// <returns></returns> private bool TryGetStatementEnclosingInvocation(SyntaxNode invocation, out SyntaxNode statement) { var statements = invocation.AncestorsAndSelf().OfType<StatementSyntax>().ToList(); if(statements.Any()) { statement = statements.First(); return true; } statement = null; return false; }