/// <summary>
        /// This is jus a test to check the ability to preprocess the AST
        /// </summary>
        /// <param name="methodNode"></param>
        /// <param name="semanticModel"></param>
        /// <returns></returns>
        public static IMethodSymbol SimplifyASTForMethod(ref SyntaxNode methodNode, ref SemanticModel semanticModel)
        {
            var oldMethod = semanticModel.GetDeclaredSymbol(methodNode) as IMethodSymbol;

            var newMethodNode = MethodSimpifier.Test(methodNode);

            var annotation = new SyntaxAnnotation("Hi");

            newMethodNode = newMethodNode.WithAdditionalAnnotations(annotation);

            var root = methodNode.SyntaxTree.GetRoot();
            var newRoot = root.ReplaceNode(methodNode, newMethodNode);

            var oldCompilation = semanticModel.Compilation;

            var newCompilation = oldCompilation.ReplaceSyntaxTree(root.SyntaxTree, newRoot.SyntaxTree);
            var newSemanticModel = newCompilation.GetSemanticModel(newRoot.SyntaxTree);

            var recoveredMethodNode = newRoot.GetAnnotatedNodes(annotation).Single();

            var method = newSemanticModel.GetDeclaredSymbol(recoveredMethodNode) as IMethodSymbol;

            methodNode = recoveredMethodNode;
            semanticModel = newSemanticModel;

            return method;
        }
        private static bool CanRemoveTypeFromParameter(
            SyntaxNode node,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            // We reduce any the parameters that are contained inside ParameterList
            if (node != null && node.IsParentKind(SyntaxKind.ParameterList) && node.Parent.IsParentKind(SyntaxKind.ParenthesizedLambdaExpression))
            {
                var parameterSyntax = (ParameterSyntax)node;
                if (parameterSyntax.Type != null)
                {
                    var annotation = new SyntaxAnnotation();
                    var newParameterSyntax = parameterSyntax.WithType(null).WithAdditionalAnnotations(annotation);

                    var oldLambda = node.FirstAncestorOrSelf<ParenthesizedLambdaExpressionSyntax>();
                    var newLambda = oldLambda.ReplaceNode(parameterSyntax, newParameterSyntax);
                    var speculationAnalyzer = new SpeculationAnalyzer(oldLambda, newLambda, semanticModel, cancellationToken);
                    newParameterSyntax = (ParameterSyntax)speculationAnalyzer.ReplacedExpression.GetAnnotatedNodesAndTokens(annotation).First();

                    var oldSymbol = semanticModel.GetDeclaredSymbol(parameterSyntax, cancellationToken);
                    var newSymbol = speculationAnalyzer.SpeculativeSemanticModel.GetDeclaredSymbol(newParameterSyntax, cancellationToken);
                    if (oldSymbol != null &&
                        newSymbol != null &&
                        oldSymbol.Type == newSymbol.Type)
                    {
                        return !speculationAnalyzer.ReplacementChangesSemantics();
                    }
                }
            }

            return false;
        }
        protected override bool TryGetSimplifiedTypeNameInCaseContext(Document document, string fullyQualifiedTypeName, string firstEnumMemberName, int startPosition, int endPosition, CancellationToken cancellationToken, out string simplifiedTypeName)
        {
            simplifiedTypeName = string.Empty;
            var typeAnnotation = new SyntaxAnnotation();

            var str = "case " + fullyQualifiedTypeName + "." + firstEnumMemberName + ":" + Environment.NewLine + " break;";
            var textChange = new TextChange(new TextSpan(startPosition, endPosition - startPosition), str);
            var typeSpanToAnnotate = new TextSpan(startPosition + "case ".Length, fullyQualifiedTypeName.Length);

            var textWithCaseAdded = document.GetTextAsync(cancellationToken).WaitAndGetResult(cancellationToken).WithChanges(textChange);
            var documentWithCaseAdded = document.WithText(textWithCaseAdded);

            var syntaxRoot = documentWithCaseAdded.GetSyntaxRootSynchronously(cancellationToken);
            var nodeToReplace = syntaxRoot.DescendantNodes().FirstOrDefault(n => n.Span == typeSpanToAnnotate);

            if (nodeToReplace == null)
            {
                return false;
            }

            var updatedRoot = syntaxRoot.ReplaceNode(nodeToReplace, nodeToReplace.WithAdditionalAnnotations(typeAnnotation, Simplifier.Annotation));
            var documentWithAnnotations = documentWithCaseAdded.WithSyntaxRoot(updatedRoot);

            var simplifiedDocument = Simplifier.ReduceAsync(documentWithAnnotations, cancellationToken: cancellationToken).Result;
            simplifiedTypeName = simplifiedDocument.GetSyntaxRootSynchronously(cancellationToken).GetAnnotatedNodesAndTokens(typeAnnotation).Single().ToString();
            return true;
        }
            private SyntaxToken AnnotationResolver(
                SyntaxNode node,
                TriviaLocation location,
                SyntaxAnnotation annotation,
                SyntaxNode callsite,
                MethodDeclarationSyntax method)
            {
                var token = node.GetAnnotatedNodesAndTokens(annotation).FirstOrDefault().AsToken();
                if (token.RawKind != 0)
                {
                    return token;
                }

                switch (location)
                {
                    case TriviaLocation.BeforeBeginningOfSpan:
                        return callsite.GetFirstToken(includeZeroWidth: true).GetPreviousToken(includeZeroWidth: true);
                    case TriviaLocation.AfterEndOfSpan:
                        return callsite.GetLastToken(includeZeroWidth: true).GetNextToken(includeZeroWidth: true);
                    case TriviaLocation.AfterBeginningOfSpan:
                        return method.Body.OpenBraceToken.GetNextToken(includeZeroWidth: true);
                    case TriviaLocation.BeforeEndOfSpan:
                        return method.Body.CloseBraceToken.GetPreviousToken(includeZeroWidth: true);
                }

                return Contract.FailWithReturn<SyntaxToken>("can't happen");
            }
 public static async Task<InsertionPoint> CreateAsync(SemanticDocument document, SyntaxNode node, CancellationToken cancellationToken)
 {
     var root = document.Root;
     var annotation = new SyntaxAnnotation();
     var newRoot = root.AddAnnotations(SpecializedCollections.SingletonEnumerable(Tuple.Create(node, annotation)));
     return new InsertionPoint(await document.WithSyntaxRootAsync(newRoot, cancellationToken).ConfigureAwait(false), annotation);
 }
		public static TypeSyntax GenerateTypeSyntax(this ITypeSymbol typeSymbol, SyntaxAnnotation simplifierAnnotation = null)
		{
			var typeSyntax = (TypeSyntax)generateTypeSyntaxMethod.Invoke(null, new object[] { typeSymbol });
			if (simplifierAnnotation != null)
				return typeSyntax.WithAdditionalAnnotations(simplifierAnnotation);
			return typeSyntax;
		}
        public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            var document = context.Document;
            if (document.Project.Solution.Workspace.Kind == WorkspaceKind.MiscellaneousFiles)
                return;
            var span = context.Span;
            if (!span.IsEmpty)
                return;
            var cancellationToken = context.CancellationToken;
            if (cancellationToken.IsCancellationRequested)
                return;
            var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            if (model.IsFromGeneratedCode(cancellationToken))
                return;
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

            SyntaxToken token = root.FindToken(span.Start);
            if (!token.IsKind(SyntaxKind.IdentifierToken))
                return;
            var property = token.Parent as PropertyDeclarationSyntax;
            if (property == null || !property.Identifier.Span.Contains(span))
                return;
            if (IsEmptyComputedProperty(property))
            {
                context.RegisterRefactoring(
                    CodeActionFactory.Create(
                        token.Span,
                        DiagnosticSeverity.Info,
                        GettextCatalog.GetString("Convert to auto-property"),
                        t2 =>
                        {
                            var newRoot = root.ReplaceNode(property, CreateNewProperty(property).WithAdditionalAnnotations(Formatter.Annotation).WithLeadingTrivia(property.GetLeadingTrivia()));
                            return Task.FromResult(document.WithSyntaxRoot(newRoot));
                        }
                    )
                );
                return;
            }
            var field = GetBackingField(model, property);
            if (!IsValidField(field, property.Parent as TypeDeclarationSyntax))
                return;

            //variable declarator->declaration->field declaration
            var backingFieldNode = root.FindNode(field.Locations.First().SourceSpan).Ancestors().OfType<FieldDeclarationSyntax>().First();


            var propertyAnnotation = new SyntaxAnnotation();
            var fieldAnnotation = new SyntaxAnnotation();

            //annotate our property node and our field node
            root = root.ReplaceNode((SyntaxNode)property, property.WithAdditionalAnnotations(propertyAnnotation));
            root = root.ReplaceNode((SyntaxNode)root.FindNode(backingFieldNode.Span), backingFieldNode.WithAdditionalAnnotations(fieldAnnotation));

            context.RegisterRefactoring(
                CodeActionFactory.Create(token.Span, DiagnosticSeverity.Info, GettextCatalog.GetString("Convert to auto-property"),
                    PerformAction(document, model, root, field.Name, CreateNewProperty(property), propertyAnnotation, fieldAnnotation))
            );
        }
 internal SyntaxIdentifierWithTrailingTrivia(string text, GreenNode trailing, DiagnosticInfo[] diagnostics, SyntaxAnnotation[] annotations)
     : base(text, diagnostics, annotations)
 {
     if (trailing != null)
     {
         this.AdjustFlagsAndWidth(trailing);
         _trailing = trailing;
     }
 }
        public static SyntaxNode RemoveInitializer(SyntaxNode root, ConstructorDeclarationSyntax constructor)
        {
            var annotation = new SyntaxAnnotation();
            var ctor = constructor;
            var newRoot = root;
            newRoot = newRoot.ReplaceNode(ctor, ctor.WithAdditionalAnnotations(annotation));
            ctor = (ConstructorDeclarationSyntax)newRoot.GetAnnotatedNodes(annotation).First();
            var initializer = ctor.Initializer;

            if (RedundantInheritanceListCodeFixProvider.HasLineEnding(constructor.ParameterList))
            {
                newRoot = newRoot.RemoveNode(initializer, SyntaxRemoveOptions.KeepNoTrivia);
                ctor = (ConstructorDeclarationSyntax)newRoot.GetAnnotatedNodes(annotation).First();

                if (ctor.Body != null &&
                    ctor.Body.HasLeadingTrivia)
                {
                    var lastTrivia = ctor.Body.GetLeadingTrivia().Last();
                    newRoot = lastTrivia.IsKind(SyntaxKind.EndOfLineTrivia)
                        ? newRoot.ReplaceNode(
                            ctor.Body,
                            ctor.Body.WithoutLeadingTrivia())
                        : newRoot.ReplaceNode(
                            ctor.Body,
                            ctor.Body.WithLeadingTrivia(lastTrivia));
                }
            }
            else
            {
                var trailingTrivia = SyntaxFactory.TriviaList();
                if (initializer.HasTrailingTrivia)
                {
                    trailingTrivia = initializer.GetTrailingTrivia();
                }
                newRoot = newRoot.RemoveNode(initializer, SyntaxRemoveOptions.KeepNoTrivia);
                ctor = (ConstructorDeclarationSyntax)newRoot.GetAnnotatedNodes(annotation).First();

                if (ctor.Body != null &&
                    ctor.Body.HasLeadingTrivia)
                {
                    var lastTrivia = ctor.Body.GetLeadingTrivia().Last();
                    newRoot = newRoot.ReplaceNode(
                        ctor.Body,
                        ctor.Body.WithLeadingTrivia(trailingTrivia.Add(lastTrivia)));
                }
                else
                {
                    if (initializer.HasTrailingTrivia)
                    {
                        newRoot = newRoot.ReplaceNode(ctor, ctor.WithTrailingTrivia(trailingTrivia));
                    }
                }
            }

            ctor = (ConstructorDeclarationSyntax)newRoot.GetAnnotatedNodes(annotation).First();
            return newRoot.ReplaceNode(ctor, ctor.WithoutAnnotations(annotation));
        }
 internal WithTwoChildren(DiagnosticInfo[] diagnostics, SyntaxAnnotation[] annotations, GreenNode child0, GreenNode child1)
     : base(diagnostics, annotations)
 {
     this.SlotCount = 2;
     this.AdjustFlagsAndWidth(child0);
     _child0 = child0;
     this.AdjustFlagsAndWidth(child1);
     _child1 = child1;
 }
 internal abstract Solution GetSolutionWithUpdatedOriginalType(
     Solution solutionWithFormattedInterfaceDocument,
     INamedTypeSymbol extractedInterfaceSymbol,
     IEnumerable<ISymbol> includedMembers,
     Dictionary<ISymbol, SyntaxAnnotation> symbolToDeclarationAnnotationMap,
     List<DocumentId> documentIds,
     SyntaxAnnotation typeNodeAnnotation,
     DocumentId documentIdWithTypeNode,
     CancellationToken cancellationToken);
        private InsertionPoint(SemanticDocument document, SyntaxAnnotation annotation)
        {
            //Contract.ThrowIfNull(document);
            //Contract.ThrowIfNull(annotation);

            this.SemanticDocument = document;
            _annotation = annotation;
            _context = CreateLazyContextNode();
        }
Beispiel #13
0
        public void CodeCleaners_Annotation()
        {
            var document = CreateDocument("class C { }", LanguageNames.CSharp);
            var annotation = new SyntaxAnnotation();
            document = document.WithSyntaxRoot(document.GetSyntaxRootAsync().Result.WithAdditionalAnnotations(annotation));

            var cleanDocument = CodeCleaner.CleanupAsync(document, annotation).Result;

            Assert.Equal(document, cleanDocument);
        }
Beispiel #14
0
        private ExtractMethodResult CreateExtractMethodResult(
            OperationStatus status, SemanticDocument semanticDocument,
            SyntaxAnnotation invocationAnnotation, SyntaxAnnotation methodAnnotation)
        {
            var newRoot = semanticDocument.Root;
            var annotatedTokens = newRoot.GetAnnotatedNodesAndTokens(invocationAnnotation);
            var methodDefinition = newRoot.GetAnnotatedNodesAndTokens(methodAnnotation).FirstOrDefault().AsNode();

            return new SimpleExtractMethodResult(status, semanticDocument.Document, GetMethodNameAtInvocation(annotatedTokens), methodDefinition);
        }
 public StatementResult(
     OperationStatus status,
     TextSpan originalSpan,
     TextSpan finalSpan,
     OptionSet options,
     bool selectionInExpression,
     SemanticDocument document,
     SyntaxAnnotation firstTokenAnnotation,
     SyntaxAnnotation lastTokenAnnotation) :
     base(status, originalSpan, finalSpan, options, selectionInExpression, document, firstTokenAnnotation, lastTokenAnnotation)
 {
 }
Beispiel #16
0
        public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax property)
        {
            if (span.IntersectsWith(property.Span) && CodeGeneration.IsExpandableProperty(property, document))
            {
                var annotation = new SyntaxAnnotation();
                annotations.Add(annotation);

                return property.WithAdditionalAnnotations(annotation);
            }

            return base.VisitPropertyDeclaration(property);
        }
        private static void HandleThisExpression(SyntaxNodeAnalysisContext context)
        {
            if (!context.Node.Parent.IsKind(SyntaxKind.SimpleMemberAccessExpression))
            {
                return;
            }

            var memberAccessExpression = (MemberAccessExpressionSyntax)context.Node.Parent;
            var originalSymbolInfo = context.SemanticModel.GetSymbolInfo(memberAccessExpression, context.CancellationToken);
            if (originalSymbolInfo.Symbol == null)
            {
                return;
            }

            SyntaxNode speculationRoot;
            var annotation = new SyntaxAnnotation();
            SemanticModel speculativeModel;

            StatementSyntax statement = context.Node.FirstAncestorOrSelf<StatementSyntax>();
            if (statement != null)
            {
                var modifiedStatement = statement.ReplaceNode(memberAccessExpression, memberAccessExpression.Name.WithAdditionalAnnotations(annotation));
                speculationRoot = modifiedStatement;
                if (!context.SemanticModel.TryGetSpeculativeSemanticModel(statement.SpanStart, modifiedStatement, out speculativeModel))
                {
                    return;
                }
            }
            else
            {
                ArrowExpressionClauseSyntax arrowExpressionClause = context.Node.FirstAncestorOrSelf<ArrowExpressionClauseSyntax>();
                if (arrowExpressionClause == null)
                {
                    return;
                }

                var modifiedArrowExpressionClause = arrowExpressionClause.ReplaceNode(memberAccessExpression, memberAccessExpression.Name.WithAdditionalAnnotations(annotation));
                speculationRoot = modifiedArrowExpressionClause;
                if (!context.SemanticModel.TryGetSpeculativeSemanticModel(arrowExpressionClause.SpanStart, modifiedArrowExpressionClause, out speculativeModel))
                {
                    return;
                }
            }

            SyntaxNode mappedNode = speculationRoot.GetAnnotatedNodes(annotation).Single();
            var newSymbolInfo = speculativeModel.GetSymbolInfo(mappedNode, context.CancellationToken);
            if (!Equals(originalSymbolInfo.Symbol, newSymbolInfo.Symbol))
            {
                return;
            }

            context.ReportDiagnostic(Diagnostic.Create(Descriptor, context.Node.GetLocation()));
        }
 public static Task<Document> CaseCorrectAsync(Document document, SyntaxAnnotation annotation, CancellationToken cancellationToken)
 {
     try
     {
         return (Task<Document>)caseCorrectAsyncMethod.Invoke(null, new object[] { document, annotation, cancellationToken });
     }
     catch (TargetInvocationException ex)
     {
         ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
         return null;
     }
 }
 public Expander(
     SemanticModel semanticModel,
     Func<SyntaxNode, bool> expandInsideNode,
     bool expandParameter,
     CancellationToken cancellationToken,
     SyntaxAnnotation annotationForReplacedAliasIdentifier = null)
 {
     _semanticModel = semanticModel;
     _expandInsideNode = expandInsideNode;
     _expandParameter = expandParameter;
     _cancellationToken = cancellationToken;
     _annotationForReplacedAliasIdentifier = annotationForReplacedAliasIdentifier;
 }
        private static SyntaxNode RemoveDeclaration(SyntaxNode root, BaseListSyntax baseList,
            int redundantIndex)
        {
            var newBaseList = baseList
                .RemoveNode(baseList.Types[redundantIndex], SyntaxRemoveOptions.KeepNoTrivia)
                .WithAdditionalAnnotations(Formatter.Annotation);

            if (newBaseList.Types.Count != 0)
            {
                return root.ReplaceNode(baseList, newBaseList);
            }

            var baseTypeHadLineEnding = HasLineEnding(baseList.Types[redundantIndex]);
            var colonHadLineEnding = HasLineEnding(baseList.ColonToken);
            var typeNameHadLineEnding = HasLineEnding(((BaseTypeDeclarationSyntax)baseList.Parent).Identifier);

            var annotation = new SyntaxAnnotation();
            var newRoot = root.ReplaceNode(
                baseList.Parent,
                baseList.Parent.WithAdditionalAnnotations(annotation));
            var declaration = (BaseTypeDeclarationSyntax)newRoot.GetAnnotatedNodes(annotation).First();

            newRoot = newRoot.RemoveNode(declaration.BaseList, SyntaxRemoveOptions.KeepNoTrivia);
            declaration = (BaseTypeDeclarationSyntax)newRoot.GetAnnotatedNodes(annotation).First();

            var needsNewLine = !typeNameHadLineEnding &&
                (colonHadLineEnding || baseTypeHadLineEnding);

            if (needsNewLine)
            {
                var trivia = SyntaxFactory.TriviaList();
                if (declaration.Identifier.HasTrailingTrivia)
                {
                    trivia = declaration.Identifier.TrailingTrivia;
                }

                trivia = colonHadLineEnding
                    ? trivia.Add(baseList.ColonToken.TrailingTrivia.Last())
                    : trivia.AddRange(baseList.Types[redundantIndex].GetTrailingTrivia());

                newRoot = newRoot.ReplaceToken(
                        declaration.Identifier,
                        declaration.Identifier
                            .WithTrailingTrivia(trivia));
            }

            declaration = (BaseTypeDeclarationSyntax)newRoot.GetAnnotatedNodes(annotation).First();
            return newRoot.ReplaceNode(
                declaration,
                declaration.WithoutAnnotations(annotation));
        }
Beispiel #21
0
        protected GreenNode(ushort kind, DiagnosticInfo[] diagnostics, SyntaxAnnotation[] annotations) :
            this(kind, diagnostics)
        {
            if (annotations?.Length > 0)
            {
                foreach (var annotation in annotations)
                {
                    if (annotation == null) throw new ArgumentException(paramName: nameof(annotations), message: "" /*CSharpResources.ElementsCannotBeNull*/);
                }

                this.flags |= NodeFlags.ContainsAnnotations;
                s_annotationsTable.Add(this, annotations);
            }
        }
 internal SyntaxTokenWithTrivia(SyntaxKind kind, CSharpSyntaxNode leading, CSharpSyntaxNode trailing, DiagnosticInfo[] diagnostics, SyntaxAnnotation[] annotations)
     : base(kind, diagnostics, annotations)
 {
     if (leading != null)
     {
         this.AdjustFlagsAndWidth(leading);
         this.LeadingField = leading;
     }
     if (trailing != null)
     {
         this.AdjustFlagsAndWidth(trailing);
         this.TrailingField = trailing;
     }
 }
        internal override Solution GetSolutionWithUpdatedOriginalType(
            Solution solutionWithFormattedInterfaceDocument,
            INamedTypeSymbol extractedInterfaceSymbol,
            IEnumerable<ISymbol> includedMembers,
            Dictionary<ISymbol, SyntaxAnnotation> symbolToDeclarationAnnotationMap,
            List<DocumentId> documentIds,
            SyntaxAnnotation typeNodeAnnotation,
            DocumentId documentIdWithTypeNode,
            CancellationToken cancellationToken)
        {
            var documentWithTypeNode = solutionWithFormattedInterfaceDocument.GetDocument(documentIdWithTypeNode);
            var root = documentWithTypeNode.GetCSharpSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken);
            var typeDeclaration = root.GetAnnotatedNodes<TypeDeclarationSyntax>(typeNodeAnnotation).Single();

            var docId = solutionWithFormattedInterfaceDocument.GetDocument(typeDeclaration.SyntaxTree).Id;

            var implementedInterfaceTypeSyntax = extractedInterfaceSymbol.TypeParameters.Any()
                ? SyntaxFactory.GenericName(
                    SyntaxFactory.Identifier(extractedInterfaceSymbol.Name),
                    SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(extractedInterfaceSymbol.TypeParameters.Select(p => SyntaxFactory.ParseTypeName(p.Name)))))
                : SyntaxFactory.ParseTypeName(extractedInterfaceSymbol.Name);

            var baseList = typeDeclaration.BaseList ?? SyntaxFactory.BaseList();
            var updatedBaseList = baseList.WithTypes(SyntaxFactory.SeparatedList(baseList.Types.Union(new[] { SyntaxFactory.SimpleBaseType(implementedInterfaceTypeSyntax) })));

            if (!baseList.Types.Any())
            {
                // If we're adding the first element to the base list, then we need to move 
                // trivia from the type name itself to the end of the base list

                updatedBaseList = updatedBaseList.WithLeadingTrivia(SyntaxFactory.Space);

                if (typeDeclaration.TypeParameterList != null)
                {
                    updatedBaseList = updatedBaseList.WithTrailingTrivia(typeDeclaration.TypeParameterList.GetTrailingTrivia());
                    typeDeclaration = typeDeclaration.WithTypeParameterList(typeDeclaration.TypeParameterList.WithoutTrailingTrivia());
                }
                else
                {
                    updatedBaseList = updatedBaseList.WithTrailingTrivia(typeDeclaration.Identifier.TrailingTrivia);
                    typeDeclaration = typeDeclaration.WithIdentifier(typeDeclaration.Identifier.WithTrailingTrivia());
                }
            }

            var updatedTypeDeclaration = typeDeclaration.WithBaseList(updatedBaseList.WithAdditionalAnnotations(Formatter.Annotation));
            var updatedRoot = root.ReplaceNode(root.GetAnnotatedNodes<TypeDeclarationSyntax>(typeNodeAnnotation).Single(), updatedTypeDeclaration);
            var solutionWithOriginalTypeUpdated = solutionWithFormattedInterfaceDocument.WithDocumentSyntaxRoot(docId, updatedRoot, PreservationMode.PreserveIdentity);
            return solutionWithOriginalTypeUpdated;
        }
Beispiel #24
0
        internal static IDocument ExpandProperty(this IDocument document, PropertyDeclarationSyntax property)
        {
            // Annotate the property declaration so we can find it later.
            var propertyAnnotation = new SyntaxAnnotation();

            var newRoot = document.GetSyntaxRoot().ReplaceNode(
                property,
                property.WithAdditionalAnnotations(propertyAnnotation));

            IFieldSymbol backingField;
            return document
                .UpdateSyntaxRoot(newRoot)
                .GetOrCreateBackingField(propertyAnnotation, out backingField)
                .ExpandProperty(propertyAnnotation, backingField);
        }
 public static SyntaxToken ToIdentifierToken(this string identifier, bool isQueryContext = false)
 {
     string text = identifier.EscapeIdentifier(isQueryContext);
     if ((text.Length == 0) || (text[0] != '@'))
     {
         return SyntaxFactory.Identifier(text);
     }
     string valueText = identifier.StartsWith("@") ? identifier.Substring(1) : identifier;
     SyntaxTriviaList leading = new SyntaxTriviaList();
     SyntaxToken token = SyntaxFactory.Identifier(leading, SyntaxKind.None, '@' + valueText, valueText, new SyntaxTriviaList());
     if (!identifier.StartsWith("@"))
     {
         SyntaxAnnotation[] annotations = new SyntaxAnnotation[] { Simplifier.Annotation };
         token = token.WithAdditionalAnnotations(annotations);
     }
     return token;
 }
            public GeneratedCode(
                OperationStatus status,
                SemanticDocument document,
                SyntaxAnnotation methodNameAnnotation,
                SyntaxAnnotation callsiteAnnotation,
                SyntaxAnnotation methodDefinitionAnnotation)
            {
                Contract.ThrowIfNull(document);
                Contract.ThrowIfNull(methodNameAnnotation);
                Contract.ThrowIfNull(callsiteAnnotation);
                Contract.ThrowIfNull(methodDefinitionAnnotation);

                this.Status = status;
                this.SemanticDocument = document;
                this.MethodNameAnnotation = methodNameAnnotation;
                this.CallSiteAnnotation = callsiteAnnotation;
                this.MethodDefinitionAnnotation = methodDefinitionAnnotation;
            }
        protected override bool TryGetSimplifiedTypeName(Document documentWithFullyQualifiedTypeName, TextSpan updatedTextSpan, CancellationToken cancellationToken, out string simplifiedTypeName)
        {
            simplifiedTypeName = string.Empty;

            var typeAnnotation = new SyntaxAnnotation();
            var syntaxRoot = documentWithFullyQualifiedTypeName.GetSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken);
            var nodeToReplace = syntaxRoot.DescendantNodes().FirstOrDefault(n => n.Span == updatedTextSpan);

            if (nodeToReplace == null)
            {
                return false;
            }

            var updatedRoot = syntaxRoot.ReplaceNode(nodeToReplace, nodeToReplace.WithAdditionalAnnotations(typeAnnotation, Simplifier.Annotation));
            var documentWithAnnotations = documentWithFullyQualifiedTypeName.WithSyntaxRoot(updatedRoot);

            var simplifiedDocument = Simplifier.ReduceAsync(documentWithAnnotations, cancellationToken: cancellationToken).WaitAndGetResult(cancellationToken);
            simplifiedTypeName = simplifiedDocument.GetSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken).GetAnnotatedNodesAndTokens(typeAnnotation).Single().ToString();
            return true;
        }
 internal SyntaxIdentifierWithTrivia(
     SyntaxKind contextualKind,
     string text,
     string valueText,
     GreenNode leading,
     GreenNode trailing,
     DiagnosticInfo[] diagnostics,
     SyntaxAnnotation[] annotations)
     : base(contextualKind, text, valueText, diagnostics, annotations)
 {
     if (leading != null)
     {
         this.AdjustFlagsAndWidth(leading);
         _leading = leading;
     }
     if (trailing != null)
     {
         this.AdjustFlagsAndWidth(trailing);
         _trailing = trailing;
     }
 }
            internal async static Task<Document> GetChangeDocumentWithPragmaAdjustedAsync(
                Document document,
                TextSpan diagnosticSpan,
                SuppressionTargetInfo suppressionTargetInfo,
                Func<SyntaxToken, TextSpan, Task<SyntaxToken>> getNewStartToken,
                Func<SyntaxToken, TextSpan, Task<SyntaxToken>> getNewEndToken,
                CancellationToken cancellationToken)
            {
                var startToken = suppressionTargetInfo.StartToken;
                var endToken = suppressionTargetInfo.EndToken;
                var nodeWithTokens = suppressionTargetInfo.NodeWithTokens;
                var root = await nodeWithTokens.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

                var startAndEndTokenAreTheSame = startToken == endToken;
                SyntaxToken newStartToken = await getNewStartToken(startToken, diagnosticSpan).ConfigureAwait(false);

                SyntaxToken newEndToken = endToken;
                if (startAndEndTokenAreTheSame)
                {
                    var annotation = new SyntaxAnnotation();
                    newEndToken = root.ReplaceToken(startToken, newStartToken.WithAdditionalAnnotations(annotation)).GetAnnotatedTokens(annotation).Single();
                    var spanChange = newStartToken.LeadingTrivia.FullSpan.Length - startToken.LeadingTrivia.FullSpan.Length;
                    diagnosticSpan = new TextSpan(diagnosticSpan.Start + spanChange, diagnosticSpan.Length);
                }

                newEndToken = await getNewEndToken(newEndToken, diagnosticSpan).ConfigureAwait(false);

                SyntaxNode newNode;
                if (startAndEndTokenAreTheSame)
                {
                    newNode = nodeWithTokens.ReplaceToken(startToken, newEndToken);
                }
                else
                {
                    newNode = nodeWithTokens.ReplaceTokens(new[] { startToken, endToken }, (o, n) => o == startToken ? newStartToken : newEndToken);
                }

                var newRoot = root.ReplaceNode(nodeWithTokens, newNode);
                return document.WithSyntaxRoot(newRoot);
            }
Beispiel #30
0
        public void RoundTripSyntaxNodeWithMultipleReferencesToSameAnnotation()
        {
            var text = "public class C {}";
            var tree = SyntaxFactory.ParseSyntaxTree(text);
            var annotation = new SyntaxAnnotation();
            var root = tree.GetCompilationUnitRoot().WithAdditionalAnnotations(annotation, annotation);
            Assert.Equal(true, root.ContainsAnnotations);
            Assert.Equal(true, root.HasAnnotation(annotation));

            var stream = new MemoryStream();
            root.SerializeTo(stream);

            stream.Position = 0;

            var droot = CSharpSyntaxNode.DeserializeFrom(stream);
            var dtext = droot.ToFullString();

            Assert.Equal(text, dtext);
            Assert.Equal(true, droot.ContainsAnnotations);
            Assert.Equal(true, droot.HasAnnotation(annotation));
            Assert.Equal(true, droot.IsEquivalentTo(tree.GetCompilationUnitRoot()));
        }
Beispiel #31
0
 protected abstract Task <TNodeUnderContainer> GetStatementOrInitializerContainingInvocationToExtractedMethodAsync(SyntaxAnnotation callsiteAnnotation, CancellationToken cancellationToken);
 public static IList <SyntaxNode> MatchGetAnnotatedNodes(this PatternNode self, SyntaxNode node, SyntaxAnnotation syntaxAnnotation, SemanticModel semanticModel = null)
 {
     return(self.EnumerateGetAnnotatedNodes(node, syntaxAnnotation, semanticModel).ToList());
 }
        private static ExpressionSyntax GetNullCoalescing(ExpressionSyntax whenTrue, ExpressionSyntax whenFalse,
                                                          ExpressionSyntax compared, SemanticModel semanticModel, SyntaxAnnotation annotation)
        {
            if (CSharpEquivalenceChecker.AreEquivalent(whenTrue, compared))
            {
                var createdExpression = SyntaxFactory.BinaryExpression(
                    SyntaxKind.CoalesceExpression,
                    compared,
                    whenFalse)
                                        .WithAdditionalAnnotations(annotation);
                return(createdExpression);
            }

            if (CSharpEquivalenceChecker.AreEquivalent(whenFalse, compared))
            {
                var createdExpression = SyntaxFactory.BinaryExpression(
                    SyntaxKind.CoalesceExpression,
                    compared,
                    whenTrue)
                                        .WithAdditionalAnnotations(annotation);
                return(createdExpression);
            }

            return(GetSimplificationFromInvocations(whenTrue, whenFalse, null, compared, semanticModel, annotation,
                                                    isNullCoalescing: true));
        }
Beispiel #34
0
        /// <summary>
        /// Reduce the sub-trees annotated with <see cref="Annotation" /> found within the subtrees identified with the specified <paramref name="annotation"/>.
        /// The annotated node and all child nodes will be reduced.
        /// </summary>
        public static async Task <Document> ReduceAsync(Document document, SyntaxAnnotation annotation, OptionSet optionSet = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            return(await ReduceAsync(document, root.GetAnnotatedNodesAndTokens(annotation).Select(t => t.FullSpan), optionSet, cancellationToken).ConfigureAwait(false));
        }
Beispiel #35
0
        private void Reduce(
            Document document,
            SyntaxNode root,
            ImmutableArray <NodeOrTokenToReduce> nodesAndTokensToReduce,
            IEnumerable <AbstractReducer> reducers,
            OptionSet optionSet,
            CancellationToken cancellationToken,
            SemanticModel semanticModel,
            ConcurrentDictionary <SyntaxNode, SyntaxNode> reducedNodesMap,
            ConcurrentDictionary <SyntaxToken, SyntaxToken> reducedTokensMap)
        {
            Contract.ThrowIfFalse(nodesAndTokensToReduce.Any());

            // Reduce each node or token in the given list by running it through each reducer.
            var simplifyTasks = new Task[nodesAndTokensToReduce.Length];

            for (int i = 0; i < nodesAndTokensToReduce.Length; i++)
            {
                var nodeOrTokenToReduce = nodesAndTokensToReduce[i];
                simplifyTasks[i] = Task.Run(async() =>
                {
                    var nodeOrToken            = nodeOrTokenToReduce.OriginalNodeOrToken;
                    var simplifyAllDescendants = nodeOrTokenToReduce.SimplifyAllDescendants;
                    var semanticModelForReduce = semanticModel;
                    var currentNodeOrToken     = nodeOrTokenToReduce.NodeOrToken;
                    var isNode = nodeOrToken.IsNode;

                    foreach (var reducer in reducers)
                    {
                        cancellationToken.ThrowIfCancellationRequested();

                        var rewriter = reducer.CreateExpressionRewriter(optionSet, cancellationToken);

                        do
                        {
                            if (currentNodeOrToken.SyntaxTree != semanticModelForReduce.SyntaxTree)
                            {
                                // currentNodeOrToken was simplified either by a previous reducer or
                                // a previous iteration of the current reducer.
                                // Create a speculative semantic model for the simplified node for semantic queries.

                                // Certain node kinds (expressions/statements) require non-null parent nodes during simplification.
                                // However, the reduced nodes haven't been parented yet, so do the required parenting using the original node's parent.
                                if (currentNodeOrToken.Parent == null &&
                                    nodeOrToken.Parent != null &&
                                    (currentNodeOrToken.IsToken ||
                                     currentNodeOrToken.AsNode() is TExpressionSyntax ||
                                     currentNodeOrToken.AsNode() is TStatementSyntax ||
                                     currentNodeOrToken.AsNode() is TCrefSyntax))
                                {
                                    var annotation     = new SyntaxAnnotation();
                                    currentNodeOrToken = currentNodeOrToken.WithAdditionalAnnotations(annotation);

                                    var replacedParent = isNode ?
                                                         nodeOrToken.Parent.ReplaceNode(nodeOrToken.AsNode(), currentNodeOrToken.AsNode()) :
                                                         nodeOrToken.Parent.ReplaceToken(nodeOrToken.AsToken(), currentNodeOrToken.AsToken());

                                    currentNodeOrToken = replacedParent
                                                         .ChildNodesAndTokens()
                                                         .Single((c) => c.HasAnnotation(annotation));
                                }

                                if (isNode)
                                {
                                    var currentNode = currentNodeOrToken.AsNode();
                                    if (this.CanNodeBeSimplifiedWithoutSpeculation(nodeOrToken.AsNode()))
                                    {
                                        // Since this node cannot be speculated, we are replacing the Document with the changes and get a new SemanticModel
                                        SyntaxAnnotation marker = new SyntaxAnnotation();
                                        var newRoot             = root.ReplaceNode(nodeOrToken.AsNode(), currentNode.WithAdditionalAnnotations(marker));
                                        var newDocument         = document.WithSyntaxRoot(newRoot);
                                        semanticModelForReduce  = await newDocument.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
                                        newRoot            = await semanticModelForReduce.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
                                        currentNodeOrToken = newRoot.DescendantNodes().Single((c) => c.HasAnnotation(marker));
                                    }
                                    else
                                    {
                                        // Create speculative semantic model for simplified node.
                                        semanticModelForReduce = GetSpeculativeSemanticModel(ref currentNode, semanticModel, nodeOrToken.AsNode());
                                        currentNodeOrToken     = currentNode;
                                    }
                                }
                            }

                            // Reduce the current node or token.
                            currentNodeOrToken = rewriter.VisitNodeOrToken(currentNodeOrToken, semanticModelForReduce, simplifyAllDescendants);
                        }while (rewriter.HasMoreWork);
                    }

                    // If nodeOrToken was simplified, add it to the appropriate dictionary of replaced nodes/tokens.
                    if (currentNodeOrToken != nodeOrToken)
                    {
                        if (isNode)
                        {
                            reducedNodesMap[nodeOrToken.AsNode()] = currentNodeOrToken.AsNode();
                        }
                        else
                        {
                            reducedTokensMap[nodeOrToken.AsToken()] = currentNodeOrToken.AsToken();
                        }
                    }
                }, cancellationToken);
            }

            Task.WaitAll(simplifyTasks, cancellationToken);
        }
Beispiel #36
0
 public abstract SyntaxNode Expand(SyntaxNode node, SemanticModel semanticModel, SyntaxAnnotation annotationForReplacedAliasIdentifier, Func <SyntaxNode, bool> expandInsideNode, bool expandParameter, CancellationToken cancellationToken);
 public static IEnumerable <T> GetAnnotatedNodes <T>(this SyntaxNode node, SyntaxAnnotation syntaxAnnotation) where T : SyntaxNode
 {
     return(node.GetAnnotatedNodesAndTokens(syntaxAnnotation).Select(n => n.AsNode()).OfType <T>());
 }
Beispiel #38
0
        private static SyntaxNode GetUniformDepthRandomAnnotatedNode(SyntaxNode root, SyntaxAnnotation annotation)
        {
            //Console.WriteLine("Tree height for root: " + root);
            var levelNodes = new MultiValueDictionary <int, SyntaxNode>();

            GetTreeNodeHeights(root, levelNodes);
            //foreach (var level in levelNodes.Keys) {
            //	Console.WriteLine("level " + level + ": " + string.Join(", ", levelNodes[level].Select(n => n.ToString()).ToArray()));
            //}

            int        levelIndex  = RandomValueGenerator.Instance.GetInt(levelNodes.Count);
            var        syntaxNodes = levelNodes.Values.ElementAt(levelIndex);
            int        nodeIndex   = RandomValueGenerator.Instance.GetInt(syntaxNodes.Count);
            SyntaxNode node        = syntaxNodes.ElementAt(nodeIndex);

            //Console.WriteLine("random select node: " + node + ", level index=" + levelIndex + ", node index=" + nodeIndex);

            return(GetRandomAnnotatedNode(root, annotation));
        }
        protected async override Task <SyntaxNode> RewriteFieldNameAndAccessibility(string originalFieldName, bool makePrivate, Document document, SyntaxAnnotation declarationAnnotation, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var declarator = root.GetAnnotatedNodes <VariableDeclaratorSyntax>(declarationAnnotation).FirstOrDefault();

            // There may be no field to rewrite if this document is part of a set of linked files
            // and the declaration is not conditionally compiled in this document's project.
            if (declarator == null)
            {
                return(root);
            }

            var tempAnnotation = new SyntaxAnnotation();
            var newIdentifier  = SyntaxFactory.Identifier(originalFieldName)
                                 .WithTrailingTrivia(declarator.Identifier.TrailingTrivia)
                                 .WithLeadingTrivia(declarator.Identifier.LeadingTrivia);

            var updatedDeclarator = declarator.WithIdentifier(newIdentifier).WithAdditionalAnnotations(tempAnnotation);

            root     = root.ReplaceNode(declarator, updatedDeclarator);
            document = document.WithSyntaxRoot(root);

            var declaration = root.GetAnnotatedNodes <SyntaxNode>(tempAnnotation).First().Parent as VariableDeclarationSyntax;

            if (declaration.Variables.Count == 1)
            {
                var fieldSyntax = declaration.Parent as FieldDeclarationSyntax;

                var modifierKinds = new[] { SyntaxKind.PrivateKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.InternalKeyword, SyntaxKind.PublicKeyword };

                if (makePrivate)
                {
                    var modifiers = SpecializedCollections.SingletonEnumerable(SyntaxFactory.Token(SyntaxKind.PrivateKeyword))
                                    .Concat(fieldSyntax.Modifiers.Where(m => !modifierKinds.Contains(m.Kind())));

                    root = root.ReplaceNode(fieldSyntax, fieldSyntax.WithModifiers(
                                                SyntaxFactory.TokenList(modifiers))
                                            .WithAdditionalAnnotations(Formatter.Annotation)
                                            .WithLeadingTrivia(fieldSyntax.GetLeadingTrivia())
                                            .WithTrailingTrivia(fieldSyntax.GetTrailingTrivia()));
                }
            }
            else if (declaration.Variables.Count > 1 && makePrivate)
            {
                document = document.WithSyntaxRoot(root);
                var codeGenService = new CSharpCodeGenerationService(document.Project.Solution.Workspace.Services.GetLanguageServices(LanguageNames.CSharp));
                var semanticModel  = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

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

                declarator  = root.GetAnnotatedNodes <VariableDeclaratorSyntax>(tempAnnotation).First();
                declaration = declarator.Parent as VariableDeclarationSyntax;

                var field = semanticModel.GetDeclaredSymbol(declarator, cancellationToken) as IFieldSymbol;

                var fieldToAdd = declarationAnnotation.AddAnnotationToSymbol(CodeGenerationSymbolFactory.CreateFieldSymbol(
                                                                                 field.GetAttributes(),
                                                                                 Accessibility.Private,
                                                                                 new DeclarationModifiers().WithIsStatic(field.IsStatic).WithIsReadOnly(field.IsReadOnly).WithIsConst(field.IsConst),
                                                                                 field.Type,
                                                                                 field.Name,
                                                                                 field.HasConstantValue,
                                                                                 field.ConstantValue,
                                                                                 declarator.Initializer));

                var withField = await codeGenService.AddFieldAsync(document.Project.Solution, field.ContainingType, fieldToAdd, new CodeGenerationOptions(), cancellationToken).ConfigureAwait(false);

                root = await withField.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                declarator  = root.GetAnnotatedNodes <VariableDeclaratorSyntax>(tempAnnotation).First();
                declaration = declarator.Parent as VariableDeclarationSyntax;

                return(root.RemoveNode(declarator, SyntaxRemoveOptions.KeepNoTrivia));
            }

            return(root);
        }
 public override SyntaxNode Expand(SyntaxNode node, SemanticModel semanticModel, SyntaxAnnotation annotationForReplacedAliasIdentifier, Func <SyntaxNode, bool> expandInsideNode, bool expandParameter, CancellationToken cancellationToken)
 {
     using (Logger.LogBlock(FunctionId.Simplifier_ExpandNode, cancellationToken))
     {
         if (node is AttributeSyntax ||
             node is AttributeArgumentSyntax ||
             node is ConstructorInitializerSyntax ||
             node is ExpressionSyntax ||
             node is FieldDeclarationSyntax ||
             node is StatementSyntax ||
             node is CrefSyntax ||
             node is XmlNameAttributeSyntax ||
             node is TypeConstraintSyntax ||
             node is BaseTypeSyntax)
         {
             var rewriter = new Expander(semanticModel, expandInsideNode, expandParameter, cancellationToken, annotationForReplacedAliasIdentifier);
             return(rewriter.Visit(node));
         }
         else
         {
             throw new ArgumentException(CSharpWorkspaceResources.Only_attributes_constructor_initializers_expressions_or_statements_can_be_made_explicit, nameof(node));
         }
     }
 }
Beispiel #41
0
 public RemoveAnnotationRewriter(SyntaxAnnotation annotationToRemove)
     : base(visitIntoStructuredTrivia: false)
 {
     this.annotationToRemove = annotationToRemove ?? throw new ArgumentNullException(nameof(annotationToRemove));
 }
Beispiel #42
0
 public AwaitCallRewriter(SyntaxAnnotation callAnnotation)
     : base(visitIntoStructuredTrivia: false)
 {
     this.callAnnotation = callAnnotation ?? throw new ArgumentNullException(nameof(callAnnotation));
 }
Beispiel #43
0
 public static SyntaxToken GetTokenWithAnnotation(this SemanticDocument document, SyntaxAnnotation annotation)
 {
     return(document.Root.GetAnnotatedNodesAndTokens(annotation).Single().AsToken());
 }
        private static CodeAction GetActionToExecute(CodeFixContext context, SyntaxNode root,
                                                     SyntaxNode nodeToChange, SyntaxNode nodeToAdd, SyntaxAnnotation annotation)
        {
            return(CodeAction.Create(
                       Title,
                       c =>
            {
                var nodeToAddWithoutAnnotation = RemoveAnnotation(nodeToAdd, annotation);

                var newRoot = root.ReplaceNode(
                    nodeToChange,
                    nodeToAddWithoutAnnotation.WithTriviaFrom(nodeToChange).WithAdditionalAnnotations(Formatter.Annotation));
                return Task.FromResult(context.Document.WithSyntaxRoot(newRoot));
            }));
        }
Beispiel #45
0
        protected async override Task <SyntaxNode> RewriteFieldNameAndAccessibility(string originalFieldName, bool makePrivate, Document document, SyntaxAnnotation declarationAnnotation, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var declarator = root.GetAnnotatedNodes <VariableDeclarationSyntax>(declarationAnnotation).FirstOrDefault();

            // There may be no field to rewrite if this document is part of a set of linked files
            // and the declaration is not conditionally compiled in this document's project.
            if (declarator == null)
            {
                return(root);
            }

            var tempAnnotation = new SyntaxAnnotation();
            var escapedName    = originalFieldName.EscapeIdentifier();
            var newIdentifier  = SyntaxFactory.Identifier(
                leading: SyntaxTriviaList.Create(SyntaxFactory.ElasticMarker),
                contextualKind: SyntaxKind.IdentifierName,
                text: escapedName,
                valueText: originalFieldName,
                trailing: SyntaxTriviaList.Create(SyntaxFactory.ElasticMarker))
                                 .WithTrailingTrivia(declarator.Identifier.TrailingTrivia)
                                 .WithLeadingTrivia(declarator.Identifier.LeadingTrivia);

            var updatedDeclarator = declarator.WithIdentifier(newIdentifier).WithAdditionalAnnotations(tempAnnotation);

            root     = root.ReplaceNode(declarator, updatedDeclarator);
            document = document.WithSyntaxRoot(root);

            var declaration = root.GetAnnotatedNodes <SyntaxNode>(tempAnnotation).First().Parent as VariableDeclarationSyntax;

            if (declaration != null)
            {
                var fieldSyntax = declaration.Parent as FieldDeclarationSyntax;

                var modifierKinds = new[] { SyntaxKind.PrivateKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.InternalKeyword, SyntaxKind.PublicKeyword };

                if (makePrivate)
                {
                    var modifiers = SpecializedCollections.SingletonEnumerable(SyntaxFactory.Token(SyntaxKind.PrivateKeyword))
                                    .Concat(fieldSyntax.Modifiers.Where(m => !modifierKinds.Contains(m.Kind())));

                    root = root.ReplaceNode(fieldSyntax, fieldSyntax.WithModifiers(
                                                SyntaxFactory.TokenList(modifiers))
                                            .WithAdditionalAnnotations(Formatter.Annotation)
                                            .WithLeadingTrivia(fieldSyntax.GetLeadingTrivia())
                                            .WithTrailingTrivia(fieldSyntax.GetTrailingTrivia()));
                }
            }
            return(root);
        }
Beispiel #46
0
 private static ConstructorDeclarationSyntax GetConstructor(SyntaxNode newRoot, SyntaxAnnotation annotation)
 {
     return((ConstructorDeclarationSyntax)newRoot.GetAnnotatedNodes(annotation).First());
 }
Beispiel #47
0
        public SyntaxNode Replace(SyntaxNode root, SemanticModel model, Func <SyntaxNode, Tuple <SyntaxTree, SemanticModel> > updater)
        {
            var discards = root
                           .DescendantNodes()
                           .OfType <DiscardDesignationSyntax>();

            var outVars = root
                          .DescendantNodes()
                          .OfType <ArgumentSyntax>()
                          .Where(arg => arg.Expression is DeclarationExpressionSyntax && arg.RefOrOutKeyword.Kind() == SyntaxKind.OutKeyword);

            var outDiscardVars = root
                                 .DescendantNodes()
                                 .OfType <ArgumentSyntax>()
                                 .Where(arg => {
                if (arg.Expression is IdentifierNameSyntax ins && ins.Identifier.ValueText == DISCARD_IDENTIFIER && arg.RefOrOutKeyword.Kind() == SyntaxKind.OutKeyword)
                {
                    var si = model.GetSymbolInfo(arg.Expression);
                    return(si.Symbol == null || si.Symbol.Kind == SymbolKind.Discard);
                }

                return(false);
            });

            var discardAssigments = root
                                    .DescendantNodes()
                                    .OfType <AssignmentExpressionSyntax>()
                                    .Where(assignment => {
                if (assignment.Left is IdentifierNameSyntax ins && ins.Identifier.ValueText == DISCARD_IDENTIFIER)
                {
                    var si = model.GetSymbolInfo(assignment.Left);
                    return(si.Symbol == null || si.Symbol.Kind == SymbolKind.Discard);
                }

                return(false);
            });

            var updatedStatements  = new Dictionary <StatementSyntax, List <LocalDeclarationStatementSyntax> >();
            var updatedDiscards    = new Dictionary <DiscardDesignationSyntax, string>();
            var updatedDiscardVars = new Dictionary <ArgumentSyntax, string>();

            var tempIndex = 0;

            foreach (var discard in discards)
            {
                try
                {
                    var typeInfo        = model.GetTypeInfo(discard.Parent);
                    var beforeStatement = discard.Ancestors().OfType <StatementSyntax>().FirstOrDefault();

                    if (beforeStatement != null)
                    {
                        if (typeInfo.Type != null)
                        {
                            string instance = DISCARD_VARIABLE + ++tempIndex;
                            if (beforeStatement.Parent != null)
                            {
                                var info = LocalUsageGatherer.GatherInfo(model, beforeStatement.Parent);

                                while (info.DirectlyOrIndirectlyUsedLocals.Any(s => s.Name == instance) || info.Names.Contains(instance))
                                {
                                    instance = DISCARD_VARIABLE + ++tempIndex;
                                }
                            }

                            var locals  = updatedStatements.ContainsKey(beforeStatement) ? updatedStatements[beforeStatement] : new List <LocalDeclarationStatementSyntax>();
                            var varDecl = SyntaxFactory.VariableDeclaration(SyntaxHelper.GenerateTypeSyntax(typeInfo.Type, model, discard.Parent.GetLocation().SourceSpan.Start)).WithVariables(SyntaxFactory.SingletonSeparatedList <VariableDeclaratorSyntax>(
                                                                                                                                                                                                    SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(instance))
                                                                                                                                                                                                    ));

                            var local = SyntaxFactory.LocalDeclarationStatement(varDecl).NormalizeWhitespace().WithTrailingTrivia(SyntaxFactory.Whitespace("\n"));
                            locals.Add(local);

                            updatedStatements[beforeStatement] = locals;
                            updatedDiscards[discard]           = instance;
                        }
                        else if (discard.Parent is DeclarationPatternSyntax && !(discard.Parent.Parent is IsPatternExpressionSyntax))
                        {
                            string instance = DISCARD_VARIABLE + ++tempIndex;
                            if (beforeStatement.Parent != null)
                            {
                                var info = LocalUsageGatherer.GatherInfo(model, beforeStatement.Parent);

                                while (info.DirectlyOrIndirectlyUsedLocals.Any(s => s.Name == instance) || info.Names.Contains(instance))
                                {
                                    instance = DISCARD_VARIABLE + ++tempIndex;
                                }
                            }

                            updatedDiscards[discard] = instance;
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new ReplacerException(discard, e);
                }
            }

            foreach (var discardVar in outDiscardVars)
            {
                try
                {
                    var typeInfo = model.GetTypeInfo(discardVar.Expression);

                    if (typeInfo.Type != null)
                    {
                        var beforeStatement = discardVar.Ancestors().OfType <StatementSyntax>().FirstOrDefault();
                        if (beforeStatement != null)
                        {
                            string instance = DISCARD_VARIABLE + ++tempIndex;
                            if (beforeStatement.Parent != null)
                            {
                                var info = LocalUsageGatherer.GatherInfo(model, beforeStatement.Parent);

                                while (info.DirectlyOrIndirectlyUsedLocals.Any(s => s.Name == instance) || info.Names.Contains(instance))
                                {
                                    instance = DISCARD_VARIABLE + ++tempIndex;
                                }
                            }

                            var locals  = updatedStatements.ContainsKey(beforeStatement) ? updatedStatements[beforeStatement] : new List <LocalDeclarationStatementSyntax>();
                            var varDecl = SyntaxFactory.VariableDeclaration(SyntaxHelper.GenerateTypeSyntax(typeInfo.Type, model, discardVar.Expression.GetLocation().SourceSpan.Start)).WithVariables(SyntaxFactory.SingletonSeparatedList <VariableDeclaratorSyntax>(
                                                                                                                                                                                                           SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(instance))
                                                                                                                                                                                                           ));

                            var local = SyntaxFactory.LocalDeclarationStatement(varDecl).NormalizeWhitespace().WithTrailingTrivia(SyntaxFactory.Whitespace("\n"));
                            locals.Add(local);

                            updatedStatements[beforeStatement] = locals;
                            updatedDiscardVars[discardVar]     = instance;
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new ReplacerException(discardVar, e);
                }
            }

            foreach (var outVar in outVars)
            {
                try
                {
                    if (((DeclarationExpressionSyntax)outVar.Expression).Designation.Kind() == SyntaxKind.DiscardDesignation)
                    {
                        continue;
                    }

                    var typeInfo = model.GetTypeInfo(outVar.Expression);

                    if (typeInfo.Type != null)
                    {
                        var beforeStatement = outVar.Ancestors().OfType <StatementSyntax>().FirstOrDefault();
                        if (beforeStatement != null)
                        {
                            if (outVar.Expression is DeclarationExpressionSyntax de)
                            {
                                var designation = de.Designation as SingleVariableDesignationSyntax;

                                if (designation != null)
                                {
                                    var locals  = updatedStatements.ContainsKey(beforeStatement) ? updatedStatements[beforeStatement] : new List <LocalDeclarationStatementSyntax>();
                                    var varDecl = SyntaxFactory.VariableDeclaration(SyntaxHelper.GenerateTypeSyntax(typeInfo.Type, model, outVar.Expression.GetLocation().SourceSpan.Start)).WithVariables(SyntaxFactory.SingletonSeparatedList <VariableDeclaratorSyntax>(
                                                                                                                                                                                                               SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(designation.Identifier.ValueText))
                                                                                                                                                                                                               ));

                                    locals.Add(SyntaxFactory.LocalDeclarationStatement(varDecl).NormalizeWhitespace().WithTrailingTrivia(SyntaxFactory.Whitespace("\n")));

                                    updatedStatements[beforeStatement] = locals;
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new ReplacerException(outVar, e);
                }
            }

            var annotatedStatemnts   = new Dictionary <SyntaxAnnotation, List <LocalDeclarationStatementSyntax> >();
            var annotatedDiscards    = new Dictionary <SyntaxAnnotation, string>();
            var annotatedDiscardVars = new Dictionary <SyntaxAnnotation, string>();
            var annotatedAssigments  = new List <SyntaxAnnotation>();

            var keys = updatedStatements.Keys.Cast <SyntaxNode>()
                       .Concat(updatedDiscards.Keys.Cast <SyntaxNode>())
                       .Concat(updatedDiscardVars.Keys.Cast <SyntaxNode>())
                       .Concat(discardAssigments);

            root = root.ReplaceNodes(keys, (n1, n2) =>
            {
                var annotation = new SyntaxAnnotation();

                if (n1 is AssignmentExpressionSyntax)
                {
                    annotatedAssigments.Add(annotation);
                }
                else if (n1 is DiscardDesignationSyntax)
                {
                    annotatedDiscards[annotation] = updatedDiscards[(DiscardDesignationSyntax)n1];
                }
                else if (n1 is ArgumentSyntax)
                {
                    annotatedDiscardVars[annotation] = updatedDiscardVars[(ArgumentSyntax)n1];
                }
                else
                {
                    annotatedStatemnts[annotation] = updatedStatements[(StatementSyntax)n1];
                }

                n2 = n2.WithAdditionalAnnotations(annotation);
                return(n2);
            });

            foreach (var annotation in annotatedDiscards.Keys)
            {
                var annotatedNode = root.GetAnnotatedNodes(annotation).First();
                var name          = annotatedDiscards[annotation];

                root = root.ReplaceNode(annotatedNode, SyntaxFactory.SingleVariableDesignation(SyntaxFactory.Identifier(name)).NormalizeWhitespace());
            }

            foreach (var annotation in annotatedDiscardVars.Keys)
            {
                var annotatedNode = root.GetAnnotatedNodes(annotation).First();
                var name          = annotatedDiscardVars[annotation];

                root = root.ReplaceNode(annotatedNode, ((ArgumentSyntax)annotatedNode).WithExpression(SyntaxFactory.IdentifierName(name)));
            }

            foreach (var annotation in annotatedAssigments)
            {
                var annotatedNode = root.GetAnnotatedNodes(annotation).First();
                root = root.ReplaceNode(annotatedNode, ((AssignmentExpressionSyntax)annotatedNode).WithLeft(SyntaxFactory.IdentifierName("Bridge.Script.Discard")));
            }

            outVars = root
                      .DescendantNodes()
                      .OfType <ArgumentSyntax>()
                      .Where(arg => arg.Expression is DeclarationExpressionSyntax && arg.RefOrOutKeyword.Kind() == SyntaxKind.OutKeyword);

            root = root.ReplaceNodes(outVars, (n1, n2) =>
            {
                var designation = ((DeclarationExpressionSyntax)n2.Expression).Designation as SingleVariableDesignationSyntax;

                if (designation == null)
                {
                    return(n2);
                }

                return(SyntaxFactory.Argument(SyntaxFactory.IdentifierName(designation.Identifier)).WithRefKindKeyword(SyntaxFactory.Token(SyntaxKind.OutKeyword)).WithRefOrOutKeyword(SyntaxFactory.Token(SyntaxKind.OutKeyword)).NormalizeWhitespace());
            });

            foreach (var annotation in annotatedStatemnts.Keys)
            {
                var annotatedNode = root.GetAnnotatedNodes(annotation).First();
                var varStatements = annotatedStatemnts[annotation];

                if (annotatedNode.Parent is BlockSyntax || !(annotatedNode is StatementSyntax))
                {
                    root = root.InsertNodesBefore(annotatedNode, varStatements);
                }
                else
                {
                    var list = new List <StatementSyntax>(varStatements);
                    list.Add((StatementSyntax)annotatedNode);
                    root = root.ReplaceNode(annotatedNode, SyntaxFactory.Block(list).NormalizeWhitespace());
                }
            }

            var discardPatterns = root.DescendantNodes().OfType <IsPatternExpressionSyntax>().Where(pattern => pattern.Pattern is DeclarationPatternSyntax dp && dp.Designation.Kind() == SyntaxKind.DiscardDesignation);

            if (discardPatterns.Any())
            {
                root = root.ReplaceNodes(discardPatterns, (n1, n2) => {
                    return(SyntaxFactory.LiteralExpression(SyntaxKind.TrueLiteralExpression, SyntaxFactory.Token(SyntaxKind.TrueKeyword)));
                });
            }

            return(root);
        }
        private static CompilationUnitSyntax MoveUsingsInsideNamespace(CompilationUnitSyntax compilationUnit, SyntaxAnnotation warningAnnotation)
        {
            // Get the compilation unit usings and set them up to format when moved.
            var usingsToAdd = compilationUnit.Usings.Select(
                directive => directive.WithAdditionalAnnotations(Formatter.Annotation, warningAnnotation));

            // Remove usings and fix leading trivia for compilation unit.
            var compilationUnitWithoutUsings    = compilationUnit.WithUsings(default);
        private static ExpressionSyntax GetSimplificationFromInvocations(ExpressionSyntax expression1, ExpressionSyntax expression2,
                                                                         ExpressionSyntax condition, ExpressionSyntax compared, SemanticModel semanticModel, SyntaxAnnotation annotation,
                                                                         bool isNullCoalescing)
        {
            var methodCall2 = expression2 as InvocationExpressionSyntax;

            if (!(expression1 is InvocationExpressionSyntax methodCall1) ||
                methodCall2 == null)
            {
                return(null);
            }

            var methodSymbol1 = semanticModel.GetSymbolInfo(methodCall1).Symbol;
            var methodSymbol2 = semanticModel.GetSymbolInfo(methodCall2).Symbol;

            if (methodSymbol1 == null ||
                methodSymbol2 == null ||
                !methodSymbol1.Equals(methodSymbol2))
            {
                return(null);
            }

            var newArgumentList = SyntaxFactory.ArgumentList();

            for (var i = 0; i < methodCall1.ArgumentList.Arguments.Count; i++)
            {
                var arg1 = methodCall1.ArgumentList.Arguments[i];
                var arg2 = methodCall2.ArgumentList.Arguments[i];

                var expr1 = arg1.Expression.RemoveParentheses();
                var expr2 = arg2.Expression.RemoveParentheses();

                if (!CSharpEquivalenceChecker.AreEquivalent(expr1, expr2))
                {
                    ExpressionSyntax createdExpression;
                    if (isNullCoalescing)
                    {
                        var arg1IsCompared = CSharpEquivalenceChecker.AreEquivalent(expr1, compared);
                        var expression     = arg1IsCompared ? expr2 : expr1;

                        createdExpression = SyntaxFactory.BinaryExpression(SyntaxKind.CoalesceExpression, compared, expression);
                    }
                    else
                    {
                        createdExpression = SyntaxFactory.ConditionalExpression(condition, expr1, expr2);
                    }

                    newArgumentList = newArgumentList.AddArguments(
                        SyntaxFactory.Argument(
                            arg1.NameColon,
                            arg1.RefOrOutKeyword,
                            createdExpression.WithAdditionalAnnotations(annotation)));
                }
                else
                {
                    newArgumentList = newArgumentList.AddArguments(arg1.WithExpression(arg1.Expression.RemoveParentheses()));
                }
            }

            return(methodCall1.WithArgumentList(newArgumentList));
        }
Beispiel #50
0
        private async Task <Document> AddImportDirectivesFromSyntaxesAsync(
            Document document,
            CodeGenerationPreferences preferences,
            IEnumerable <SyntaxNode> syntaxNodes,
            IAddImportsService addImportsService,
            SyntaxGenerator generator,
            bool allowInHiddenRegions,
            CancellationToken cancellationToken)
        {
            using var _1 = ArrayBuilder <SyntaxNode> .GetInstance(out var importsToAdd);

            using var _2 = ArrayBuilder <SyntaxNode> .GetInstance(out var nodesToSimplify);

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

            var model = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var nodesWithExplicitNamespaces = syntaxNodes
                                              .Select(n => (syntaxnode: n, namespaceSymbol: GetExplicitNamespaceSymbol(n, model)));

            var addedSymbols = new HashSet <INamespaceSymbol>();

            foreach (var(node, namespaceSymbol) in nodesWithExplicitNamespaces)
            {
                if (namespaceSymbol is null)
                {
                    continue;
                }

                cancellationToken.ThrowIfCancellationRequested();

                nodesToSimplify.Add(node);

                if (addedSymbols.Contains(namespaceSymbol))
                {
                    continue;
                }

                var namespaceSyntax = GenerateNamespaceImportDeclaration(namespaceSymbol, generator);
                if (addImportsService.HasExistingImport(model.Compilation, root, node, namespaceSyntax, generator))
                {
                    continue;
                }

                if (IsInsideNamespace(node, namespaceSymbol, model, cancellationToken))
                {
                    continue;
                }

                addedSymbols.Add(namespaceSymbol);
                importsToAdd.Add(namespaceSyntax);
            }

            if (nodesToSimplify.Count == 0)
            {
                return(document);
            }

            var annotation = new SyntaxAnnotation();

            root = root.ReplaceNodes(
                nodesToSimplify,
                (o, r) => r.WithAdditionalAnnotations(Simplifier.Annotation, annotation));

            var first = root.DescendantNodesAndSelf().First(x => x.HasAnnotation(annotation));
            var last  = root.DescendantNodesAndSelf().Last(x => x.HasAnnotation(annotation));

            var context = first.GetCommonRoot(last);

            root = addImportsService.AddImports(
                model.Compilation, root, context, importsToAdd, generator, preferences,
                allowInHiddenRegions, cancellationToken);

            return(document.WithSyntaxRoot(root));
        }
 private static ConditionalExpressionSyntax GetConditionalExpression(ExpressionSyntax condition, ExpressionSyntax expressionTrue,
                                                                     ExpressionSyntax expressionFalse, SyntaxAnnotation annotation)
 {
     return(SyntaxFactory.ConditionalExpression(
                condition,
                expressionTrue,
                expressionFalse)
            .WithAdditionalAnnotations(annotation));
 }
Beispiel #52
0
        private (ImmutableArray <SyntaxNode> imports, IEnumerable <INamespaceSymbol> namespaceSymbols, SyntaxNode?context) GetImportDirectivesFromSyntaxesAsync(
            IEnumerable <SyntaxNode> syntaxNodes,
            ref SyntaxNode root,
            SemanticModel model,
            IAddImportsService addImportsService,
            SyntaxGenerator generator,
            CancellationToken cancellationToken
            )
        {
            var importsToAdd = ArrayBuilder <SyntaxNode> .GetInstance();

            var nodesWithExplicitNamespaces = syntaxNodes
                                              .Select(n => (syntaxnode: n, namespaceSymbol: GetExplicitNamespaceSymbol(n, model)))
                                              .Where(x => x.namespaceSymbol != null);

            var nodesToSimplify = ArrayBuilder <SyntaxNode> .GetInstance();

            var addedSymbols = new HashSet <INamespaceSymbol>();

            foreach (var(node, namespaceSymbol) in nodesWithExplicitNamespaces)
            {
                cancellationToken.ThrowIfCancellationRequested();

                nodesToSimplify.Add(node);

                if (addedSymbols.Contains(namespaceSymbol))
                {
                    continue;
                }

                var namespaceSyntax = GenerateNamespaceImportDeclaration(namespaceSymbol, generator);

                if (addImportsService.HasExistingImport(model.Compilation, root, node, namespaceSyntax))
                {
                    continue;
                }

                if (IsInsideNamespace(node, namespaceSymbol, model, cancellationToken))
                {
                    continue;
                }

                addedSymbols.Add(namespaceSymbol);
                importsToAdd.Add(namespaceSyntax);
            }

            if (nodesToSimplify.Count == 0)
            {
                nodesToSimplify.Free();
                return(importsToAdd.ToImmutableAndFree(), addedSymbols, null);
            }

            var annotation = new SyntaxAnnotation();

            root = root.ReplaceNodes(
                nodesToSimplify,
                (o, r) => r.WithAdditionalAnnotations(Simplifier.Annotation, annotation));

            var first = root.DescendantNodesAndSelf().First(x => x.HasAnnotation(annotation));
            var last  = root.DescendantNodesAndSelf().Last(x => x.HasAnnotation(annotation));

            nodesToSimplify.Free();
            return(importsToAdd.ToImmutableAndFree(), addedSymbols, first.GetCommonRoot(last));
        }
Beispiel #53
0
        public static async Task <(Document containingDocument, SyntaxAnnotation typeAnnotation)> AddTypeToNewFileAsync(
            Solution solution,
            string containingNamespaceDisplay,
            string fileName,
            ProjectId projectId,
            IEnumerable <string> folders,
            INamedTypeSymbol newSymbol,
            Document hintDocument,
            CleanCodeGenerationOptionsProvider fallbackOptions,
            CancellationToken cancellationToken)
        {
            var newDocumentId   = DocumentId.CreateNewId(projectId, debugName: fileName);
            var newDocumentPath = PathUtilities.CombinePaths(PathUtilities.GetDirectoryName(hintDocument.FilePath), fileName);

            var solutionWithInterfaceDocument = solution.AddDocument(newDocumentId, fileName, text: "", folders: folders, filePath: newDocumentPath);
            var newDocument      = solutionWithInterfaceDocument.GetRequiredDocument(newDocumentId);
            var newSemanticModel = await newDocument.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var context = new CodeGenerationContext(
                contextLocation: newSemanticModel.SyntaxTree.GetLocation(new TextSpan()),
                generateMethodBodies: true);

            // need to remove the root namespace from the containing namespace display because it is implied
            // For C# this does nothing as there is no root namespace (root namespace is empty string)
            var generateTypeService = newDocument.GetRequiredLanguageService <IGenerateTypeService>();
            var rootNamespace       = generateTypeService.GetRootNamespace(newDocument.Project.CompilationOptions);
            var index = rootNamespace.IsEmpty() ? -1 : containingNamespaceDisplay.IndexOf(rootNamespace);
            // if we did find the root namespace as the first element, then we remove it
            // this may leave us with an extra "." character at the start, but when we split it shouldn't matter
            var namespaceWithoutRoot = index == 0
                ? containingNamespaceDisplay.Remove(index, rootNamespace.Length)
                : containingNamespaceDisplay;

            var namespaceParts  = namespaceWithoutRoot.Split('.').Where(s => !string.IsNullOrEmpty(s));
            var newTypeDocument = await CodeGenerator.AddNamespaceOrTypeDeclarationAsync(
                new CodeGenerationSolutionContext(
                    newDocument.Project.Solution,
                    context,
                    fallbackOptions),
                newSemanticModel.GetEnclosingNamespace(0, cancellationToken),
                newSymbol.GenerateRootNamespaceOrType(namespaceParts.ToArray()),
                cancellationToken).ConfigureAwait(false);

            var newCleanupOptions = await newTypeDocument.GetCodeCleanupOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false);

            var formattingService = newTypeDocument.GetLanguageService <INewDocumentFormattingService>();

            if (formattingService is not null)
            {
                newTypeDocument = await formattingService.FormatNewDocumentAsync(newTypeDocument, hintDocument, newCleanupOptions, cancellationToken).ConfigureAwait(false);
            }

            var syntaxRoot = await newTypeDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var typeAnnotation = new SyntaxAnnotation();
            var syntaxFacts    = newTypeDocument.GetRequiredLanguageService <ISyntaxFactsService>();

            var declarationNode = syntaxRoot.DescendantNodes().First(syntaxFacts.IsTypeDeclaration);
            var annotatedRoot   = syntaxRoot.ReplaceNode(declarationNode, declarationNode.WithAdditionalAnnotations(typeAnnotation));

            newTypeDocument = newTypeDocument.WithSyntaxRoot(annotatedRoot);

            var simplified = await Simplifier.ReduceAsync(newTypeDocument, newCleanupOptions.SimplifierOptions, cancellationToken).ConfigureAwait(false);

            var formattedDocument = await Formatter.FormatAsync(simplified, newCleanupOptions.FormattingOptions, cancellationToken).ConfigureAwait(false);

            return(formattedDocument, typeAnnotation);
        }
        private static async Task <T> FindNodeWithAnnotationAsync <T>(Document document, SyntaxAnnotation annotation, CancellationToken cancellationToken)
            where T : SyntaxNode
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            return(root
                   .GetAnnotatedNodesAndTokens(annotation)
                   .Single()
                   .AsNode() as T);
        }
        private async Task <Result> EncapsulateFieldAsync(IFieldSymbol field, Document document, bool updateReferences, CancellationToken cancellationToken)
        {
            var originalField         = field;
            var finalNames            = GeneratePropertyAndFieldNames(field);
            var finalFieldName        = finalNames.Item1;
            var generatedPropertyName = finalNames.Item2;

            // Annotate the field declarations so we can find it after rename.
            var fieldDeclaration      = field.DeclaringSyntaxReferences.First();
            var declarationAnnotation = new SyntaxAnnotation();

            document = document.WithSyntaxRoot(fieldDeclaration.SyntaxTree.GetRoot(cancellationToken).ReplaceNode(fieldDeclaration.GetSyntax(cancellationToken),
                                                                                                                  fieldDeclaration.GetSyntax(cancellationToken).WithAdditionalAnnotations(declarationAnnotation)));

            var solution = document.Project.Solution;

            foreach (var linkedDocumentId in document.GetLinkedDocumentIds())
            {
                var linkedDocument = solution.GetDocument(linkedDocumentId);
                var linkedRoot     = await linkedDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                var linkedFieldNode = linkedRoot.FindNode(fieldDeclaration.Span);
                if (linkedFieldNode.Span != fieldDeclaration.Span)
                {
                    continue;
                }

                var updatedRoot = linkedRoot.ReplaceNode(linkedFieldNode, linkedFieldNode.WithAdditionalAnnotations(declarationAnnotation));
                solution = solution.WithDocumentSyntaxRoot(linkedDocumentId, updatedRoot);
            }

            document = solution.GetDocument(document.Id);

            // Resolve the annotated symbol and prepare for rename.

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

            var compilation = semanticModel.Compilation;

            field = field.GetSymbolKey().Resolve(compilation, cancellationToken: cancellationToken).Symbol as IFieldSymbol;

            var solutionNeedingProperty = solution;

            // We couldn't resolve field after annotating its declaration. Bail
            if (field == null)
            {
                return(null);
            }

            solutionNeedingProperty = await UpdateReferencesAsync(
                updateReferences, solution, document, field, finalFieldName, generatedPropertyName, cancellationToken).ConfigureAwait(false);

            document = solutionNeedingProperty.GetDocument(document.Id);

            var markFieldPrivate          = field.DeclaredAccessibility != Accessibility.Private;
            var rewrittenFieldDeclaration = await RewriteFieldNameAndAccessibility(finalFieldName, markFieldPrivate, document, declarationAnnotation, cancellationToken).ConfigureAwait(false);

            document = await Formatter.FormatAsync(document.WithSyntaxRoot(rewrittenFieldDeclaration), Formatter.Annotation, cancellationToken : cancellationToken).ConfigureAwait(false);

            solution = document.Project.Solution;
            foreach (var linkedDocumentId in document.GetLinkedDocumentIds())
            {
                var linkedDocument    = solution.GetDocument(linkedDocumentId);
                var updatedLinkedRoot = await RewriteFieldNameAndAccessibility(finalFieldName, markFieldPrivate, linkedDocument, declarationAnnotation, cancellationToken).ConfigureAwait(false);

                var updatedLinkedDocument = await Formatter.FormatAsync(linkedDocument.WithSyntaxRoot(updatedLinkedRoot), Formatter.Annotation, cancellationToken : cancellationToken).ConfigureAwait(false);

                solution = updatedLinkedDocument.Project.Solution;
            }

            document = solution.GetDocument(document.Id);

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

            compilation = semanticModel.Compilation;

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

            var newDeclaration = newRoot.GetAnnotatedNodes <SyntaxNode>(declarationAnnotation).First();

            field = semanticModel.GetDeclaredSymbol(newDeclaration, cancellationToken) as IFieldSymbol;

            var generatedProperty = GenerateProperty(generatedPropertyName, finalFieldName, originalField.DeclaredAccessibility, originalField, field.ContainingType, new SyntaxAnnotation(), document, cancellationToken);

            var codeGenerationService = document.GetLanguageService <ICodeGenerationService>();
            var solutionWithProperty  = await AddPropertyAsync(
                document, document.Project.Solution, field, generatedProperty, cancellationToken).ConfigureAwait(false);

            return(new Result(solutionWithProperty, originalField.ToDisplayString(), originalField.GetGlyph()));
        }
        private static StatementSyntax GetSimplified(StatementSyntax statement1, StatementSyntax statement2,
                                                     ExpressionSyntax condition, ExpressionSyntax compared, SemanticModel semanticModel, SyntaxAnnotation annotation,
                                                     bool isNullCoalescing)
        {
            if (statement1 is ReturnStatementSyntax return1 &&
                statement2 is ReturnStatementSyntax return2)
            {
                var retExpr1 = return1.Expression.RemoveParentheses();
                var retExpr2 = return2.Expression.RemoveParentheses();

                var createdExpression = isNullCoalescing
                    ? GetNullCoalescing(retExpr1, retExpr2, compared, semanticModel, annotation)
                    : GetConditionalExpression(condition, return1.Expression, return2.Expression, annotation);

                return(SyntaxFactory.ReturnStatement(createdExpression));
            }

            var expressionStatement1 = statement1 as ExpressionStatementSyntax;
            var expressionStatement2 = statement2 as ExpressionStatementSyntax;

            var expression1 = expressionStatement1.Expression.RemoveParentheses();
            var expression2 = expressionStatement2.Expression.RemoveParentheses();

            var assignment = GetSimplifiedAssignment(expression1, expression2, condition, compared, semanticModel, annotation, isNullCoalescing);

            if (assignment != null)
            {
                return(SyntaxFactory.ExpressionStatement(assignment));
            }

            var expression = GetSimplificationFromInvocations(expression1, expression2, condition, compared, semanticModel, annotation, isNullCoalescing);

            return(expression != null
                ? SyntaxFactory.ExpressionStatement(expression)
                : null);
        }
 public static IEnumerable <SyntaxNode> EnumerateGetAnnotatedNodes(this PatternNode self, SyntaxNode node, SyntaxAnnotation syntaxAnnotation, SemanticModel semanticModel = null)
 {
     return(self.Enumerate(node.GetAnnotatedNodes(syntaxAnnotation), semanticModel));
 }
        private static ExpressionSyntax GetSimplifiedAssignment(ExpressionSyntax expression1, ExpressionSyntax expression2,
                                                                ExpressionSyntax condition, ExpressionSyntax compared, SemanticModel semanticModel, SyntaxAnnotation annotation,
                                                                bool isNullCoalescing)
        {
            var assignment1     = expression1 as AssignmentExpressionSyntax;
            var assignment2     = expression2 as AssignmentExpressionSyntax;
            var canBeSimplified =
                assignment1 != null &&
                assignment2 != null &&
                CSharpEquivalenceChecker.AreEquivalent(assignment1.Left, assignment2.Left) &&
                assignment1.Kind() == assignment2.Kind();

            if (!canBeSimplified)
            {
                return(null);
            }

            var createdExpression = isNullCoalescing
                ? GetNullCoalescing(assignment1.Right, assignment2.Right, compared, semanticModel, annotation)
                : GetConditionalExpression(condition, assignment1.Right, assignment2.Right, annotation);

            return(SyntaxFactory.AssignmentExpression(
                       assignment1.Kind(),
                       assignment1.Left,
                       createdExpression));
        }
Beispiel #59
0
        public async Task <Document> AddImportsAsync(
            Document document,
            IEnumerable <TextSpan> spans,
            Strategy strategy,
            bool safe,
            OptionSet?options,
            CancellationToken cancellationToken)
        {
            options ??= await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);

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

            Contract.ThrowIfNull(model);
            var root = await model.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

            var addImportsService = document.GetLanguageService <IAddImportsService>();
            var generator         = SyntaxGenerator.GetGenerator(document);

            // Create a simple interval tree for simplification spans.
            var spansTree = new SimpleIntervalTree <TextSpan>(TextSpanIntervalIntrospector.Instance, spans);

            var nodes = root.DescendantNodesAndSelf().Where(IsInSpan);

            var(importDirectivesToAdd, namespaceSymbols, context) = strategy switch
            {
                Strategy.AddImportsFromSymbolAnnotations
                => GetImportDirectivesFromAnnotatedNodesAsync(nodes, root, model, addImportsService, generator, cancellationToken),
                Strategy.AddImportsFromSyntaxes
                => GetImportDirectivesFromSyntaxesAsync(nodes, ref root, model, addImportsService, generator, cancellationToken),
                _ => throw new InvalidEnumArgumentException(nameof(strategy), (int)strategy, typeof(Strategy)),
            };

            if (importDirectivesToAdd.Length == 0)
            {
                return(document.WithSyntaxRoot(root)); //keep any added simplifier annotations
            }

            if (safe)
            {
                // Mark the context with an annotation.
                // This will allow us to find it after we have called MakeSafeToAddNamespaces.
                var annotation = new SyntaxAnnotation();
                document = document.WithSyntaxRoot(root.ReplaceNode(context, context.WithAdditionalAnnotations(annotation)));
                root     = (await document.GetSyntaxRootAsync().ConfigureAwait(false)) !;

                model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                Contract.ThrowIfNull(model);

                // Make Safe to add namespaces
                document = document.WithSyntaxRoot(
                    MakeSafeToAddNamespaces(root, namespaceSymbols, model, document.Project.Solution.Workspace, cancellationToken));
                root = (await document.GetSyntaxRootAsync().ConfigureAwait(false)) !;

                model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                Contract.ThrowIfNull(model);

                // Find the context. It might be null if we have removed the context in the process of complexifying the tree.
                context = root.DescendantNodesAndSelf().FirstOrDefault(x => x.HasAnnotation(annotation)) ?? root;
            }

            var placeSystemNamespaceFirst = options.GetOption(GenerationOptions.PlaceSystemNamespaceFirst, document.Project.Language);

            root = addImportsService.AddImports(model.Compilation, root, context, importDirectivesToAdd, placeSystemNamespaceFirst, cancellationToken);

            return(document.WithSyntaxRoot(root));

            bool IsInSpan(SyntaxNode node) =>
            spansTree.HasIntervalThatOverlapsWith(node.FullSpan.Start, node.FullSpan.Length);
        }
        /// <summary>
        /// Ensure that an event handler exists for a given event.
        /// </summary>
        /// <param name="thisDocument">The document corresponding to this operation.</param>
        /// <param name="targetDocument">The document to generate the event handler in if it doesn't
        /// exist.</param>
        /// <param name="className">The name of the type to generate the event handler in.</param>
        /// <param name="objectName">The name of the event member (if <paramref
        /// name="useHandlesClause"/> is true)</param>
        /// <param name="objectTypeName">The name of the type containing the event.</param>
        /// <param name="nameOfEvent">The name of the event member in <paramref
        /// name="objectTypeName"/></param>
        /// <param name="eventHandlerName">The name of the method to be hooked up to the
        /// event.</param>
        /// <param name="itemidInsertionPoint">The VS itemid of the file to generate the event
        /// handler in.</param>
        /// <param name="useHandlesClause">If true, a vb "Handles" clause will be generated for the
        /// handler.</param>
        /// <param name="additionalFormattingRule">An additional formatting rule that can be used to
        /// format the newly inserted method</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        /// <returns>Either the unique id of the method if it already exists, or the unique id of
        /// the to be generated method, the text of the to be generated method, and the position in
        /// <paramref name="itemidInsertionPoint"/> where the text should be inserted.</returns>
        public static Tuple <string, string, VsTextSpan> EnsureEventHandler(
            Document thisDocument,
            Document targetDocument,
            string className,
            string objectName,
            string objectTypeName,
            string nameOfEvent,
            string eventHandlerName,
            uint itemidInsertionPoint,
            bool useHandlesClause,
            IFormattingRule additionalFormattingRule,
            CancellationToken cancellationToken)
        {
            var thisCompilation = thisDocument.Project.GetCompilationAsync(cancellationToken).WaitAndGetResult(cancellationToken);
            var type            = thisCompilation.GetTypeByMetadataName(className);

            var existingEventHandlers = GetCompatibleEventHandlers(targetDocument, className, objectTypeName, nameOfEvent, cancellationToken);
            var existingHandler       = existingEventHandlers.SingleOrDefault(e => e.Item1 == eventHandlerName);

            if (existingHandler != null)
            {
                return(Tuple.Create(existingHandler.Item2, (string)null, default(VsTextSpan)));
            }

            // Okay, it doesn't exist yet.  Let's create it.
            var codeGenerationService = targetDocument.GetLanguageService <ICodeGenerationService>();
            var syntaxFactory         = targetDocument.GetLanguageService <SyntaxGenerator>();
            var eventMember           = GetEventSymbol(thisDocument, objectTypeName, nameOfEvent, type, cancellationToken);

            if (eventMember == null)
            {
                throw new InvalidOperationException();
            }

            var eventType = ((IEventSymbol)eventMember).Type;

            if (eventType.Kind != SymbolKind.NamedType || ((INamedTypeSymbol)eventType).DelegateInvokeMethod == null)
            {
                throw new InvalidOperationException(ServicesVSResources.EventTypeIsInvalid);
            }

            var handlesExpressions = useHandlesClause ?
                                     new[]
            {
                syntaxFactory.MemberAccessExpression(
                    objectName != null ? syntaxFactory.IdentifierName(objectName) : syntaxFactory.ThisExpression(),
                    syntaxFactory.IdentifierName(nameOfEvent))
            }
            : null;

            var invokeMethod = ((INamedTypeSymbol)eventType).DelegateInvokeMethod;
            var newMethod    = CodeGenerationSymbolFactory.CreateMethodSymbol(
                attributes: null,
                accessibility: Accessibility.Protected,
                modifiers: new DeclarationModifiers(),
                returnType: targetDocument.Project.GetCompilationAsync(cancellationToken).WaitAndGetResult(cancellationToken).GetSpecialType(SpecialType.System_Void),
                explicitInterfaceSymbol: null,
                name: eventHandlerName,
                typeParameters: null,
                parameters: invokeMethod.Parameters.ToArray(),
                statements: null,
                handlesExpressions: handlesExpressions);

            var annotation = new SyntaxAnnotation();

            newMethod = annotation.AddAnnotationToSymbol(newMethod);
            var codeModel   = targetDocument.Project.LanguageServices.GetService <ICodeModelNavigationPointService>();
            var syntaxFacts = targetDocument.Project.LanguageServices.GetService <ISyntaxFactsService>();

            var targetSyntaxTree = targetDocument.GetSyntaxTreeAsync(cancellationToken).WaitAndGetResult(cancellationToken);

            var position        = type.Locations.First(loc => loc.SourceTree == targetSyntaxTree).SourceSpan.Start;
            var destinationType = syntaxFacts.GetContainingTypeDeclaration(targetSyntaxTree.GetRoot(cancellationToken), position);
            var insertionPoint  = codeModel.GetEndPoint(destinationType, EnvDTE.vsCMPart.vsCMPartBody);

            if (insertionPoint == null)
            {
                throw new InvalidOperationException(ServicesVSResources.MemberInsertionFailed);
            }

            var newType = codeGenerationService.AddMethod(destinationType, newMethod, new CodeGenerationOptions(autoInsertionLocation: false), cancellationToken);
            var newRoot = targetSyntaxTree.GetRoot(cancellationToken).ReplaceNode(destinationType, newType);

            newRoot = Simplifier.ReduceAsync(targetDocument.WithSyntaxRoot(newRoot), Simplifier.Annotation, null, cancellationToken).WaitAndGetResult(cancellationToken).GetSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken);

            var formattingRules = additionalFormattingRule.Concat(Formatter.GetDefaultFormattingRules(targetDocument));

            var workspace = targetDocument.Project.Solution.Workspace;

            newRoot = Formatter.Format(newRoot, Formatter.Annotation, workspace, workspace.Options, formattingRules, cancellationToken);

            var newMember     = newRoot.GetAnnotatedNodesAndTokens(annotation).Single();
            var newMemberText = newMember.ToFullString();

            // In VB, the final newline is likely a statement terminator in the parent - just add
            // one on so that things don't get messed.
            if (!newMemberText.EndsWith(Environment.NewLine, StringComparison.Ordinal))
            {
                newMemberText += Environment.NewLine;
            }

            return(Tuple.Create(ConstructMemberId(newMethod), newMemberText, insertionPoint.Value.ToVsTextSpan()));
        }