예제 #1
0
 public void Navigate(INavigableRelationship relationship)
 {
     try {
         Location.GotoSource(_serviceProvider);
     } catch (Exception ex) when(!ex.IsCriticalException())
     {
         MessageBox.Show(Strings.CannotGoToDefn_Name.FormatUI(SymbolSpan.GetText()), Strings.ProductTitle);
     }
 }
예제 #2
0
        private static SymbolSpan CreateSymbolSpan(SyntaxTree syntaxTree, SourceText text, ClassifiedSpan span, ClassificationSpan classificationSpan)
        {
            var lineSpan   = syntaxTree.GetLineSpan(span.TextSpan);
            var symbolSpan = new SymbolSpan()
            {
                Start  = classificationSpan.Start,
                Length = classificationSpan.Length,
            };

            return(symbolSpan);
        }
        public void AppendDefinition(string text, DefinitionSymbol definition)
        {
            SymbolSpan symbolSpan = new SymbolSpan()
            {
                Start  = StringBuilder.Length,
                Length = text.Length,
            };

            StringBuilder.Append(text);
            BoundSourceFile.Definitions.Add(symbolSpan.CreateDefinition(definition));
            references.Add(symbolSpan.CreateReference(definition));
        }
예제 #4
0
        private void AddReferencesToOverriddenMembers(
            SymbolSpan symbolSpan,
            ISymbol declaredSymbol,
            bool excludeFromSearch     = false,
            SymbolId relatedDefinition = default(SymbolId))
        {
            if (!declaredSymbol.IsOverride)
            {
                return;
            }

            IMethodSymbol method = declaredSymbol as IMethodSymbol;

            if (method != null)
            {
                var overriddenMethod = method.OverriddenMethod;
                if (overriddenMethod != null)
                {
                    references.Add(symbolSpan.CreateReference(GetReferenceSymbol(overriddenMethod, ReferenceKind.Override), relatedDefinition));
                }
            }

            IPropertySymbol property = declaredSymbol as IPropertySymbol;

            if (property != null)
            {
                var overriddenProperty = property.OverriddenProperty;
                if (overriddenProperty != null)
                {
                    references.Add(symbolSpan.CreateReference(GetReferenceSymbol(overriddenProperty, ReferenceKind.Override), relatedDefinition));
                }
            }

            IEventSymbol eventSymbol = declaredSymbol as IEventSymbol;

            if (eventSymbol != null)
            {
                var overriddenEvent = eventSymbol.OverriddenEvent;
                if (overriddenEvent != null)
                {
                    references.Add(symbolSpan.CreateReference(GetReferenceSymbol(overriddenEvent, ReferenceKind.Override), relatedDefinition));
                }
            }

            if (excludeFromSearch)
            {
                references[references.Count - 1].Reference.ExcludeFromSearch = true;
            }

            // TODO: Should we add transitive overrides
        }
        public void AppendReferences(string text, params ReferenceSymbol[] referenceSymbols)
        {
            SymbolSpan symbolSpan = new SymbolSpan()
            {
                Start  = StringBuilder.Length,
                Length = text.Length,
            };

            StringBuilder.Append(text);
            foreach (var reference in referenceSymbols)
            {
                references.Add(symbolSpan.CreateReference(reference));
            }
        }
예제 #6
0
 public void Navigate(INavigableRelationship relationship)
 {
     try {
         PythonToolsPackage.NavigateTo(
             _serviceProvider,
             CommonUtils.GetLocalFilePath(VariableLocation.Uri),
             Guid.Empty,
             VariableLocation.Range.Start.Line,
             VariableLocation.Range.Start.Character
             );
     } catch (Exception ex) when(!ex.IsCriticalException())
     {
         MessageBox.Show(Strings.CannotGoToDefn_Name.FormatUI(SymbolSpan.GetText()), Strings.ProductTitle);
     }
 }
예제 #7
0
 public void Navigate(INavigableRelationship relationship)
 {
     try {
         PythonToolsPackage.NavigateTo(
             _serviceProvider,
             Variable.Location.FilePath,
             Guid.Empty,
             Variable.Location.StartLine - 1,
             Variable.Location.StartColumn - 1
             );
     } catch (Exception ex) when(!ex.IsCriticalException())
     {
         MessageBox.Show(Strings.CannotGoToDefn_Name.FormatUI(SymbolSpan.GetText()), Strings.ProductTitle);
     }
 }
예제 #8
0
        private void AddReferencesToImplementedMembers(
            SymbolSpan symbolSpan,
            ISymbol declaredSymbol,
            SymbolId relatedDefinition = default(SymbolId))
        {
            var declaringType        = declaredSymbol.ContainingType;
            var implementationLookup = interfaceMemberImplementationMap.GetOrAdd(declaringType, type =>
            {
                return(type.AllInterfaces
                       .SelectMany(implementedInterface =>
                                   implementedInterface.GetMembers()
                                   .Select(member => CreateKeyValuePair(type.FindImplementationForInterfaceMember(member), member))
                                   .Where(kvp => kvp.Key != null))
                       .ToLookup(kvp => kvp.Key, kvp => kvp.Value));
            });

            foreach (var implementedMember in implementationLookup[declaredSymbol])
            {
                references.Add(symbolSpan.CreateReference(GetReferenceSymbol(implementedMember, ReferenceKind.InterfaceMemberImplementation), relatedDefinition));
            }
        }
예제 #9
0
        public async Task <BoundSourceFile> CreateBoundSourceFile()
        {
            var syntaxRoot = await _document.GetSyntaxRootAsync();

            var syntaxTree = syntaxRoot.SyntaxTree;

            SemanticModel = _compilation.GetSemanticModel(syntaxTree);
            DocumentText  = await _document.GetTextAsync();

            boundSourceFile.SourceFile.Info.Lines = DocumentText.Lines.Count;
            boundSourceFile.SourceFile.Info.Size  = DocumentText.Length;

            var classificationSpans = (IReadOnlyList <ClassifiedSpan>) await Classifier.GetClassifiedSpansAsync(_document, syntaxRoot.FullSpan);

            var text = await _document.GetTextAsync();

            classificationSpans = MergeSpans(classificationSpans).ToList();
            var fileClassificationSpans = new List <ClassificationSpan>();

            foreach (var span in classificationSpans)
            {
                if (SkipSpan(span))
                {
                    continue;
                }

                ClassificationSpan classificationSpan = new ClassificationSpan();
                fileClassificationSpans.Add(classificationSpan);

                classificationSpan.Start          = span.TextSpan.Start;
                classificationSpan.Length         = span.TextSpan.Length;
                classificationSpan.Classification = span.ClassificationType;

                if (!IsSemanticSpan(span))
                {
                    continue;
                }

                var token = syntaxRoot.FindToken(span.TextSpan.Start, findInsideTrivia: true);

                if (semanticServices.IsNewKeyword(token))
                {
                    continue;
                }

                ISymbol symbol         = null;
                ISymbol declaredSymbol = null;
                bool    isThis         = false;

                if (span.ClassificationType != ClassificationTypeNames.Keyword)
                {
                    declaredSymbol = SemanticModel.GetDeclaredSymbol(token.Parent);
                }

                var usingExpression = semanticServices.TryGetUsingExpressionFromToken(token);
                if (usingExpression != null)
                {
                    var disposeSymbol = CompilationServices.IDisposable_Dispose.Value;
                    if (disposeSymbol != null)
                    {
                        var typeInfo          = SemanticModel.GetTypeInfo(usingExpression);
                        var disposeImplSymbol = typeInfo.Type?.FindImplementationForInterfaceMember(disposeSymbol);
                        if (disposeImplSymbol != null)
                        {
                            SymbolSpan usingSymbolSpan = CreateSymbolSpan(syntaxTree, text, span, classificationSpan);
                            references.Add(usingSymbolSpan.CreateReference(GetReferenceSymbol(disposeImplSymbol, ReferenceKind.UsingDispose)));
                        }
                    }
                }

                if (semanticServices.IsOverrideKeyword(token))
                {
                    var bindableNode = token.Parent;
                    bindableNode = semanticServices.GetEventField(bindableNode);

                    var parentSymbol = SemanticModel.GetDeclaredSymbol(bindableNode);

                    SymbolSpan parentSymbolSpan = CreateSymbolSpan(syntaxTree, text, span, classificationSpan);

                    // Don't allow this to show up in search. It's only added for go to definition navigation
                    // on override keyword.
                    AddReferencesToOverriddenMembers(parentSymbolSpan, parentSymbol, excludeFromSearch: true);
                }

                if (symbol == null)
                {
                    symbol = declaredSymbol;

                    if (declaredSymbol == null)
                    {
                        var node = GetBindableParent(token);
                        if (node != null)
                        {
                            symbol = GetSymbol(node, out isThis);
                        }
                    }
                }

                if (symbol == null || symbol.ContainingAssembly == null)
                {
                    continue;
                }

                if (symbol.Kind == SymbolKind.Local ||
                    symbol.Kind == SymbolKind.Parameter ||
                    symbol.Kind == SymbolKind.TypeParameter ||
                    symbol.Kind == SymbolKind.RangeVariable)
                {
                    //  Just generate group ids rather than full ref/def
                    var localSymbolId = localSymbolIdMap.GetOrAdd(symbol, localSymbolIdMap.Count + 1);
                    classificationSpan.LocalGroupId = localSymbolId;
                    continue;
                }

                if ((symbol.Kind == SymbolKind.Event ||
                     symbol.Kind == SymbolKind.Field ||
                     symbol.Kind == SymbolKind.Method ||
                     symbol.Kind == SymbolKind.NamedType ||
                     symbol.Kind == SymbolKind.Property) &&
                    symbol.Locations.Length >= 1)
                {
                    var documentationId = GetDocumentationCommentId(symbol);

                    if (string.IsNullOrEmpty(documentationId))
                    {
                        continue;
                    }

                    SymbolSpan symbolSpan = CreateSymbolSpan(syntaxTree, text, span, classificationSpan);

                    if (declaredSymbol != null)
                    {
                        // This is a definition
                        var definitionSymbol = GetDefinitionSymbol(symbol, documentationId);
                        var definitionSpan   = symbolSpan.CreateDefinition(definitionSymbol);
                        boundSourceFile.AddDefinition(definitionSpan);

                        // A reference symbol for the definition is added so the definition is found in find all references
                        var definitionReferenceSymbol = GetReferenceSymbol(symbol, referenceKind: ReferenceKind.Definition);
                        references.Add(symbolSpan.CreateReference(definitionReferenceSymbol));

                        ProcessDefinitionAndAddAdditionalReferenceSymbols(symbol, definitionSpan, token);
                    }
                    else
                    {
                        // This is a reference
                        var referenceSymbol = GetReferenceSymbol(symbol, documentationId, token);
                        var referenceSpan   = symbolSpan.CreateReference(referenceSymbol);

                        // This parameter should not show up in find all references search
                        // but should navigate to type for go to definition
                        referenceSymbol.ExcludeFromSearch = isThis;// token.IsKind(SyntaxKind.ThisKeyword) || token.IsKind(SyntaxKind.BaseKeyword);
                        references.Add(referenceSpan);

                        // Reference to external project
                        if (referenceSymbol.ProjectId != _analyzedProject.Id)
                        {
                            if (!_analyzedProject.ReferenceDefinitionMap.ContainsKey(referenceSymbol))
                            {
                                _analyzedProject.ReferenceDefinitionMap.TryAdd(referenceSymbol, GetDefinitionSymbol(symbol, documentationId));
                            }
                        }

                        AddAdditionalReferenceSymbols(symbol, referenceSpan, token);
                    }
                }
            }

            boundSourceFile.AddClassifications(fileClassificationSpans);
            boundSourceFile.AddReferences(references);
            return(boundSourceFile.Build());
        }
        private static IEnumerable <SymbolSpan> GetSymbolSpans(SemanticModel semanticModel, SyntaxNode node)
        {
            switch (node.Kind)
            {
            case SyntaxKind.VariableDeclarator:
            {
                var expression = (VariableDeclaratorSyntax)node;
                var symbol     = semanticModel.GetDeclaredSymbol(expression);
                if (symbol != null)
                {
                    yield return(SymbolSpan.CreateDefinition(symbol, expression.Identifier.SourceRange, expression.Identifier.FileSpan));
                }
                break;
            }

            case SyntaxKind.ClassType:
            case SyntaxKind.StructType:
            {
                var expression = (StructTypeSyntax)node;
                var symbol     = semanticModel.GetDeclaredSymbol(expression);
                if (symbol != null && expression.Name != null)
                {
                    yield return(SymbolSpan.CreateDefinition(symbol, expression.Name.SourceRange, expression.Name.FileSpan));
                }
                break;
            }

            case SyntaxKind.InterfaceType:
            {
                var expression = (InterfaceTypeSyntax)node;
                var symbol     = semanticModel.GetDeclaredSymbol(expression);
                if (symbol != null)
                {
                    yield return(SymbolSpan.CreateDefinition(symbol, expression.Name.SourceRange, expression.Name.FileSpan));
                }
                break;
            }

            case SyntaxKind.IdentifierName:
            {
                var expression = (IdentifierNameSyntax)node;
                var symbol     = semanticModel.GetSymbol(expression);
                if (symbol != null)
                {
                    yield return(SymbolSpan.CreateReference(symbol, expression.Name.SourceRange, expression.Name.FileSpan));
                }
                break;
            }

            case SyntaxKind.IdentifierDeclarationName:
            {
                var expression = (IdentifierDeclarationNameSyntax)node;
                var symbol     = semanticModel.GetSymbol(expression);
                if (symbol != null)
                {
                    yield return(SymbolSpan.CreateDefinition(symbol, expression.Name.SourceRange, expression.Name.FileSpan));
                }
                break;
            }

            case SyntaxKind.FieldAccessExpression:
            {
                var expression = (FieldAccessExpressionSyntax)node;
                var symbol     = semanticModel.GetSymbol(expression);
                if (symbol != null)
                {
                    yield return(SymbolSpan.CreateReference(symbol, expression.Name.SourceRange, expression.Name.FileSpan));
                }
                break;
            }

            case SyntaxKind.MethodInvocationExpression:
            {
                var expression = (MethodInvocationExpressionSyntax)node;
                var symbol     = semanticModel.GetSymbol(expression);
                if (symbol != null)
                {
                    yield return(SymbolSpan.CreateReference(symbol, expression.Name.SourceRange, expression.Name.FileSpan));
                }
                break;
            }

            case SyntaxKind.FunctionInvocationExpression:
            {
                var expression = (FunctionInvocationExpressionSyntax)node;
                var symbol     = semanticModel.GetSymbol(expression);
                if (symbol != null)
                {
                    yield return(SymbolSpan.CreateReference(symbol,
                                                            expression.Name.GetUnqualifiedName().Name.SourceRange,
                                                            expression.Name.GetUnqualifiedName().Name.FileSpan));
                }
                break;
            }

            case SyntaxKind.FunctionDefinition:
            {
                var expression = (FunctionDefinitionSyntax)node;
                var symbol     = semanticModel.GetDeclaredSymbol(expression);
                if (symbol != null)
                {
                    yield return(SymbolSpan.CreateDefinition(symbol,
                                                             expression.Name.GetUnqualifiedName().Name.SourceRange,
                                                             expression.Name.GetUnqualifiedName().Name.FileSpan));
                }
                break;
            }

            case SyntaxKind.FunctionDeclaration:
            {
                var expression = (FunctionDeclarationSyntax)node;
                var symbol     = semanticModel.GetDeclaredSymbol(expression);
                if (symbol != null)
                {
                    yield return(SymbolSpan.CreateDefinition(symbol,
                                                             expression.Name.GetUnqualifiedName().Name.SourceRange,
                                                             expression.Name.GetUnqualifiedName().Name.FileSpan));
                }
                break;
            }
            }
        }
예제 #11
0
        public static IEnumerable <SymbolSpan> ParseHighlightSpans(string highlight)
        {
            highlight  = highlight.Replace(HighlightStartTag, HighlightStartTagCharString);
            highlight  = highlight.Replace(HighlightEndTag, HighlightEndTagCharString);
            highlight += "\n";

            List <SymbolSpan> spans       = new List <SymbolSpan>(1);
            StringBuilder     builder     = new StringBuilder();
            SymbolSpan        currentSpan = new SymbolSpan();

            for (int i = 0; i < highlight.Length; i++)
            {
                var ch = highlight[i];
                switch (ch)
                {
                case StartOfLineSpecifierChar:
                    var endOfLineSpecifierIndex = highlight.IndexOf(EndOfLineSpecifierChar, i + 1);
                    if (endOfLineSpecifierIndex >= 0)
                    {
                        int lineNumber       = 0;
                        var lineNumberString = highlight.Substring(i + 1, endOfLineSpecifierIndex - (i + 1));
                        if (int.TryParse(lineNumberString, out lineNumber))
                        {
                            currentSpan.LineNumber = lineNumber;
                        }

                        i = endOfLineSpecifierIndex;
                    }
                    else
                    {
                        i = highlight.Length;
                    }

                    continue;

                case HighlightStartTagChar:
                    if (currentSpan.Length == 0)
                    {
                        currentSpan.LineSpanStart = builder.Length;
                    }

                    break;

                case HighlightEndTagChar:
                    currentSpan.Length = (builder.Length - currentSpan.LineSpanStart);
                    break;

                case EndOfLineSpecifierChar:
                    // This is only encountered if this character appears before
                    // a start of line specifier character. Truncate in that case.
                    builder.Clear();
                    break;

                case '\r':
                    // Just skip carriage return.
                    break;

                case '\n':
                    if (spans.Count != 0)
                    {
                        var priorSpan = spans[spans.Count - 1];
                        if (currentSpan.LineNumber != 0)
                        {
                            priorSpan.LineNumber = currentSpan.LineNumber - 1;
                        }
                        else
                        {
                            currentSpan.LineNumber = priorSpan.LineNumber + 1;
                        }
                    }

                    currentSpan.LineSpanText = builder.ToString();
                    currentSpan.LineSpanText = currentSpan.LineSpanText.Trim();
                    spans.Add(currentSpan);
                    currentSpan = new SymbolSpan();
                    builder.Clear();
                    break;

                default:
                    if (char.IsWhiteSpace(ch) && builder.Length == 0)
                    {
                        currentSpan.LineOffset++;

                        // Skip leading whitespace
                        continue;
                    }

                    builder.Append(ch);
                    break;
                }
            }

            return(spans.Where(s => s.Length != 0));
        }