示例#1
0
		public static SyntaxTree GetSyntaxTreeSynchronously(Document document, CancellationToken cancellationToken) {
			//TODO: Roslyn 2.0: use document.GetSyntaxTreeSynchronously()
			SyntaxTree syntaxTree;
			if (document.TryGetSyntaxTree(out syntaxTree))
				return syntaxTree;
			return document.GetSyntaxTreeAsync(cancellationToken).GetAwaiter().GetResult();
		}
示例#2
0
        public static async Task<IEnumerable<LinePositionSpanTextChange>> GetFormattingChangesAfterKeystroke(Workspace workspace, OptionSet options, Document document, int position, char character)
        {
            var tree = await document.GetSyntaxTreeAsync();

            if (character == '\n')
            {
                // format previous line on new line
                var lines = (await document.GetTextAsync()).Lines;
                var targetLine = lines[lines.GetLineFromPosition(position).LineNumber - 1];
                if (!string.IsNullOrWhiteSpace(targetLine.Text.ToString(targetLine.Span)))
                {
                    return await GetFormattingChangesForRange(workspace, options, document, targetLine.Start, targetLine.End);
                }
            }
            else if (character == '}' || character == ';')
            {
                // format after ; and }
                var node = FindFormatTarget(tree, position);
                if (node != null)
                {
                    return await GetFormattingChangesForRange(workspace, options, document, node.FullSpan.Start, node.FullSpan.End);
                }
            }

            return Enumerable.Empty<LinePositionSpanTextChange>();
        }
        public async Task<QuickInfoItem> GetItemAsync(
            Document document,
            int position,
            CancellationToken cancellationToken)
        {
            var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
            var token = await tree.GetTouchingTokenAsync(position, cancellationToken, findInsideTrivia: true).ConfigureAwait(false);

            var state = await GetQuickInfoItemAsync(document, token, position, cancellationToken).ConfigureAwait(false);
            if (state != null)
            {
                return state;
            }

            if (ShouldCheckPreviousToken(token))
            {
                var previousToken = token.GetPreviousToken();

                if ((state = await GetQuickInfoItemAsync(document, previousToken, position, cancellationToken).ConfigureAwait(false)) != null)
                {
                    return state;
                }
            }

            return null;
        }
示例#4
0
    private static Document RemoveUnnecessaryUsings(Document doc, Compilation compilation)
    {
      #region CodeContracts
      Contract.Requires(doc != null);
      Contract.Requires(compilation != null);
      Contract.Ensures(Contract.Result<Document>() != null);
      #endregion CodeContracts

      var st = doc.GetSyntaxTreeAsync().Result;
      var sm = doc.GetSemanticModelAsync().Result;
      //var assembly = Assembly.LoadFrom(@"C:\cci\Microsoft.Research\Imported\Tools\Roslyn\v4.5.1\Microsoft.CodeAnalysis.CSharp.Features.dll");
      //var assembly = Assembly.LoadFrom(@"C:\cci\Microsoft.Research\CCTools\ReviewBot\bin\Debug\Microsoft.CodeAnalysis.CSharp.Features.dll");
      //var assembly = Assembly.LoadFrom(@"..\..\..\packages\Microsoft.CodeAnalysis.Features.0.7.4040207-beta\lib\net45\Microsoft.CodeAnalysis.CSharp.Features.dll");
      //var assembly = Assembly.LoadFrom(@"C:\Users\t-scottc\Desktop\Signed_20140201.1\Microsoft.CodeAnalysis.CSharp.Features.dll");
      //var assembly = Assembly.LoadFrom(@"C:\Users\t-scottc\workspace\roslyn\Binaries\Debug\Microsoft.CodeAnalysis.CSharp.Workspaces.dll");
      Assembly assembly;

      if (TryGetMicrosoftCodeAnalysisCSharpFeatures(out assembly))
      {
        var type = assembly.GetType("Microsoft.CodeAnalysis.CSharp.RemoveUnnecessaryImports.CSharpRemoveUnnecessaryImportsService");
        var method = type.GetMethod("RemoveUnnecessaryImports");
        var service = Activator.CreateInstance(type);
        return method.Invoke(service, new object[] { doc, sm, st.GetRoot(), CancellationToken.None }) as Document;
      }
      else
      {
        Output.WriteWarning("Can't run the refactoring to remove using");

        return doc;
      }
    }
		public async Task<ParameterHintingResult> InternalGetParameterDataProviderAsync (Document document, SemanticModel semanticModel, int position, CancellationToken cancellationToken, int recCount)
		{
			if (position == 0 || recCount > 1)
				return ParameterHintingResult.Empty;
			var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
			var tokenLeftOfPosition = tree.FindTokenOnLeftOfPosition (position, cancellationToken);
			if (tokenLeftOfPosition.IsKind (SyntaxKind.LessThanToken)) {
				var startToken = tokenLeftOfPosition.GetPreviousToken();
				return HandleTypeParameterCase(semanticModel, startToken.Parent, cancellationToken);
			}
		
			var context = SyntaxContext.Create(workspace, document, semanticModel, position, cancellationToken);
			var targetParent = context.TargetToken.Parent;
			if (targetParent == null)
				return ParameterHintingResult.Empty;
			
			if (context.TargetToken.IsKind (SyntaxKind.IdentifierName)) {
				targetParent = targetParent.Parent;
			}
			
			if (context.TargetToken.IsKind (SyntaxKind.CloseParenToken) || context.TargetToken.IsKind (SyntaxKind.CloseBracketToken) || context.TargetToken.IsKind (SyntaxKind.GreaterThanToken))
				targetParent = targetParent.Parent;
			var node = targetParent.Parent;

			// case: identifier<arg1,|
			if (node == null) {
				if (context.LeftToken.Kind() == SyntaxKind.CommaToken) {
					targetParent = context.LeftToken.GetPreviousToken().Parent;
					node = targetParent.Parent;
					if (node.Kind() == SyntaxKind.LessThanExpression) {
						return HandleTypeParameterCase(semanticModel, ((BinaryExpressionSyntax)node).Left, cancellationToken);

					}
				}
				return ParameterHintingResult.Empty;
			}
			if (node.IsKind (SyntaxKind.Argument)) {
				node = node.Parent.Parent;
			} else {
				if (!(targetParent is BaseArgumentListSyntax) && !(targetParent is AttributeArgumentListSyntax) && !(targetParent is InitializerExpressionSyntax)) {
					if (position == targetParent.Span.Start)
						return ParameterHintingResult.Empty;
					return await InternalGetParameterDataProviderAsync (document, semanticModel, targetParent.Span.Start, cancellationToken, recCount + 1).ConfigureAwait (false);
				}
			}
			switch (node.Kind()) {
				case SyntaxKind.Attribute:
					return HandleAttribute(semanticModel, node, cancellationToken);					
				case SyntaxKind.ThisConstructorInitializer:
				case SyntaxKind.BaseConstructorInitializer:
					return HandleConstructorInitializer(semanticModel, node, cancellationToken);
				case SyntaxKind.ObjectCreationExpression:
					return HandleObjectCreationExpression(semanticModel, node, cancellationToken);
				case SyntaxKind.InvocationExpression:
					return HandleInvocationExpression(semanticModel, (InvocationExpressionSyntax)node, cancellationToken);
				case SyntaxKind.ElementAccessExpression:
					return HandleElementAccessExpression(semanticModel, (ElementAccessExpressionSyntax)node, cancellationToken);
			}
			return ParameterHintingResult.Empty;
		}
        static async Task <int> GetAdjustedContextPointAsync(int contextPoint, Document document, CancellationToken cancellationToken)
        {
            var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            // Determine the position in the buffer at which to end the tracking span representing
            // the part of the imaginary buffer before the text in the view.
            var token = tree.FindTokenOnLeftOfPosition(contextPoint, cancellationToken);

            // Special case to handle class designer because it asks for debugger IntelliSense using
            // spans between members.
            if (contextPoint > token.Span.End &&
                token.IsKindOrHasMatchingText(SyntaxKind.CloseBraceToken) &&
                token.Parent.IsKind(SyntaxKind.Block) &&
                token.Parent.Parent is MemberDeclarationSyntax)
            {
                return(contextPoint);
            }

            if (token.IsKindOrHasMatchingText(SyntaxKind.CloseBraceToken) &&
                token.Parent.IsKind(SyntaxKind.Block))
            {
                return(token.SpanStart);
            }

            return(token.FullSpan.End);
        }
            public async Task AnalyzeSyntaxAsync(Document document, CancellationToken cancellationToken)
            {
                if (!document.SupportsSyntaxTree)
                {
                    return;
                }

                // getting tree is cheap since tree always stays in memory
                var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
                var length = tree.Length;

                while (true)
                {
                    if (_map.TryAdd(document.Id, length))
                    {
                        Interlocked.Add(ref _size, length);
                        return;
                    }

                    long size;
                    if (_map.TryGetValue(document.Id, out size))
                    {
                        if (size == length)
                        {
                            return;
                        }

                        if (_map.TryUpdate(document.Id, length, size))
                        {
                            Interlocked.Add(ref _size, length - size);
                            return;
                        }
                    }
                }
            }
        protected override int GetAdjustedContextPoint(int contextPoint, Document document)
        {
            // Determine the position in the buffer at which to end the tracking span representing
            // the part of the imagininary buffer before the text in the view. 
            var tree = document.GetSyntaxTreeAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None);
            var token = tree.FindTokenOnLeftOfPosition(contextPoint, CancellationToken.None);

            // Special case to handle class designer because it asks for debugger IntelliSense using
            // spans between members.
            if (contextPoint > token.Span.End &&
                token.IsKindOrHasMatchingText(SyntaxKind.CloseBraceToken) &&
                token.Parent.IsKind(SyntaxKind.Block) &&
                token.Parent.Parent is MemberDeclarationSyntax)
            {
                return contextPoint;
            }

            if (token.IsKindOrHasMatchingText(SyntaxKind.CloseBraceToken) &&
                token.Parent.IsKind(SyntaxKind.Block))
            {
                return token.SpanStart;
            }

            return token.FullSpan.End;
        }
        async Task<Solution> MoveClassIntoNewFileAsync(Document document, ClassStatementSyntax typeDecl, string className, CancellationToken cancellationToken)
        {
            // symbol representing the type
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
            var typeSymbol = semanticModel.GetDeclaredSymbol(typeDecl, cancellationToken);

            // remove type from current files
            var currentSyntaxTree = await document.GetSyntaxTreeAsync();
            var currentRoot = await currentSyntaxTree.GetRootAsync();


            //In VB you have to remove th parent of det declaration node. That is the "ClassBlockSyntax"
            var replacedRoot = currentRoot.RemoveNode(typeDecl.Parent, SyntaxRemoveOptions.KeepNoTrivia);
            document = document.WithSyntaxRoot(replacedRoot);


            // create new tree for a new file
            // we drag all the imports because we don't know which are needed
            // and there is no easy way to find out which
            var currentUsings = currentRoot.DescendantNodesAndSelf().Where(s => s is ImportsStatementSyntax);

            var currentNs = (NamespaceStatementSyntax)currentRoot.DescendantNodesAndSelf().First(s => s is NamespaceStatementSyntax);

            SyntaxList<StatementSyntax> c;


            if(currentNs != null)
            {
                //We have to wrap the content of the class in the namespace. 
                var temp = SyntaxFactory.SingletonList(
                SyntaxFactory.NamespaceBlock(
                     SyntaxFactory.NamespaceStatement(SyntaxFactory.ParseName(currentNs.Name.ToString())),
                        SyntaxFactory.SingletonList(typeDecl.Parent),
                        SyntaxFactory.EndNamespaceStatement()
                     ));
                c = SyntaxFactory.List(temp.Select(i => ((StatementSyntax)i)));
            }
            else
            {
                c = SyntaxFactory.SingletonList(typeDecl.Parent);
            }
                

            var newFileTree = SyntaxFactory.CompilationUnit()
                .WithImports(SyntaxFactory.List(currentUsings.Select(i => ((ImportsStatementSyntax)i))))
                .WithMembers(c)
                .WithoutLeadingTrivia()
                .NormalizeWhitespace();

            var codeText = newFileTree.ToFullString();

            //TODO: handle name conflicts
            var newDocument = document.Project.AddDocument(className, SourceText.From(codeText), document.Folders);
            
            newDocument = await RemoveUnusedImportDirectivesAsync(newDocument, cancellationToken);

            return newDocument.Project.Solution;

        }
        //--- Class Methods ---
        private static async Task<Document> AddMissingEnumFields(Document document, SyntaxToken typeDecl, CancellationToken cancellationToken) {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
            var node = (SwitchStatementSyntax)typeDecl.Parent;
            IdentifierNameSyntax switchVariable;
            var missingMembers = EnumSwitchAnalysis.GetMissingEnumMembers(node, semanticModel, out switchVariable);
            if(missingMembers.Any()) {

                // get existing switchSections
                var existingSections = node.Sections.ToList();
                SwitchSectionSyntax defaultSection = null;
                if(existingSections.Any() && existingSections.Last().DescendantNodes().OfType<DefaultSwitchLabelSyntax>().Any()) {
                    defaultSection = existingSections.Last();
                    existingSections = existingSections.Take(existingSections.Count - 1).ToList();
                }

                // generate missing case statements
                var switchVariableTypeInfo = semanticModel.GetTypeInfo(switchVariable);
                var newCaseStatements = missingMembers.Select(missingMember =>
                    SyntaxFactory.CaseSwitchLabel(
                        SyntaxFactory.Token(SyntaxKind.CaseKeyword),
                        SyntaxFactory.MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            SyntaxFactory.IdentifierName(switchVariableTypeInfo.Type.Name),
                            SyntaxFactory.IdentifierName(missingMember.Name)
                        ),
                        SyntaxFactory.Token(SyntaxKind.ColonToken)
                    )
                ).Select(caseSection => SyntaxFactory.SwitchSection(
                    SyntaxFactory.List<SwitchLabelSyntax>(new[] { caseSection }),
                    SyntaxFactory.List<StatementSyntax>().Add(
                        SyntaxFactory.ThrowStatement(
                            SyntaxFactory.ObjectCreationExpression(
                                SyntaxFactory.ParseTypeName(nameof(NotImplementedException)),
                                SyntaxFactory.ArgumentList(),
                                null
                            )
                        )
                    )
                )).ToImmutableArray();

                // insert case statements after the last one
                var tree = await document.GetSyntaxTreeAsync(cancellationToken);
                var root = (CompilationUnitSyntax)tree.GetRoot(cancellationToken);
                var switchStatement = SyntaxFactory.SwitchStatement(
                    SyntaxFactory.IdentifierName(switchVariable.Identifier)
                        .WithLeadingTrivia(switchVariable.GetLeadingTrivia())
                        .WithTrailingTrivia(switchVariable.GetTrailingTrivia())
                ).WithSections(
                    new SyntaxList<SwitchSectionSyntax>()
                        .AddRange(existingSections)
                        .AddRange(newCaseStatements)
                        .AddRange(defaultSection == null ? Enumerable.Empty<SwitchSectionSyntax>() : new [] { defaultSection })
                ).WithLeadingTrivia(node.GetLeadingTrivia())
                 .WithTrailingTrivia(node.GetTrailingTrivia());
                root = root.ReplaceNode(node, switchStatement);
                return document.WithSyntaxRoot(root);
            }
            return document;
        }
示例#11
0
 /// <summary>
 /// The entry point to Gistify's engine. Takes the document and the extent of the selection,
 /// and outputs the augmented snippet.
 /// </summary>
 /// <param name="document"></param>
 /// <param name="startPosition"></param>
 /// <param name="endPosition"></param>
 /// <returns>String with the augmented snippet.</returns>
 public static string AugmentSelection(Document document, int startPosition, int endPosition)
 {
     var tree = document.GetSyntaxTreeAsync().Result;
     var model = document.GetSemanticModelAsync().Result;
     var objectInfos = DiscoveryWalker.FindObjects(tree, model, startPosition, endPosition);
     var augmentedSelection = SyntaxBuilder.AugmentSnippet(objectInfos, tree, startPosition, endPosition);
     return augmentedSelection;
 }
        protected override async Task<bool> IsExclusiveAsync(Document document, int caretPosition, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
            var token = syntaxTree.FindTokenOnLeftOfPosition(caretPosition, cancellationToken)
                                  .GetPreviousTokenIfTouchingWord(caretPosition);

            return IsAfterNameColonArgument(token) || IsAfterNameEqualsArgument(token);
        }
 public async Task<IList<string>> GetProximityExpressionsAsync(
     Document document,
     int position,
     CancellationToken cancellationToken)
 {
     var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
     return Do(tree, position, cancellationToken);
 }
        public override async Task<string> GetHelpTermAsync(Document document, TextSpan span, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var syntaxFacts = document.GetLanguageService<ISyntaxFactsService>();

            // For now, find the token under the start of the selection.
            var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
            var token = syntaxTree.GetTouchingToken(span.Start, cancellationToken, findInsideTrivia: true);

            if (IsValid(token, span))
            {
                var semanticModel = await document.GetSemanticModelForSpanAsync(span, cancellationToken).ConfigureAwait(false);

                var result = TryGetText(token, semanticModel, document, cancellationToken, syntaxFacts);
                if (string.IsNullOrEmpty(result))
                {
                    var previousToken = token.GetPreviousToken();
                    if (IsValid(previousToken, span))
                    {
                        result = TryGetText(previousToken, semanticModel, document, cancellationToken, syntaxFacts);
                    }
                }

                return result;
            }

            var trivia = root.FindTrivia(span.Start, findInsideTrivia: true);
            if (trivia.Span.IntersectsWith(span) && trivia.Kind() == SyntaxKind.PreprocessingMessageTrivia &&
                trivia.Token.GetAncestor<RegionDirectiveTriviaSyntax>() != null)
            {
                return "#region";
            }

            if (trivia.IsRegularOrDocComment())
            {
                // just find the first "word" that intersects with our position
                var text = await syntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false);
                int start = span.Start;
                int end = span.Start;

                while (start > 0 && syntaxFacts.IsIdentifierPartCharacter(text[start - 1]))
                {
                    start--;
                }

                while (end < text.Length - 1 && syntaxFacts.IsIdentifierPartCharacter(text[end]))
                {
                    end++;
                }

                return text.GetSubText(TextSpan.FromBounds(start, end)).ToString();
            }

            return string.Empty;
        }
        private async Task<Document> ExplodePropertyAsync(SyntaxNode oldRoot, Document document, PropertyDeclarationSyntax property, CancellationToken cancellationToken)
        {
            var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            // Call the Property Exploder. The code refactoring happens here.
            var expander = new PropertyExploder(property.Parent, property);
            var newRoot = expander.Visit(oldRoot);

            // Update code with the refactored Root
            return document.WithSyntaxRoot(newRoot);
        }
示例#16
0
        internal static async Task<DebugLocationInfo> GetInfoAsync(Document document, int position, CancellationToken cancellationToken)
        {
            // PERF:  This method will be called synchronously on the UI thread for every breakpoint in the solution.
            // Therefore, it is important that we make this call as cheap as possible.  Rather than constructing a
            // containing Symbol and using ToDisplayString (which might be more *correct*), we'll just do the best we
            // can with Syntax.  This approach is capable of providing parity with the pre-Roslyn implementation.
            var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
            var root = await tree.GetRootAsync(cancellationToken).ConfigureAwait(false);
            var syntaxFactsService = document.Project.LanguageServices.GetService<ISyntaxFactsService>();
            var memberDeclaration = syntaxFactsService.GetContainingMemberDeclaration(root, position, useFullSpan: true);

            // It might be reasonable to return an empty Name and a LineOffset from the beginning of the
            // file for GlobalStatements.  However, the only known caller (Breakpoints Window) doesn't
            // appear to consume this information, so we'll just return the simplest thing (no location).
            if ((memberDeclaration == null) || (memberDeclaration.Kind() == SyntaxKind.GlobalStatement))
            {
                return default(DebugLocationInfo);
            }

            // field or event field declarations may contain multiple variable declarators. Try finding the correct one.
            // If the position does not point to one, try using the first one.
            VariableDeclaratorSyntax fieldDeclarator = null;
            if (memberDeclaration.Kind() == SyntaxKind.FieldDeclaration || memberDeclaration.Kind() == SyntaxKind.EventFieldDeclaration)
            {
                SeparatedSyntaxList<VariableDeclaratorSyntax> variableDeclarators = ((BaseFieldDeclarationSyntax)memberDeclaration).Declaration.Variables;

                foreach (var declarator in variableDeclarators)
                {
                    if (declarator.FullSpan.Contains(position))
                    {
                        fieldDeclarator = declarator;
                        break;
                    }
                }

                if (fieldDeclarator == null)
                {
                    fieldDeclarator = variableDeclarators.Count > 0 ? variableDeclarators[0] : null;
                }
            }

            var name = syntaxFactsService.GetDisplayName(fieldDeclarator ?? memberDeclaration,
                DisplayNameOptions.IncludeNamespaces |
                DisplayNameOptions.IncludeParameters);

            var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
            var lineNumber = text.Lines.GetLineFromPosition(position).LineNumber;
            var accessor = memberDeclaration.GetAncestorOrThis<AccessorDeclarationSyntax>();
            var memberLine = text.Lines.GetLineFromPosition(accessor?.SpanStart ?? memberDeclaration.SpanStart).LineNumber;
            var lineOffset = lineNumber - memberLine;

            return new DebugLocationInfo(name, lineOffset);
        }
        private async Task<Document> ReplaceEmptyStringWithStringEmpty(Document document, SyntaxNode oldNode, CancellationToken cancellationToken)
        {
            // NOTE: string.Empty
            var stringType = SF.PredefinedType(SF.Token(SyntaxKind.StringKeyword));
            var empty = SF.IdentifierName("Empty");
            var stringEmpty = SF.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, stringType, SF.Token(SyntaxKind.DotToken), empty);

            var tree = await document.GetSyntaxTreeAsync();
            var node = tree.GetRoot().ReplaceNode(oldNode, stringEmpty);

            return document.WithSyntaxRoot(node);
        }
示例#18
0
        public static async Task<IEnumerable<SyntaxNode>> GetContainedSyntaxNodesAsync(Document document, CancellationToken cancellationToken)
        {
            var progressionLanguageService = document.Project.LanguageServices.GetService<IProgressionLanguageService>();
            if (progressionLanguageService == null)
            {
                return SpecializedCollections.EmptyEnumerable<SyntaxNode>();
            }

            var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
            var root = await syntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
            return progressionLanguageService.GetTopLevelNodesFromDocument(root, cancellationToken);
        }
        public Document Annotate(Document document)
        {
            if (document == null) throw new ArgumentNullException("document");

            _model = (SemanticModel)document.GetSemanticModelAsync().Result;

            var originalTree = (SyntaxTree)document.GetSyntaxTreeAsync().Result;

            var annotatedTree = Visit(originalTree.GetRoot());

            return document.WithSyntaxRoot(annotatedTree);
        }
示例#20
0
        public static List<Tuple<SyntaxToken, ISymbol>> Build(Document document, TextSpan span)
        {
            var tree = (SyntaxTree)document.GetSyntaxTreeAsync(CancellationToken.None).Result;
            if (tree == null)
            {
                return null;
            }

            var builder = new TokenSymbolPairBuilder(document, span);
            builder.Visit(tree.GetRoot());

            return builder.tokenSymbolPair;
        }
        protected override async Task<IEnumerable<CompletionItem>> GetItemsWorkerAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken)
        {
            var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            // first try to get the #r string literal token.  If we couldn't, then we're not in a #r
            // reference directive and we immediately bail.
            SyntaxToken stringLiteral;
            if (!TryGetStringLiteralToken(tree, position, out stringLiteral, cancellationToken))
            {
                return null;
            }

            var documentPath = document.Project.IsSubmission ? null : document.FilePath;
            var textChangeSpan = this.GetTextChangeSpan(stringLiteral, position);

            var gacHelper = new GlobalAssemblyCacheCompletionHelper(this, textChangeSpan, itemRules: ItemRules.Instance);
            var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
            var snapshot = text.FindCorrespondingEditorTextSnapshot();
            if (snapshot == null)
            {
                // Passing null to GetFileSystemDiscoveryService raises an exception.
                // Instead, return here since there is no longer snapshot for this document.
                return null;
            }

            var assemblyReferenceResolver = document.Project.CompilationOptions.MetadataReferenceResolver as AssemblyReferenceResolver;
            if (assemblyReferenceResolver == null)
            {
                return null;
            }

            var metadataFileResolver = assemblyReferenceResolver.PathResolver as MetadataFileReferenceResolver;
            if (metadataFileResolver == null)
            {
                return null;
            }

            var fileSystemHelper = new FileSystemCompletionHelper(
                this, textChangeSpan,
                GetFileSystemDiscoveryService(snapshot),
                Glyph.OpenFolder,
                Glyph.Assembly,
                searchPaths: metadataFileResolver.SearchPaths,
                allowableExtensions: new[] { ".dll", ".exe" },
                exclude: path => path.Contains(","),
                itemRules: ItemRules.Instance);

            var pathThroughLastSlash = this.GetPathThroughLastSlash(stringLiteral, position);
            return gacHelper.GetItems(pathThroughLastSlash, documentPath).Concat(
                fileSystemHelper.GetItems(pathThroughLastSlash, documentPath));
        }
        protected override async Task<CompletionItem> GetBuilderAsync(Document document, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (triggerInfo.TriggerReason == CompletionTriggerReason.TypeCharCommand)
            {
                var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

                if (triggerInfo.IsDebugger)
                {
                    // Aggressive Intellisense in the debugger: always show the builder 
                    return CreateEmptyBuilder(text, position);
                }

                var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
                var token = tree
                    .FindTokenOnLeftOfPosition(position, cancellationToken)
                    .GetPreviousTokenIfTouchingWord(position);

                if (token.Kind() == SyntaxKind.None)
                {
                    return null;
                }

                var semanticModel = await document.GetSemanticModelForNodeAsync(token.Parent, cancellationToken).ConfigureAwait(false);
                var typeInferrer = document.GetLanguageService<ITypeInferenceService>();

                if (IsLambdaExpression(semanticModel, position, token, typeInferrer, cancellationToken))
                {
                    return CreateBuilder(text, position, CSharpFeaturesResources.LambdaExpression, CSharpFeaturesResources.AutoselectDisabledDueToPotentialLambdaDeclaration);
                }
                else if (IsAnonymousObjectCreation(token))
                {
                    return CreateBuilder(text, position, CSharpFeaturesResources.MemberName, CSharpFeaturesResources.AutoselectDisabledDueToPossibleExplicitlyNamesAnonTypeMemCreation);
                }
                else if (token.IsPreProcessorExpressionContext())
                {
                    return CreateEmptyBuilder(text, position);
                }
                else if (IsImplicitArrayCreation(semanticModel, token, position, typeInferrer, cancellationToken))
                {
                    return CreateBuilder(text, position, CSharpFeaturesResources.ImplicitArrayCreation, CSharpFeaturesResources.AutoselectDisabledDueToPotentialImplicitArray);
                }
                else if (token.IsKindOrHasMatchingText(SyntaxKind.FromKeyword) || token.IsKindOrHasMatchingText(SyntaxKind.JoinKeyword))
                {
                    return CreateBuilder(text, position, CSharpFeaturesResources.RangeVariable, CSharpFeaturesResources.AutoselectDisabledDueToPotentialRangeVariableDecl);
                }
            }

            return null;
        }
        private ImmutableArray<CodeAction> GetCodeFixes(Document document, TextSpan span, DiagnosticDescriptor descriptor)
        {
            var builder = ImmutableArray.CreateBuilder<CodeAction>();
            Action<CodeAction, ImmutableArray<Diagnostic>> registerCodeFix =
                (a, _) => builder.Add(a);

            var tree = document.GetSyntaxTreeAsync(CancellationToken.None).Result;
            var diagnostic = Diagnostic.Create(descriptor, Location.Create(tree, span));
            var context = new CodeFixContext(document, diagnostic, registerCodeFix, CancellationToken.None);

            var provider = CreateProvider();
            provider.RegisterCodeFixesAsync(context).Wait();

            return builder.ToImmutable();
        }
        internal static async Task<BreakpointResolutionResult> GetBreakpointAsync(Document document, int position, CancellationToken cancellationToken)
        {
            var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
            if (!BreakpointSpans.TryGetBreakpointSpan(tree, position, cancellationToken, out var span))
            {
                return null;
            }

            if (span.Length == 0)
            {
                return BreakpointResolutionResult.CreateLineResult(document);
            }

            return BreakpointResolutionResult.CreateSpanResult(document, span);
        }
        private async Task<Document> CrunchPropertyAsync(SyntaxNode oldRoot, Document document, PropertyDeclarationSyntax property, CancellationToken cancellationToken)
        {
            var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            // Get the property's backing field.
            var backingField = property.GetBackingField(semanticModel);

            // Call the Property Cruncher. The code refactoring happens here.
            var collapser = new PropertyCruncher(semanticModel, backingField, property);
            var newRoot = collapser.Visit(oldRoot);

            // Update code with the refactored Root
            return document.WithSyntaxRoot(newRoot);
        }
            public async Task AnalyzeSyntaxAsync(Document document, CancellationToken cancellationToken)
            {
                // if closed file diagnostic is off and document is not opened, then don't do anything
                if (!_workspace.Options.GetOption(ServiceFeatureOnOffOptions.ClosedFileDiagnostic, document.Project.Language) && !document.IsOpen())
                {
                    return;
                }

                var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
                var diagnostics = tree.GetDiagnostics(cancellationToken);

                Contract.Requires(document.Project.Solution.Workspace == _workspace);

                var diagnosticData = diagnostics == null ? ImmutableArray<DiagnosticData>.Empty : diagnostics.Select(d => DiagnosticData.Create(document, d)).ToImmutableArrayOrEmpty();
                _service.RaiseDiagnosticsUpdated(new DiagnosticsUpdatedArgs(ValueTuple.Create(this, document.Id), _workspace, document.Project.Solution, document.Project.Id, document.Id, diagnosticData));
            }
        public static string CreateUniqueEventName(
            Document document, string className, string objectName, string nameOfEvent, CancellationToken cancellationToken)
        {
            var type = document.Project.GetCompilationAsync(cancellationToken).WaitAndGetResult(cancellationToken).GetTypeByMetadataName(className);
            var name = objectName + "_" + nameOfEvent;

            var semanticModel = document.GetSemanticModelAsync(cancellationToken).WaitAndGetResult(cancellationToken);

            var tree = document.GetSyntaxTreeAsync(cancellationToken).WaitAndGetResult(cancellationToken);
            var typeNode = type.DeclaringSyntaxReferences.Where(r => r.SyntaxTree == tree).Select(r => r.GetSyntax(cancellationToken)).First();
            var codeModel = document.Project.LanguageServices.GetService<ICodeModelNavigationPointService>();
            var point = codeModel.GetStartPoint(typeNode, EnvDTE.vsCMPart.vsCMPartBody);
            var reservedNames = semanticModel.LookupSymbols(point.Value.Position, type).Select(m => m.Name);

            return NameGenerator.EnsureUniqueness(name, reservedNames, document.Project.LanguageServices.GetService<ISyntaxFactsService>().IsCaseSensitive);
        }
        protected override async Task<CompletionItem> GetSuggestionModeItemAsync(Document document, int position, TextSpan itemSpan, CompletionTrigger trigger, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (trigger.Kind == CompletionTriggerKind.Insertion)
            {
                var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

                var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
                var token = tree
                    .FindTokenOnLeftOfPosition(position, cancellationToken)
                    .GetPreviousTokenIfTouchingWord(position);

                if (token.Kind() == SyntaxKind.None)
                {
                    return null;
                }

                var semanticModel = await document.GetSemanticModelForNodeAsync(token.Parent, cancellationToken).ConfigureAwait(false);
                var typeInferrer = document.GetLanguageService<ITypeInferenceService>();

                if (IsLambdaExpression(semanticModel, position, token, typeInferrer, cancellationToken))
                {
                    return CreateSuggestionModeItem(CSharpFeaturesResources.LambdaExpression, itemSpan, CSharpFeaturesResources.AutoselectDisabledDueToPotentialLambdaDeclaration);
                }
                else if (IsAnonymousObjectCreation(token) || IsPossibleTupleExpression(token))
                {
                    return CreateSuggestionModeItem(CSharpFeaturesResources.MemberName, itemSpan, CSharpFeaturesResources.AutoselectDisabledDueToPossibleExplicitlyNamesAnonTypeMemCreation);
                }
                else if (token.IsPreProcessorExpressionContext())
                {
                    return CreateEmptySuggestionModeItem(itemSpan);
                }
                else if (IsImplicitArrayCreation(semanticModel, token, position, typeInferrer, cancellationToken))
                {
                    return CreateSuggestionModeItem(CSharpFeaturesResources.ImplicitArrayCreation, itemSpan, CSharpFeaturesResources.AutoselectDisabledDueToPotentialImplicitArray);
                }
                else if (token.IsKindOrHasMatchingText(SyntaxKind.FromKeyword) || token.IsKindOrHasMatchingText(SyntaxKind.JoinKeyword))
                {
                    return CreateSuggestionModeItem(CSharpFeaturesResources.RangeVariable, itemSpan, CSharpFeaturesResources.AutoselectDisabledDueToPotentialRangeVariableDecl);
                }
                else if (tree.IsNamespaceDeclarationNameContext(position, cancellationToken))
                {
                    return CreateSuggestionModeItem(CSharpFeaturesResources.NamespaceName, itemSpan, CSharpFeaturesResources.AutoselectDisabledDueToNamespaceDeclaration);
                }
            }

            return null;
        }
        protected override int GetContainingClassName(Document document, SnapshotSpan fieldSpan, CancellationToken cancellationToken, ref string value, ref int hasDefaultValue)
        {
            // Find the nearest encolsing type declaration and use its name
            var syntaxTree = document.GetSyntaxTreeAsync(cancellationToken).WaitAndGetResult(cancellationToken);
            var type = syntaxTree.FindTokenOnLeftOfPosition(fieldSpan.Start.Position, cancellationToken).GetAncestor<TypeDeclarationSyntax>();

            if (type != null)
            {
                value = type.Identifier.ToString();

                if (!string.IsNullOrWhiteSpace(value))
                {
                    hasDefaultValue = 1;
                }
            }

            return VSConstants.S_OK;
        }
        private async Task<Solution> MoveSymbolToFile(Document document, CompilationUnitSyntax syntaxRoot, TypeDeclarationSyntax typeDecl)
        {
            var identifierToken = typeDecl.Identifier;
            var originalSolution = document.Project.Solution;

            // Get the typeDecl's namespace
            var semanticModel = await document.GetSemanticModelAsync();
            var symbol = semanticModel.GetDeclaredSymbol(typeDecl);

            // Build new file
            var newFileTree = SyntaxFactory.CompilationUnit()
                .WithUsings(SyntaxFactory.List(syntaxRoot.Usings))
                .WithMembers(
                            SyntaxFactory.SingletonList<MemberDeclarationSyntax>(
                                SyntaxFactory.NamespaceDeclaration(SyntaxFactory.IdentifierName(symbol.ContainingNamespace.Name))
                .WithMembers(SyntaxFactory.SingletonList<MemberDeclarationSyntax>(typeDecl))))
                .WithoutLeadingTrivia()
                .NormalizeWhitespace();

            var newDocumentId = DocumentId.CreateNewId(document.Project.Id);
            var newSolution = originalSolution.AddDocument(newDocumentId, identifierToken.Text, newFileTree, document.Folders);

            // Remove declaration from source file
            var syntaxTree = await document.GetSyntaxTreeAsync();
            var modifiedSyntaxTree = syntaxTree.GetRoot().RemoveNode(typeDecl, SyntaxRemoveOptions.KeepNoTrivia);

            // If the original file now has no types, remove it completely.
            var remainingTypesInDocument = modifiedSyntaxTree.DescendantNodesAndSelf()?
                                                             .Where(x => x.GetType() == typeof(EnumDeclarationSyntax) ||
                                                                         x.GetType() == typeof(TypeDeclarationSyntax)).ToList();
            if(remainingTypesInDocument == null || !remainingTypesInDocument.Any())
            {
                // Remove this file completely
                newSolution = newSolution.RemoveDocument(document.Id);
            } else
            {
                // Include the modified document
                newSolution = newSolution.WithDocumentSyntaxRoot(document.Id, modifiedSyntaxTree);
            }

            // TOODO: Remove unused usings from both source and new.
            
            return newSolution;
        }
示例#31
0
        static Document ProcessCode(Document doc)
        {
            SyntaxTree tree = doc.GetSyntaxTreeAsync().Result;
            CompilationUnitSyntax root = (CompilationUnitSyntax) tree.GetRoot();

            root = RemoveRegions(root);
            root = AddRequiredUsings(root);
            root = RemovePrivateMethods(root);
            root = RemovePrivateFields(root);
            root = DumpEvents(root);
            root = DumpMethods(root);
            root = DumpConversionOperators(root);
            root = DumpConstructors(root);
            root = DumpProperties(root);

            
            return doc.WithSyntaxRoot(root);

        }
        private async Task <InvocationContext> GetInvocation(Microsoft.CodeAnalysis.Document document, int offset)
        {
            var sourceText = await document.GetTextAsync();

            var position = offset;
            var tree     = await document.GetSyntaxTreeAsync();

            var root = await tree.GetRootAsync();

            var node = root.FindToken(position).Parent;

            // Walk up until we find a node that we're interested in.
            while (node != null)
            {
                if (node is InvocationExpressionSyntax invocation && invocation.ArgumentList != null && invocation.ArgumentList.Span.Contains(position))
                {
                    var semanticModel = await document.GetSemanticModelAsync();

                    return(new InvocationContext(semanticModel, position, invocation.Expression, invocation.ArgumentList, invocation.IsInStaticContext()));
                }

                if (node is ObjectCreationExpressionSyntax objectCreation && objectCreation.ArgumentList != null && objectCreation.ArgumentList.Span.Contains(position))
                {
                    var semanticModel = await document.GetSemanticModelAsync();

                    return(new InvocationContext(semanticModel, position, objectCreation, objectCreation.ArgumentList, objectCreation.IsInStaticContext()));
                }

                if (node is AttributeSyntax attributeSyntax && attributeSyntax.ArgumentList != null && attributeSyntax.ArgumentList.Span.Contains(position))
                {
                    var semanticModel = await document.GetSemanticModelAsync();

                    return(new InvocationContext(semanticModel, position, attributeSyntax, attributeSyntax.ArgumentList, attributeSyntax.IsInStaticContext()));
                }

                node = node.Parent;
            }

            return(null);
        }
示例#33
0
        private static async Task <O.TextPart[][]> CreateDocumentLines(R.Document document, ImmutableArray <R.Diagnostic> diagnostics)
        {
            var tree = await document.GetSyntaxTreeAsync().ConfigureAwait(false);

            var text = await document.GetTextAsync().ConfigureAwait(false);

            return(text.Lines
                   .Select(x =>
            {
                // TODO: diagnostics に該当するものがないなら LinkedList 使わないで行きたい気持ち
                var parts = new LinkedList <WorkingTextPart>();
                // TODO: シンタックスハイライト
                parts.AddFirst(new WorkingTextPart(O.TextPartType.Plain, x.Span, null));

                foreach (var diagnostic in diagnostics)
                {
                    if (diagnostic.Location.SourceTree != tree)
                    {
                        continue;
                    }

                    var diagSpan = diagnostic.Location.SourceSpan;
                    if (!x.Span.IntersectsWith(diagSpan))
                    {
                        continue;
                    }

                    var node = parts.First;
                    while (node != null)
                    {
                        var part = node.Value;

                        if ((!part.Severity.HasValue || part.Severity.Value < diagnostic.Severity) &&
                            part.Span.Intersection(diagSpan) is R.Text.TextSpan intersection)
                        {
                            if (intersection.Start > part.Span.Start)
                            {
                                parts.AddBefore(
                                    node,
                                    new WorkingTextPart(
                                        part.Type,
                                        new R.Text.TextSpan(part.Span.Start, intersection.Start - part.Span.Start),
                                        part.Severity
                                        )
                                    );
                            }

                            node.Value = new WorkingTextPart(part.Type, intersection, diagnostic.Severity);

                            if (intersection.End < part.Span.End)
                            {
                                node = parts.AddAfter(
                                    node,
                                    new WorkingTextPart(
                                        part.Type,
                                        new R.Text.TextSpan(intersection.End, part.Span.End - intersection.End),
                                        part.Severity
                                        )
                                    );
                            }
                        }

                        node = node.Next;
                    }
                }

                return parts
                .Select(y => new O.TextPart(y.Type, text.ToString(y.Span), y.Severity))
                .ToArray();
            })
                   .ToArray());
        }
示例#34
0
        /// <summary>
        /// Get the text changes between this document and a prior version of the same document.
        /// The changes, when applied to the text of the old document, will produce the text of the current document.
        /// </summary>
        public async Task <IEnumerable <TextChange> > GetTextChangesAsync(Document oldDocument, CancellationToken cancellationToken = default)
        {
            try
            {
                using (Logger.LogBlock(FunctionId.Workspace_Document_GetTextChanges, this.Name, cancellationToken))
                {
                    if (oldDocument == this)
                    {
                        // no changes
                        return(SpecializedCollections.EmptyEnumerable <TextChange>());
                    }

                    if (this.Id != oldDocument.Id)
                    {
                        throw new ArgumentException(WorkspacesResources.The_specified_document_is_not_a_version_of_this_document);
                    }

                    // first try to see if text already knows its changes
                    IList <TextChange> textChanges = null;
                    if (this.TryGetText(out var text) && oldDocument.TryGetText(out var oldText))
                    {
                        if (text == oldText)
                        {
                            return(SpecializedCollections.EmptyEnumerable <TextChange>());
                        }

                        var container = text.Container;
                        if (container != null)
                        {
                            textChanges = text.GetTextChanges(oldText).ToList();

                            // if changes are significant (not the whole document being replaced) then use these changes
                            if (textChanges.Count > 1 || (textChanges.Count == 1 && textChanges[0].Span != new TextSpan(0, oldText.Length)))
                            {
                                return(textChanges);
                            }
                        }
                    }

                    // get changes by diffing the trees
                    if (this.SupportsSyntaxTree)
                    {
                        var tree = await this.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

                        var oldTree = await oldDocument.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

                        return(tree.GetChanges(oldTree));
                    }

                    text = await this.GetTextAsync(cancellationToken).ConfigureAwait(false);

                    oldText = await oldDocument.GetTextAsync(cancellationToken).ConfigureAwait(false);

                    return(text.GetTextChanges(oldText).ToList());
                }
            }
            catch (Exception e) when(FatalError.ReportUnlessCanceled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }