private async Task<Document> HandleDeclarationAsync(Document document, SyntaxNode root, SyntaxNode node, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            var declarationContext = node.Parent;

            TypeSyntax typeSyntax = null;
            if (declarationContext is VariableDeclarationSyntax)
            {
                typeSyntax = ((VariableDeclarationSyntax)declarationContext).Type;
            }
            else if (declarationContext is ForEachStatementSyntax)
            {
                typeSyntax = ((ForEachStatementSyntax)declarationContext).Type;
            }
            else
            {
                Contract.Fail($"unhandled kind {declarationContext.Kind().ToString()}");
            }

            var typeSymbol = semanticModel.GetTypeInfo(typeSyntax).ConvertedType;

            var typeName = typeSymbol.GenerateTypeSyntax()
                                     .WithLeadingTrivia(node.GetLeadingTrivia())
                                     .WithTrailingTrivia(node.GetTrailingTrivia());

            Debug.Assert(!typeName.ContainsDiagnostics, "Explicit type replacement likely introduced an error in code");

            var newRoot = root.ReplaceNode(node, typeName);
            return document.WithSyntaxRoot(newRoot);
        }
        private static Task<Document> ReplaceTypeWithVarAsync(Document document, SyntaxNode root, SyntaxNode node)
        {
            var implicitType = SyntaxFactory.IdentifierName("var")
                                            .WithLeadingTrivia(node.GetLeadingTrivia())
                                            .WithTrailingTrivia(node.GetTrailingTrivia());

            var newRoot = root.ReplaceNode(node, implicitType);
            return Task.FromResult(document.WithSyntaxRoot(newRoot));
        }
        private static bool CheckSuppressionCommentOnNode(Diagnostic diagnostic, string diagnosticShortName, SyntaxNode node, CancellationToken cancellation)
        {
            cancellation.ThrowIfCancellationRequested();
            var successfulMatch = node?.GetLeadingTrivia()
                                  .Where(x => x.IsKind(SyntaxKind.SingleLineCommentTrivia))
                                  .Select(trivia => _suppressPattern.Match(trivia.ToString()))
                                  .FirstOrDefault(match => match.Success &&
                                                  diagnostic.Id == match.Groups[1].Value &&
                                                  diagnosticShortName == match.Groups[2].Value);

            return(successfulMatch != null);
        }
        internal override Task<Document> GetUpdatedDocumentAsync(
            Document document, SemanticModel model, SyntaxNode root,
            SyntaxNode nodeToFix, string diagnosticId, CancellationToken cancellationToken)
        {
            ArrayTypeSyntax arrayType = GetArrayType(nodeToFix);
            if (arrayType != null)
            {
                TypeSyntax elementType = arrayType.ElementType.WithoutLeadingTrivia().WithoutTrailingTrivia();
                if (arrayType.RankSpecifiers.Count > 1)
                {
                    elementType = SyntaxFactory.ArrayType(elementType, SyntaxFactory.List(arrayType.RankSpecifiers.Skip(1)));
                }

                InvocationExpressionSyntax syntax = InvokeStaticGenericParameterlessMethod(
                    model.Compilation.GetTypeByMetadataName("System.Array"),
                    EmptyArrayDiagnosticAnalyzer.ArrayEmptyMethodName,
                    elementType.WithoutLeadingTrivia().WithoutTrailingTrivia());

                if (nodeToFix.HasLeadingTrivia)
                {
                    syntax = syntax.WithLeadingTrivia(nodeToFix.GetLeadingTrivia());
                }

                if (nodeToFix.HasTrailingTrivia)
                {
                    syntax = syntax.WithTrailingTrivia(nodeToFix.GetTrailingTrivia());
                }

                if (syntax != null)
                {
                    root = root.ReplaceNode(nodeToFix, syntax);
                    document = document.WithSyntaxRoot(root);
                }
            }

            return Task.FromResult(document);
        }
        private static int GetLeadingWhitespaceLength(SyntaxNode node)
        {
            if (!(node is IXmlElement))
            {
                return 0;
            }

            var leadingTrivia = node.GetLeadingTrivia();
            if (leadingTrivia == null)
            {
                return 0;
            }

            int totalLength = 0;
            foreach (var child in leadingTrivia.ChildNodes)
            {
                if (child.Kind == SyntaxKind.WhitespaceTrivia)
                {
                    totalLength += child.FullWidth;
                }
            }

            return totalLength;
        }
示例#6
0
        private IEnumerable <ExpressionStatementSyntax> CreateStubInitializerDeclarations(SyntaxNode node, string variableName, INamedTypeSymbol symbol)
        {
            var objectCreationExpression = node.DescendantNodes(s => !(s is ObjectCreationExpressionSyntax)).OfType <ObjectCreationExpressionSyntax>().FirstOrDefault();
            IEnumerable <ExpressionStatementSyntax> initializerExpressions = new ExpressionStatementSyntax[0];

            if (objectCreationExpression?.Initializer != null && symbol != null)
            {
                initializerExpressions =
                    InitializersToExpressions.Expand(objectCreationExpression.Initializer, SyntaxFactory.IdentifierName(variableName))
                    .Select(expressionStatementSyntax =>
                {
                    var statementSyntax = expressionStatementSyntax.WithLeadingTrivia(node.GetLeadingTrivia());

                    var newAssignment = TryReplaceAssignmentExpressionWithMethodCall(statementSyntax, symbol);
                    if (newAssignment == null)
                    {
                        return(statementSyntax);
                    }

                    return(newAssignment
                           .WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed));
                });
            }

            return(initializerExpressions);
        }
示例#7
0
 internal static SyntaxNode WithLeadingTriviaFrom(this SyntaxNode node, SyntaxNode other)
 {
     return(other.HasLeadingTrivia
         ? node.WithLeadingTrivia(other.GetLeadingTrivia())
         : node);
 }
        private static bool HasLeadingBlankLines(SyntaxNode node)
        {
            var firstTriviaIgnoringWhitespace = node.GetLeadingTrivia().FirstOrDefault(x => !x.IsKind(SyntaxKind.WhitespaceTrivia));

            return(firstTriviaIgnoringWhitespace.IsKind(SyntaxKind.EndOfLineTrivia));
        }
示例#9
0
 /// <summary>
 /// Determines if the node should be json serialized based on the precedence of
 /// a //json single line comment
 /// </summary>
 public static bool ShouldBeConvertedToJson(this SyntaxNode node) =>
 node.HasLeadingTrivia && ShouldBeConvertedToJson(node, node.GetLeadingTrivia());
示例#10
0
 /// <summary>
 /// Determines if the node should be hidden i.e. not included in the documentation,
 /// based on the precedence of a //hide single line comment
 /// </summary>
 public static bool ShouldBeHidden(this SyntaxNode node) =>
 node.HasLeadingTrivia && ShouldBeHidden(node, node.GetLeadingTrivia());
示例#11
0
        private static SyntaxNode ReplaceWellFormedMultiLineCommentHeader(Document document, SyntaxNode root, StyleCopSettings settings, int commentIndex, XmlFileHeader header)
        {
            SyntaxTriviaList trivia = root.GetLeadingTrivia();
            var commentTrivia       = trivia[commentIndex];

            // Is the comment pushed in by a prefix?
            var commentIndentation = string.Empty;

            if (commentIndex > 0)
            {
                var prefixTrivia = trivia[commentIndex - 1];
                if (prefixTrivia.IsKind(SyntaxKind.WhitespaceTrivia))
                {
                    commentIndentation = prefixTrivia.ToFullString();
                }
            }

            var triviaString      = commentTrivia.ToFullString();
            var startIndex        = triviaString.IndexOf("/*", StringComparison.Ordinal) + 2;
            var endIndex          = triviaString.LastIndexOf("*/", StringComparison.Ordinal);
            var commentContext    = triviaString.Substring(startIndex, endIndex - startIndex).Trim(' ', '\t').TrimEnd();
            var triviaStringParts = commentContext.Replace("\r\n", "\n").Split('\n');

            // Assume we have comments that have a leading *
            string interlinePadding = " *";

            int    minExpectedLength = (commentIndentation + interlinePadding).Length;
            string newLineText       = document.Project.Solution.Workspace.Options.GetOption(FormattingOptions.NewLine, LanguageNames.CSharp);

            // Examine second line to see if we should have stars or not if it's blank
            // set the interline padding to be blank also.
            if ((triviaStringParts.Length > 2) &&
                (triviaStringParts[1].Length > minExpectedLength) &&
                string.IsNullOrWhiteSpace(triviaStringParts[1].Substring(0, minExpectedLength)))
            {
                interlinePadding = "  ";
            }

            // Pad line that used to be next to a /*
            triviaStringParts[0] = commentIndentation + interlinePadding + " " + triviaStringParts[0];
            StringBuilder sb            = StringBuilderPool.Allocate();
            string        fileName      = Path.GetFileName(document.FilePath);
            var           copyrightText = GetCopyrightText(commentIndentation + interlinePadding, settings.DocumentationRules.GetCopyrightText(fileName), newLineText);
            var           newHeader     = WrapInXmlComment(commentIndentation + interlinePadding, copyrightText, document.Name, settings, newLineText);

            sb.Append(commentIndentation);
            sb.Append("/*");
            if (header.GetElement("copyright") == null)
            {
                // No copyright element at the moment so add us.
                sb.Append(newHeader.Substring(minExpectedLength));
                sb.Append(newLineText);

                // Append the original stuff
                foreach (var oldLine in triviaStringParts)
                {
                    sb.Append(oldLine.TrimEnd());
                    sb.Append(newLineText);
                }
            }
            else
            {
                bool firstLine   = true;
                bool inCopyright = false;
                foreach (var oldLine in triviaStringParts)
                {
                    var openingTag = oldLine.Contains("<copyright ");
                    var closingTag = oldLine.Contains("</copyright>") ||
                                     (openingTag && oldLine.Trim().EndsWith("/>"));
                    if (openingTag)
                    {
                        inCopyright = !closingTag;
                        sb.Append(newHeader.Substring(firstLine ? minExpectedLength : 0));
                        sb.Append(newLineText);
                    }

                    if (inCopyright)
                    {
                        inCopyright = !closingTag;
                    }
                    else
                    {
                        sb.Append(oldLine.Substring(firstLine ? minExpectedLength : 0));
                        sb.Append(newLineText);
                    }

                    firstLine = false;
                }
            }

            sb.Append(commentIndentation);
            sb.Append(" */");

            // Get rid of any trailing spaces.
            var lines = sb.ToString().Split(new string[] { newLineText }, StringSplitOptions.None);

            sb.Clear();
            for (int i = 0; i < lines.Length; i++)
            {
                sb.Append((i == 0 ? string.Empty : newLineText) + lines[i].TrimEnd());
            }

            var newTrivia = SyntaxFactory.SyntaxTrivia(SyntaxKind.MultiLineCommentTrivia, StringBuilderPool.ReturnAndFree(sb));

            return(root.WithLeadingTrivia(trivia.Replace(commentTrivia, newTrivia)));
        }
示例#12
0
        public static T WithTrivia <T>([NotNull] this T syntaxNode, [NotNull] SyntaxNode templateNode)
            where T : SyntaxNode
        {
            Requires.NotNull(syntaxNode, nameof(syntaxNode));
            Requires.NotNull(templateNode, nameof(templateNode));

            return(syntaxNode.WithTrailingTrivia(templateNode.GetTrailingTrivia()).WithLeadingTrivia(templateNode.GetLeadingTrivia()));
        }
示例#13
0
        /// <summary>
        /// Visits the specified syntax node.
        /// </summary>
        /// <param name="node">The syntax node to visit.</param>
        public void Visit(SyntaxNode node)
        {
            if (node == null)
            {
                return;
            }

            if (node is SyntaxToken)
            {
                Visit(node.GetLeadingTrivia());
            }

            switch (node.Kind)
            {
            case SyntaxKind.SingleLineCommentTrivia:
            case SyntaxKind.MultiLineCommentTrivia:
                VisitCommentTrivia((StructurelessSyntaxTrivia)node);
                break;

            case SyntaxKind.NumberToken:
                VisitNumber((SyntaxToken)node);
                break;

            case SyntaxKind.AnimationKeyword:
            case SyntaxKind.AsKeyword:
            case SyntaxKind.EventKeyword:
            case SyntaxKind.HandledKeyword:
            case SyntaxKind.ImportantKeyword:
            case SyntaxKind.KeyframeKeyword:
            case SyntaxKind.PlaySfxKeyword:
            case SyntaxKind.PlayStoryboardKeyword:
            case SyntaxKind.PropertyKeyword:
            case SyntaxKind.SetHandledKeyword:
            case SyntaxKind.SetKeyword:
            case SyntaxKind.TargetKeyword:
            case SyntaxKind.TransitionKeyword:
            case SyntaxKind.TriggerKeyword:
                VisitKeyword((SyntaxToken)node);
                break;

            case SyntaxKind.Selector:
                VisitSelector((UvssSelectorSyntax)node);
                break;

            case SyntaxKind.SelectorPart:
            case SyntaxKind.InvalidSelectorPart:
                VisitSelectorPart((UvssSelectorPartBaseSyntax)node);
                break;

            case SyntaxKind.PseudoClass:
                VisitPseudoClass((UvssPseudoClassSyntax)node);
                break;

            case SyntaxKind.Rule:
                VisitRule((UvssRuleSyntax)node);
                break;

            case SyntaxKind.EventName:
                VisitEventName((UvssEventNameSyntax)node);
                break;

            case SyntaxKind.PropertyName:
                VisitPropertyName((UvssPropertyNameSyntax)node);
                break;

            case SyntaxKind.PropertyValueToken:
                VisitPropertyValueToken((SyntaxToken)node);
                break;

            case SyntaxKind.Storyboard:
                VisitStoryboard((UvssStoryboardSyntax)node);
                break;

            case SyntaxKind.StoryboardTarget:
                VisitStoryboardTarget((UvssStoryboardTargetSyntax)node);
                break;

            case SyntaxKind.AnimationKeyframe:
                VisitAnimationKeyframe((UvssAnimationKeyframeSyntax)node);
                break;

            case SyntaxKind.NavigationExpression:
                VisitNavigationExpression((UvssNavigationExpressionSyntax)node);
                break;

            case SyntaxKind.UnknownDirective:
                VisitUnknownDirective((UvssUnknownDirectiveSyntax)node);
                break;

            case SyntaxKind.CultureDirective:
                VisitCultureDirective((UvssCultureDirectiveSyntax)node);
                break;
            }

            for (int i = 0; i < node.SlotCount; i++)
            {
                var child = node.GetSlot(i);
                if (child != null)
                {
                    Visit(child);
                }
            }

            if (node is SyntaxToken)
            {
                Visit(node.GetTrailingTrivia());
            }
        }
        private static SyntaxNode ReplaceHeader(ISyntaxFacts syntaxFacts, AbstractFileHeaderHelper fileHeaderHelper, SyntaxTrivia newLineTrivia, SyntaxNode root, string expectedFileHeader)
        {
            // Skip single line comments, whitespace, and end of line trivia until a blank line is encountered.
            var triviaList = root.GetLeadingTrivia();

            // True if the current line is blank so far (empty or whitespace); otherwise, false. The first line is
            // assumed to not be blank, which allows the analysis to detect a file header which follows a blank line at
            // the top of the file.
            var onBlankLine = false;

            // The set of indexes to remove from 'triviaList'. After removing these indexes, the remaining trivia (if
            // any) will be preserved in the document along with the replacement header.
            var removalList = new List <int>();

            // The number of spaces to indent the new header. This is expected to match the indentation of the header
            // which is being replaced.
            var leadingSpaces = string.Empty;

            // The number of spaces found so far on the current line. This will become 'leadingSpaces' if the spaces are
            // followed by a comment which is considered a header comment.
            var possibleLeadingSpaces = string.Empty;

            // Need to do this with index so we get the line endings correct.
            for (var i = 0; i < triviaList.Count; i++)
            {
                var triviaLine = triviaList[i];
                if (triviaLine.RawKind == syntaxFacts.SyntaxKinds.SingleLineCommentTrivia)
                {
                    if (possibleLeadingSpaces != string.Empty)
                    {
                        // One or more spaces precedes the comment. Keep track of these spaces so we can indent the new
                        // header by the same amount.
                        leadingSpaces = possibleLeadingSpaces;
                    }

                    removalList.Add(i);
                    onBlankLine = false;
                }
                else if (triviaLine.RawKind == syntaxFacts.SyntaxKinds.WhitespaceTrivia)
                {
                    if (leadingSpaces == string.Empty)
                    {
                        possibleLeadingSpaces = triviaLine.ToFullString();
                    }

                    removalList.Add(i);
                }
                else if (triviaLine.RawKind == syntaxFacts.SyntaxKinds.EndOfLineTrivia)
                {
                    possibleLeadingSpaces = string.Empty;
                    removalList.Add(i);

                    if (onBlankLine)
                    {
                        break;
                    }
                    else
                    {
                        onBlankLine = true;
                    }
                }
                else
                {
                    break;
                }
            }

            // Remove copyright lines in reverse order.
            for (var i = removalList.Count - 1; i >= 0; i--)
            {
                triviaList = triviaList.RemoveAt(removalList[i]);
            }

            var newHeaderTrivia = CreateNewHeader(syntaxFacts, leadingSpaces + fileHeaderHelper.CommentPrefix, expectedFileHeader, newLineTrivia.ToFullString());

            // Add a blank line and any remaining preserved trivia after the header.
            newHeaderTrivia = newHeaderTrivia.Add(newLineTrivia).Add(newLineTrivia).AddRange(triviaList);

            // Insert header at top of the file.
            return(root.WithLeadingTrivia(newHeaderTrivia));
        }
示例#15
0
        /// <summary>
        /// Returns the updated solution and a flag indicating if all references were fixed or not.
        /// </summary>
        private async Task <(Solution newSolution, bool allReferencesFixed)> UpdateReferencesAsync(ISymbol symbol, Solution solution, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var references = await SymbolFinder.FindReferencesAsync(symbol, solution, cancellationToken).ConfigureAwait(false);

            // Filter out cascaded symbol references. For example, accessor references for property symbol.
            references = references.Where(r => symbol.Equals(r.Definition));

            if (!references.HasExactly(1))
            {
                return(newSolution : solution, allReferencesFixed : !references.Any());
            }

            var allReferencesFixed = true;

            // Group references by document and fix references in each document.
            foreach (var referenceLocationGroup in references.Single().Locations.GroupBy(r => r.Document))
            {
                // Get document in current solution
                var document = solution.GetDocument(referenceLocationGroup.Key.Id);

                // Skip references in projects with different language.
                // https://github.com/dotnet/roslyn-analyzers/issues/1986 tracks handling them.
                if (!document.Project.Language.Equals(symbol.Language, StringComparison.Ordinal))
                {
                    allReferencesFixed = false;
                    continue;
                }

                var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                // Compute replacements
                var editor = new SyntaxEditor(root, solution.Workspace);
                foreach (var referenceLocation in referenceLocationGroup)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var referenceNode = root.FindNode(referenceLocation.Location.SourceSpan, getInnermostNodeForTie: true);
                    if (referenceNode == null)
                    {
                        allReferencesFixed = false;
                        continue;
                    }

                    var        operation        = semanticModel.GetOperationWalkingUpParentChain(referenceNode, cancellationToken);
                    SyntaxNode nodeToReplaceOpt = null;
                    switch (operation)
                    {
                    case IMemberReferenceOperation memberReference:
                        if (IsReplacableOperation(memberReference.Instance))
                        {
                            nodeToReplaceOpt = GetSyntaxNodeToReplace(memberReference);
                        }

                        break;

                    case IInvocationOperation invocation:
                        if (IsReplacableOperation(invocation.Instance))
                        {
                            nodeToReplaceOpt = GetExpressionOfInvocation(invocation.Syntax);
                        }

                        break;
                    }

                    if (nodeToReplaceOpt == null)
                    {
                        allReferencesFixed = false;
                        continue;
                    }

                    // Fetch the symbol for the node to replace - note that this might be
                    // different from the original symbol due to generic type arguments.
                    var symbolForNodeToReplace = GetSymbolForNodeToReplace(nodeToReplaceOpt, semanticModel);
                    if (symbolForNodeToReplace == null)
                    {
                        allReferencesFixed = false;
                        continue;
                    }

                    SyntaxNode memberName;
                    var        typeArgumentsOpt = GetTypeArguments(referenceNode);
                    memberName = typeArgumentsOpt != null?
                                 editor.Generator.GenericName(symbolForNodeToReplace.Name, typeArgumentsOpt) :
                                     editor.Generator.IdentifierName(symbolForNodeToReplace.Name);

                    var newNode = editor.Generator.MemberAccessExpression(
                        expression: editor.Generator.TypeExpression(symbolForNodeToReplace.ContainingType),
                        memberName: memberName)
                                  .WithLeadingTrivia(nodeToReplaceOpt.GetLeadingTrivia())
                                  .WithTrailingTrivia(nodeToReplaceOpt.GetTrailingTrivia())
                                  .WithAdditionalAnnotations(Formatter.Annotation);

                    editor.ReplaceNode(nodeToReplaceOpt, newNode);
                }

                document = document.WithSyntaxRoot(editor.GetChangedRoot());
                solution = document.Project.Solution;
            }

            return(solution, allReferencesFixed);

            // Local functions.
            bool IsReplacableOperation(IOperation operation)
            {
                // We only replace reference operations whose removal cannot change semantics.
                if (operation != null)
                {
                    switch (operation.Kind)
                    {
                    case OperationKind.InstanceReference:
                    case OperationKind.ParameterReference:
                    case OperationKind.LocalReference:
                        return(true);

                    case OperationKind.FieldReference:
                    case OperationKind.PropertyReference:
                        return(IsReplacableOperation(((IMemberReferenceOperation)operation).Instance));
                    }
                }

                return(false);
            }

            ISymbol GetSymbolForNodeToReplace(SyntaxNode nodeToReplace, SemanticModel semanticModel)
            {
                var symbolInfo             = semanticModel.GetSymbolInfo(nodeToReplace, cancellationToken);
                var symbolForNodeToReplace = symbolInfo.Symbol;

                if (symbolForNodeToReplace == null &&
                    symbolInfo.CandidateReason == CandidateReason.StaticInstanceMismatch &&
                    symbolInfo.CandidateSymbols.Length == 1)
                {
                    return(symbolInfo.CandidateSymbols[0]);
                }

                return(symbolForNodeToReplace);
            }
        }
示例#16
0
 public static SyntaxToken WithLeadingTrivia(this SyntaxToken token, [NotNull] SyntaxNode node)
 {
     Requires.NotNull(node, nameof(node));
     return(token.WithLeadingTrivia(node.GetLeadingTrivia()));
 }
示例#17
0
            void CheckXmlDocForErrors(SyntaxNode node, ISymbol member)
            {
                context.CancellationToken.ThrowIfCancellationRequested();

                foreach (var triva in node.GetLeadingTrivia())
                {
                    if (triva.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia))
                    {
                        storedXmlComment.Add((DocumentationCommentTriviaSyntax)triva.GetStructure());
                        new CRefVisistor(this).Visit(triva.GetStructure());
                    }
                }

                if (storedXmlComment.Count == 0)
                {
                    return;
                }

                xml.Clear();
                xml.Append(firstline);
                var OffsetTable = new List <int>();

                foreach (var cmt in storedXmlComment)
                {
                    OffsetTable.Add(xml.Length - firstline.Length);
                    xml.Append(cmt.Content + "\n");
                }
                xml.Append("</root>\n");

                var doc = new AXmlParser().Parse(SourceText.From(xml.ToString()));

                var stack = new Stack <AXmlObject>();

                stack.Push(doc);
                foreach (var err in doc.SyntaxErrors)
                {
                    AddXmlIssue(CalculateRealStartOffset(OffsetTable, err.StartOffset), err.EndOffset - err.StartOffset, err.Description);
                }

                while (stack.Count > 0)
                {
                    var cur = stack.Pop();
                    var el  = cur as AXmlElement;
                    if (el != null)
                    {
                        switch (el.Name)
                        {
                        case "typeparam":
                        case "typeparamref":
                            var name = el.Attributes.FirstOrDefault(attr => attr.Name == "name");
                            if (name == null || name.ValueSegment.Length < 2)
                            {
                                break;
                            }
                            if (member != null && member.IsKind(SymbolKind.NamedType))
                            {
                                var type = (INamedTypeSymbol)member;
                                if (!type.TypeArguments.Any(arg => arg.Name == name.Value))
                                {
                                    AddXmlIssue(CalculateRealStartOffset(OffsetTable, name.ValueSegment.Start + 1), name.ValueSegment.Length - 2, string.Format(GettextCatalog.GetString("Type parameter '{0}' not found"), name.Value));
                                }
                            }
                            break;

                        case "param":
                        case "paramref":
                            name = el.Attributes.FirstOrDefault(attr => attr.Name == "name");
                            if (name == null || name.ValueSegment.Length < 2)
                            {
                                break;
                            }
                            var m = member as IMethodSymbol;
                            if (m != null)
                            {
                                if (m.Parameters.Any(p => p.Name == name.Value))
                                {
                                    break;
                                }
                                AddXmlIssue(CalculateRealStartOffset(OffsetTable, name.ValueSegment.Start + 1), name.ValueSegment.Length - 2, string.Format(GettextCatalog.GetString("Parameter '{0}' not found"), name.Value));
                                break;
                            }
                            var prop = member as IPropertySymbol;
                            if (prop != null)
                            {
                                if (prop.Parameters.Any(p => p.Name == name.Value))
                                {
                                    break;
                                }
                                if (name.Value == "value")
                                {
                                    break;
                                }
                                AddXmlIssue(CalculateRealStartOffset(OffsetTable, name.ValueSegment.Start + 1), name.ValueSegment.Length - 2, string.Format(GettextCatalog.GetString("Parameter '{0}' not found"), name.Value));
                                break;
                            }
                            var evt = member as IEventSymbol;
                            if (evt != null)
                            {
                                if (name.Value == "value")
                                {
                                    break;
                                }
                                AddXmlIssue(CalculateRealStartOffset(OffsetTable, name.ValueSegment.Start + 1), name.ValueSegment.Length - 2, string.Format(GettextCatalog.GetString("Parameter '{0}' not found"), name.Value));
                                break;
                            }
                            var named = member as INamedTypeSymbol;
                            if (named != null)
                            {
                                if (named.DelegateInvokeMethod == null)
                                {
                                    break;
                                }
                                if (named.DelegateInvokeMethod.Parameters.Any(p => p.Name == name.Value))
                                {
                                    break;
                                }
                                AddXmlIssue(CalculateRealStartOffset(OffsetTable, name.ValueSegment.Start + 1), name.ValueSegment.Length - 2, string.Format(GettextCatalog.GetString("Parameter '{0}' not found"), name.Value));
                                break;
                            }
                            AddXmlIssue(CalculateRealStartOffset(OffsetTable, name.ValueSegment.Start + 1), name.ValueSegment.Length - 2, string.Format(GettextCatalog.GetString("Parameter '{0}' not found"), name.Value));
                            break;
                        }
                    }
                    foreach (var child in cur.Children)
                    {
                        stack.Push(child);
                    }
                }


                storedXmlComment.Clear();
            }
示例#18
0
 /// <summary>
 /// Adds the <c>auto-generated</c> file header to the document.
 /// </summary>
 public SyntaxNode Process(SyntaxNode syntax, ProcessorContext context)
 => syntax.WithLeadingTrivia(syntax.GetLeadingTrivia().Add(Comment(header)));
示例#19
0
 public static bool IsExteriorTriviaEmptyOrWhitespace(SyntaxNode node)
 {
     return(node.GetLeadingTrivia().IsEmptyOrWhitespace() &&
            node.GetTrailingTrivia().IsEmptyOrWhitespace());
 }
示例#20
0
        public static SyntaxTrivia GetIndentation(this SyntaxNode node)
        {
            IEnumerable <SyntaxTrivia> leadingTrivia = node.GetLeadingTrivia();

            return(leadingTrivia.GetIndentation());
        }
示例#21
0
        public DocumentationComment?GetSingleLineComment(SyntaxNode method)
        {
            var trivia = method.GetLeadingTrivia().FirstOrDefault(t => t.Kind() == SyntaxKind.SingleLineDocumentationCommentTrivia);

            return(trivia == default ? null : Translate(trivia));
        }
示例#22
0
        internal static async Task HandleDeclarationAsync(
            Document document, SyntaxEditor editor,
            SyntaxNode node, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var declarationContext = node.Parent;

            TypeSyntax typeSyntax = null;
            ParenthesizedVariableDesignationSyntax parensDesignation = null;

            if (declarationContext is RefTypeSyntax refType)
            {
                declarationContext = declarationContext.Parent;
            }

            if (declarationContext is VariableDeclarationSyntax varDecl)
            {
                typeSyntax = varDecl.Type;
            }
            else if (declarationContext is ForEachStatementSyntax forEach)
            {
                typeSyntax = forEach.Type;
            }
            else if (declarationContext is DeclarationExpressionSyntax declarationExpression)
            {
                typeSyntax = declarationExpression.Type;
                if (declarationExpression.Designation.IsKind(SyntaxKind.ParenthesizedVariableDesignation))
                {
                    parensDesignation = (ParenthesizedVariableDesignationSyntax)declarationExpression.Designation;
                }
            }
            else
            {
                Contract.Fail($"unhandled kind {declarationContext.Kind().ToString()}");
            }

            if (parensDesignation is null)
            {
                var typeSymbol = semanticModel.GetTypeInfo(typeSyntax.StripRefIfNeeded()).ConvertedType;

                // We're going to be passed through the simplifier.  Tell it to not just convert
                // this back to var (as that would defeat the purpose of this refactoring entirely).
                var typeName = typeSymbol.GenerateTypeSyntax(allowVar: false)
                               .WithLeadingTrivia(node.GetLeadingTrivia())
                               .WithTrailingTrivia(node.GetTrailingTrivia());
                Debug.Assert(!typeName.ContainsDiagnostics, "Explicit type replacement likely introduced an error in code");

                editor.ReplaceNode(node, typeName);
            }
            else
            {
                var tupleTypeSymbol = semanticModel.GetTypeInfo(typeSyntax.Parent).ConvertedType;

                var leadingTrivia = node.GetLeadingTrivia()
                                    .Concat(parensDesignation.GetAllPrecedingTriviaToPreviousToken().Where(t => !t.IsWhitespace()).Select(t => t.WithoutAnnotations(SyntaxAnnotation.ElasticAnnotation)));

                var tupleDeclaration = GenerateTupleDeclaration(tupleTypeSymbol, parensDesignation).WithLeadingTrivia(leadingTrivia);

                editor.ReplaceNode(declarationContext, tupleDeclaration);
            }
        }
示例#23
0
        private static SyntaxNode RemoveComments(SyntaxNode ele)
        {
            if (ele.HasLeadingTrivia)
            {
                var oldCommentsTrivias = from trivia in ele.GetLeadingTrivia().Where(
                    x => (x.Kind == SyntaxKind.MultiLineCommentTrivia || x.Kind == SyntaxKind.SingleLineCommentTrivia))
                                         select trivia;
                foreach (var comment in oldCommentsTrivias)
                {
                    ele = ele.ReplaceTrivia(comment, SyntaxTriviaList.Empty);                    

                }
            }
            if (ele.DescendantTrivia() != null && ele.DescendantTrivia().Count() > 0)
            {
                var containingComments = from trivia in ele.DescendantTrivia().Where(
                    x => (x.Kind == SyntaxKind.MultiLineCommentTrivia || x.Kind == SyntaxKind.SingleLineCommentTrivia))
                                         select trivia;
                foreach (var comment in containingComments)
                {
                    ele = ele.ReplaceTrivia(comment, SyntaxTriviaList.Empty);
                }
            }

            return ele;
        }
示例#24
0
        private static SyntaxNode ReplaceHeader(Document document, SyntaxNode root, StyleCopSettings settings, bool isMalformedHeader)
        {
            // If the header is well formed Xml then we parse out the copyright otherwise
            // Skip single line comments, whitespace, and end of line trivia until a blank line is encountered.
            SyntaxTriviaList trivia      = root.GetLeadingTrivia();
            bool             onBlankLine = false;
            bool             inCopyright = isMalformedHeader;
            int?   copyrightTriviaIndex  = null;
            var    removalList           = new List <int>();
            var    leadingSpaces         = string.Empty;
            string possibleLeadingSpaces = string.Empty;

            // remove header decoration lines, they will be re-generated
            trivia = RemoveHeaderDecorationLines(trivia, settings);

            // Need to do this with index so we get the line endings correct.
            for (int i = 0; i < trivia.Count; i++)
            {
                var  triviaLine = trivia[i];
                bool done       = false;
                switch (triviaLine.Kind())
                {
                case SyntaxKind.SingleLineCommentTrivia:
                    if (possibleLeadingSpaces != string.Empty)
                    {
                        leadingSpaces = possibleLeadingSpaces;
                    }

                    if (!isMalformedHeader)
                    {
                        var openingTag = triviaLine.ToFullString().Contains("<copyright ");
                        var closingTag = triviaLine.ToFullString().Contains("</copyright>") ||
                                         (openingTag && triviaLine.ToFullString().Trim().EndsWith("/>"));
                        if (openingTag)
                        {
                            inCopyright          = !closingTag;
                            copyrightTriviaIndex = i;
                        }
                        else if (inCopyright)
                        {
                            removalList.Add(i);
                            inCopyright = !closingTag;
                        }
                    }
                    else
                    {
                        removalList.Add(i);
                    }

                    onBlankLine = false;
                    break;

                case SyntaxKind.WhitespaceTrivia:
                    if (leadingSpaces == string.Empty)
                    {
                        possibleLeadingSpaces = triviaLine.ToFullString();
                    }

                    if (inCopyright)
                    {
                        removalList.Add(i);
                    }

                    break;

                case SyntaxKind.EndOfLineTrivia:
                    if (inCopyright)
                    {
                        removalList.Add(i);
                    }

                    if (onBlankLine)
                    {
                        done = true;
                    }
                    else
                    {
                        onBlankLine = true;
                    }

                    break;

                default:
                    done = true;
                    break;
                }

                if (done)
                {
                    break;
                }
            }

            // Remove copyright lines in reverse order.
            for (int i = removalList.Count - 1; i >= 0; i--)
            {
                trivia = trivia.RemoveAt(removalList[i]);
            }

            string newLineText   = document.Project.Solution.Workspace.Options.GetOption(FormattingOptions.NewLine, LanguageNames.CSharp);
            var    newLineTrivia = SyntaxFactory.EndOfLine(newLineText);

            var newHeaderTrivia = CreateNewHeader(leadingSpaces + "//", document.Name, settings, newLineText);

            if (!isMalformedHeader && copyrightTriviaIndex.HasValue)
            {
                // Does the copyright element have leading whitespace? If so remove it.
                if ((copyrightTriviaIndex.Value > 0) && trivia[copyrightTriviaIndex.Value - 1].IsKind(SyntaxKind.WhitespaceTrivia))
                {
                    copyrightTriviaIndex = copyrightTriviaIndex - 1;
                    trivia = trivia.RemoveAt(copyrightTriviaIndex.Value);
                }

                // Replace copyright element in place.
                return(root.WithLeadingTrivia(trivia.ReplaceRange(trivia[copyrightTriviaIndex.Value], newHeaderTrivia)));
            }
            else
            {
                // Add blank line if we don't already have comments at top of file.
                if (!FirstLineIsComment(trivia))
                {
                    newHeaderTrivia = newHeaderTrivia.Add(newLineTrivia);
                }

                // Insert header at top of the file.
                return(root.WithLeadingTrivia(newHeaderTrivia.Add(newLineTrivia).AddRange(trivia)));
            }
        }
        protected static void ComputePositionAndTriviaForRemoveAttributeFromAttributeList(
            SyntaxNode attributeToRemove,
            Func <SyntaxToken, bool> isComma,
            out int positionOfRemovedNode,
            out IEnumerable <SyntaxTrivia> triviaOfRemovedNode)
        {
            positionOfRemovedNode = attributeToRemove.FullSpan.Start;
            var root          = attributeToRemove.SyntaxTree.GetRoot();
            var previousToken = root.FindToken(attributeToRemove.FullSpan.Start - 1);
            var leading       = isComma(previousToken) ? previousToken.LeadingTrivia : attributeToRemove.GetLeadingTrivia();
            var nextToken     = root.FindToken(attributeToRemove.FullSpan.End + 1);
            var trailing      = isComma(nextToken) ? nextToken.TrailingTrivia : attributeToRemove.GetTrailingTrivia();

            triviaOfRemovedNode = leading.Concat(trailing);
        }
示例#26
0
 public static bool ShouldBeHidden(this SyntaxNode node, SyntaxTriviaList leadingTrivia) =>
 leadingTrivia != default(SyntaxTriviaList) &&
 SingleLineHideComment.IsMatch(node.GetLeadingTrivia().ToFullString());
示例#27
0
            private bool HasCopyrightHeader(SyntaxNode syntaxNode)
            {
                var existingHeader = GetExistingHeader(syntaxNode.GetLeadingTrivia());

                return(SequnceStartsWith(_header, existingHeader));
            }
示例#28
0
 /// <summary>
 /// Determines if the node is preceded by any multiline documentation.
 /// </summary>
 /// <param name="node">The node.</param>
 public static bool HasMultiLineDocumentationCommentTrivia(this SyntaxNode node) =>
 node.HasLeadingTrivia &&
 node.GetLeadingTrivia().Any(c => c.IsKind(SyntaxKind.MultiLineDocumentationCommentTrivia));
            public override SyntaxNode Visit(SyntaxNode node)
            {
                _cancellationToken.ThrowIfCancellationRequested();

                if (node == null)
                {
                    return node;
                }

                // Process children first
                node = base.Visit(node);

                // Check the leading trivia for doc comments.
                if (node.GetLeadingTrivia().Any(SyntaxKind.SingleLineDocumentationCommentTrivia))
                {
                    var newLeadingTrivia = new List<SyntaxTrivia>();

                    foreach (var trivia in node.GetLeadingTrivia())
                    {
                        if (trivia.Kind() == SyntaxKind.SingleLineDocumentationCommentTrivia)
                        {
                            newLeadingTrivia.Add(SyntaxFactory.Comment("//"));
                            newLeadingTrivia.Add(SyntaxFactory.ElasticCarriageReturnLineFeed);

                            var structuredTrivia = (DocumentationCommentTriviaSyntax)trivia.GetStructure();
                            newLeadingTrivia.AddRange(ConvertDocCommentToRegularComment(structuredTrivia));
                        }
                        else
                        {
                            newLeadingTrivia.Add(trivia);
                        }
                    }

                    node = node.WithLeadingTrivia(newLeadingTrivia);
                }

                return node;
            }
示例#30
0
        public SyntaxNode TraverseAndConvert(SyntaxNode node, SyntaxNode newNode)
        {
            // Step 1: Handle current node
            // Find out if this node is a documentable API declaration
            // If not, skip to go to the child nodes.
            string docCommentId = GetAPIForNode(node);

            if (docCommentId != null)

            {
                // Look up the comment text
                string docCommentText = GetDocCommentForId(docCommentId);

                // Get the SyntaxTrivia for the comment
                SyntaxTree newTree   = (CSharpSyntaxTree)CSharpSyntaxTree.ParseText(docCommentText);
                var        newTrivia = newTree.GetRoot().GetLeadingTrivia();
                // Read a doc comment from a syntax tree.
                //var classNode = (ClassDeclarationSyntax)newTree.GetRoot().ChildNodes().First();
                //var newTrivia = classNode.GetLeadingTrivia();
                //var docCommentTrivia = newTrivia.Single(t => t.Kind() == SyntaxKind.SingleLineDocumentationCommentTrivia ||
                //                                       t.Kind() == SyntaxKind.MultiLineDocumentationCommentTrivia);

                // Find out if there is an existing comment or doc comment
                if (node.HasLeadingTrivia)
                {
                    SyntaxTriviaList triviaList   = node.GetLeadingTrivia();
                    SyntaxTrivia     firstComment = triviaList.Last();
                    foreach (var trivia in triviaList.Reverse())
                    {
                        SyntaxKind kind = trivia.Kind();

                        switch (kind)
                        {
                        case SyntaxKind.SingleLineCommentTrivia:
                        case SyntaxKind.MultiLineCommentTrivia:
                            // Found existing comment
                            firstComment = trivia;
                            break;

                        case SyntaxKind.MultiLineDocumentationCommentTrivia:
                        case SyntaxKind.SingleLineDocumentationCommentTrivia:
                            // Found existing XML doc comment
                            firstComment = trivia;
                            break;

                        default:
                            break;
                        }
                    }


                    // Append the doc comment
                    newNode = node.InsertTriviaBefore(firstComment, newTrivia);
                }
                else // no leading trivia
                {
                    newNode = node.WithLeadingTrivia(newTrivia);
                }
            }
            else // not an API node
            {
                newNode = node;
            }

            if (node.ChildNodes().Count() > 0)
            {
                newNode = newNode.ReplaceNodes(newNode.ChildNodes(), TraverseAndConvert);
            }
            return(newNode);
        }
示例#31
0
        public static void CollectCommentBlockSpans(
            SyntaxNode node, ArrayBuilder<BlockSpan> spans)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            var triviaList = node.GetLeadingTrivia();

            CollectCommentBlockSpans(triviaList, spans);
        }
 private static SyntaxNode TrimLeadingNewLines(SyntaxNode node)
 => node.WithLeadingTrivia(node.GetLeadingTrivia().SkipWhile(t => t.Kind() == SyntaxKind.EndOfLineTrivia));
        private async Task <Document> ReplaceDateTimeWithDateTimeOffsetAsync(Document document, SyntaxNode node, CancellationToken cancellationToken)
        {
            SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken);

            IdentifierNameSyntax convertedNode = (IdentifierNameSyntax)node;

            IdentifierNameSyntax newNode = convertedNode?.WithIdentifier(SyntaxFactory.ParseToken("DateTimeOffset")).WithLeadingTrivia(node.GetLeadingTrivia()).WithTrailingTrivia(node.GetTrailingTrivia());

            SyntaxNode newRoot = root.ReplaceNode(node, newNode);

            Document newDocument = document.WithSyntaxRoot(newRoot);

            return(newDocument);
        }
示例#34
0
 /// <summary>
 /// Gets the number of steps that the given node is indented.
 /// </summary>
 /// <param name="indentationOptions">The indentation options to use.</param>
 /// <param name="node">The node to inspect.</param>
 /// <returns>The number of steps that the node is indented.</returns>
 public static int GetIndentationSteps(IndentationOptions indentationOptions, SyntaxNode node)
 {
     return(GetIndentationSteps(indentationOptions, node.SyntaxTree, node.GetLeadingTrivia()));
 }
 public static string ConvertTo(this SyntaxNode source, string middle)
 {
     return($"{source.GetLeadingTrivia().ToFullString()}{middle}{source.GetTrailingTrivia().ToFullString()}");
 }
示例#36
0
 public static bool IsAutogenerated(SyntaxNode contents)
 {
     return contents.GetLeadingTrivia().Any(x => x.ToFullString().Contains("<auto-generated"));
 }
        // VB can't override virtual events :\
        // See https://github.com/dotnet/vblang/issues/63
        protected override SyntaxNode AddEvent(SyntaxGenerator generator, SyntaxNode syntax, IEventSymbol symbol, SyntaxNode @event)
        => syntax.WithLeadingTrivia(syntax.GetLeadingTrivia().Add(
                                        CommentTrivia($@"' NOTE: overriding virtual events is not supported by VB.NET. Skipping {generator.GetName(@event)}. See https://github.com/dotnet/vblang/issues/63
")));
示例#38
0
        public static void CollectCommentRegions(SyntaxNode node, List<OutliningSpan> spans)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            var triviaList = node.GetLeadingTrivia();

            CollectCommentRegions(triviaList, spans);
        }
示例#39
0
 private static bool NoCommentsBefore(SyntaxNode node) => !node.GetLeadingTrivia().Any(t => t.IsComment());