Exemple #1
0
        /// <inheritdoc/>
        protected override void ReParseImpl()
        {
            Stopwatch stopwatch = Stopwatch.StartNew();

            ITextSnapshot snapshot = TextBuffer.CurrentSnapshot;

            try
            {
                ITextDocument       textDocument  = TextDocument;
                string              fileName      = textDocument != null ? textDocument.FilePath : null;
                Document            document      = snapshot.GetOpenDocumentInCurrentContextWithChanges();
                SourceTextContainer textContainer = document != null?document.GetTextAsync().Result.Container : null;

                Project  project  = document != null ? document.Project : null;
                Solution solution = project != null ? project.Solution : null;

                List <ITagSpan <IInheritanceTag> > tags = new List <ITagSpan <IInheritanceTag> >();

                if (document != null && !string.IsNullOrEmpty(fileName))
                {
                    SyntaxTree    syntaxTree    = document.GetSyntaxTreeAsync().Result;
                    SyntaxNode    syntaxRoot    = syntaxTree.GetRoot();
                    SemanticModel semanticModel = document.GetSemanticModelAsync().Result;
                    Compilation   compilation   = semanticModel.Compilation;

                    IDictionary <ISymbol, ISet <ISymbol> > interfaceImplementations = new Dictionary <ISymbol, ISet <ISymbol> >();

                    List <CSharpSyntaxNode> allMembers = new List <CSharpSyntaxNode>();
                    IEnumerable <BaseTypeDeclarationSyntax> typeNodes = syntaxRoot.DescendantNodes().OfType <BaseTypeDeclarationSyntax>();
                    foreach (var typeNode in typeNodes)
                    {
                        ISymbol symbol = semanticModel.GetDeclaredSymbol(typeNode);
                        if (symbol == null)
                        {
                            MarkDirty(true);
                            return;
                        }

                        INamedTypeSymbol typeSymbol = symbol as INamedTypeSymbol;
                        if (typeSymbol == null)
                        {
                            continue;
                        }

                        // get implemented interface symbols
                        foreach (INamedTypeSymbol namedTypeSymbol in typeSymbol.AllInterfaces)
                        {
                            foreach (ISymbol member in namedTypeSymbol.GetMembers())
                            {
                                ISymbol implementation = typeSymbol.FindImplementationForInterfaceMember(member);
                                if (implementation == null || !implementation.ContainingSymbol.Equals(typeSymbol))
                                {
                                    continue;
                                }

                                ISet <ISymbol> symbols;
                                if (!interfaceImplementations.TryGetValue(implementation, out symbols))
                                {
                                    symbols = new HashSet <ISymbol>();
                                    interfaceImplementations[implementation] = symbols;
                                }

                                symbols.Add(member);
                            }
                        }

                        TypeDeclarationSyntax typeDeclarationSyntax = typeNode as TypeDeclarationSyntax;
                        if (typeDeclarationSyntax != null)
                        {
                            allMembers.AddRange(typeDeclarationSyntax.Members);
                        }

                        if (typeSymbol.IsSealed)
                        {
                            continue;
                        }

                        // types which implement or derive from this type
                        ISet <ITypeSymbol> derivedTypes = new HashSet <ITypeSymbol>();
                        derivedTypes.UnionWith(FindDerivedClassesAsync.Value(typeSymbol, solution, null, CancellationToken.None).Result);
                        derivedTypes.UnionWith(FindDerivedInterfacesAsync.Value(typeSymbol, solution, null, CancellationToken.None).Result);
                        derivedTypes.UnionWith(FindImplementingTypesAsync.Value(typeSymbol, solution, null, CancellationToken.None).Result);

                        if (derivedTypes.Count == 0)
                        {
                            continue;
                        }

                        StringBuilder builder = new StringBuilder();
                        string        elementKindDisplayName =
                            "types";

                        builder.AppendLine("Derived " + elementKindDisplayName + ":");
                        foreach (var derived in derivedTypes)
                        {
                            builder.AppendLine("    " + derived.ToString());
                        }

                        SyntaxToken  identifier = typeNode.Accept(IdentifierSyntaxVisitor.Instance);
                        SnapshotSpan span       = new SnapshotSpan(snapshot, new Span(identifier.SpanStart, identifier.Span.Length));

                        InheritanceGlyph tag = typeSymbol.TypeKind == TypeKind.Interface ? InheritanceGlyph.HasImplementations : InheritanceGlyph.Overridden;

                        var targets = derivedTypes.Select(i => new TypeTarget(textContainer, project, solution, i));
                        tags.Add(new TagSpan <IInheritanceTag>(span, _tagFactory.CreateTag(tag, builder.ToString().TrimEnd(), targets)));
                    }

                    foreach (var eventFieldDeclarationSyntax in allMembers.OfType <EventFieldDeclarationSyntax>().ToArray())
                    {
                        allMembers.AddRange(eventFieldDeclarationSyntax.Declaration.Variables);
                    }

                    foreach (CSharpSyntaxNode memberNode in allMembers)
                    {
                        if (!(memberNode is MethodDeclarationSyntax) &&
                            !(memberNode is PropertyDeclarationSyntax) &&
                            !(memberNode is IndexerDeclarationSyntax) &&
                            !(memberNode is EventDeclarationSyntax) &&
                            !(memberNode is EventFieldDeclarationSyntax) &&
                            !(memberNode is VariableDeclaratorSyntax))
                        {
                            continue;
                        }

                        ISymbol symbol = semanticModel.GetDeclaredSymbol(memberNode);
                        if (symbol == null)
                        {
                            MarkDirty(true);
                            return;
                        }

                        // members which this member implements
                        ISet <ISymbol> implementedMethods = new HashSet <ISymbol>();
                        if (!interfaceImplementations.TryGetValue(symbol, out implementedMethods))
                        {
                            implementedMethods = new HashSet <ISymbol>();
                        }

                        ISet <ISymbol> overriddenMethods = new HashSet <ISymbol>();

                        IMethodSymbol methodSymbol = symbol as IMethodSymbol;
                        if (methodSymbol != null)
                        {
                            // methods which this method overrides
                            for (IMethodSymbol current = methodSymbol.OverriddenMethod;
                                 current != null;
                                 current = current.OverriddenMethod)
                            {
                                overriddenMethods.Add(current);
                            }
                        }
                        else
                        {
                            IPropertySymbol propertySymbol = symbol as IPropertySymbol;
                            if (propertySymbol != null)
                            {
                                // properties which this property overrides
                                for (IPropertySymbol current = propertySymbol.OverriddenProperty;
                                     current != null;
                                     current = current.OverriddenProperty)
                                {
                                    overriddenMethods.Add(current);
                                }
                            }
                            else
                            {
                                IEventSymbol eventSymbol = symbol as IEventSymbol;
                                if (eventSymbol != null)
                                {
                                    // events which this event overrides
                                    for (IEventSymbol current = eventSymbol.OverriddenEvent;
                                         current != null;
                                         current = current.OverriddenEvent)
                                    {
                                        overriddenMethods.Add(current);
                                    }
                                }
                            }
                        }

                        ISet <ISymbol> implementingMethods = new HashSet <ISymbol>(SymbolFinder.FindImplementationsAsync(symbol, solution).Result);

                        ISet <ISymbol> overridingMethods = new HashSet <ISymbol>(SymbolFinder.FindOverridesAsync(symbol, solution).Result);

                        if (implementingMethods.Count == 0 && implementedMethods.Count == 0 && overriddenMethods.Count == 0 && overridingMethods.Count == 0)
                        {
                            continue;
                        }

                        StringBuilder builder = new StringBuilder();
                        string        elementKindDisplayName =
                            symbol is IPropertySymbol ? "properties" :
                            symbol is IEventSymbol ? "events" :
                            "methods";

                        if (implementedMethods.Count > 0)
                        {
                            builder.AppendLine("Implemented " + elementKindDisplayName + ":");
                            foreach (var methodId in implementedMethods)
                            {
                                builder.AppendLine("    " + methodId.ToString());
                            }
                        }

                        if (overriddenMethods.Count > 0)
                        {
                            builder.AppendLine("Overridden " + elementKindDisplayName + ":");
                            foreach (var methodId in overriddenMethods)
                            {
                                builder.AppendLine("    " + methodId.ToString());
                            }
                        }

                        if (implementingMethods.Count > 0)
                        {
                            builder.AppendLine("Implementing " + elementKindDisplayName + " in derived types:");
                            foreach (var methodId in implementingMethods)
                            {
                                builder.AppendLine("    " + methodId.ToString());
                            }
                        }

                        if (overridingMethods.Count > 0)
                        {
                            builder.AppendLine("Overriding " + elementKindDisplayName + " in derived types:");
                            foreach (var methodId in overridingMethods)
                            {
                                builder.AppendLine("    " + methodId.ToString());
                            }
                        }

                        SyntaxToken  identifier = memberNode.Accept(IdentifierSyntaxVisitor.Instance);
                        SnapshotSpan span       = new SnapshotSpan(snapshot, new Span(identifier.SpanStart, identifier.Span.Length));

                        InheritanceGlyph tag;
                        if (implementedMethods.Count > 0)
                        {
                            if (overridingMethods.Count > 0)
                            {
                                tag = InheritanceGlyph.ImplementsAndOverridden;
                            }
                            else if (implementingMethods.Count > 0)
                            {
                                tag = InheritanceGlyph.ImplementsAndHasImplementations;
                            }
                            else
                            {
                                tag = InheritanceGlyph.Implements;
                            }
                        }
                        else if (implementingMethods.Count > 0)
                        {
                            tag = InheritanceGlyph.HasImplementations;
                        }
                        else if (overriddenMethods.Count > 0)
                        {
                            if (overridingMethods.Count > 0)
                            {
                                tag = InheritanceGlyph.OverridesAndOverridden;
                            }
                            else
                            {
                                tag = InheritanceGlyph.Overrides;
                            }
                        }
                        else
                        {
                            tag = InheritanceGlyph.Overridden;
                        }

                        List <ISymbol> members = new List <ISymbol>();
                        members.AddRange(implementedMethods);
                        members.AddRange(overriddenMethods);
                        members.AddRange(implementingMethods);
                        members.AddRange(overridingMethods);

                        var targets = members.Select(i => new MemberTarget(textContainer, project, solution, i));
                        tags.Add(new TagSpan <IInheritanceTag>(span, _tagFactory.CreateTag(tag, builder.ToString().TrimEnd(), targets)));
                    }
                }

                InheritanceParseResultEventArgs result = new InheritanceParseResultEventArgs(snapshot, stopwatch.Elapsed, tags);
                OnParseComplete(result);
            }
            catch (InvalidOperationException)
            {
                MarkDirty(true);
                throw;
            }
        }
Exemple #2
0
        /// <inheritdoc/>
        protected override void ReParseImpl()
        {
            Stopwatch stopwatch = Stopwatch.StartNew();

            ITextSnapshot snapshot = TextBuffer.CurrentSnapshot;

            try
            {
                ITextDocument   textDocument = TextDocument;
                string          fileName     = textDocument != null ? textDocument.FilePath : null;
                IDECompilerHost host         = new IDECompilerHost();
                IProject        project      = null;

                ILangService languageService;
                LangService_GetInstance(out languageService);
                if (languageService != null)
                {
                    ICSharpTextBuffer csharpBuffer = languageService.FindTextBuffer(fileName);
                    if (csharpBuffer != null)
                    {
                        project = csharpBuffer.Project;
                    }
                }

                List <ITagSpan <IInheritanceTag> > tags = new List <ITagSpan <IInheritanceTag> >();

                if (host != null && project != null && !string.IsNullOrEmpty(fileName))
                {
                    Compilation compilation = host.CreateCompiler(project).GetCompilation();
                    SourceFile  sourceFile;
                    if (!compilation.SourceFiles.TryGetValue(new FileName(fileName), out sourceFile))
                    {
                        InheritanceParseResultEventArgs errorResult = new InheritanceParseResultEventArgs(snapshot, stopwatch.Elapsed, tags);
                        OnParseComplete(errorResult);
                        return;
                    }

                    ParseTree parseTree = sourceFile.GetParseTree();

                    SpecializedMatchingMemberCollector collector = new SpecializedMatchingMemberCollector(host.Compilers.Select(i => i.GetCompilation()), false);

                    IEnumerable <ParseTreeNode> nodes = SelectTypes(parseTree);
                    foreach (var node in nodes)
                    {
                        CSharpType type = null;

                        type = compilation.GetTypeFromTypeDeclaration(node);
                        if (type == null)
                        {
                            MarkDirty(true);
                            return;
                        }

                        if (type.IsSealed)
                        {
                            continue;
                        }

                        // types which implement or derive from this type
                        ISet <CSharpType> derivedClasses = collector.GetDerivedTypes(type.SymbolicIdentifier);

                        if (derivedClasses.Count == 0)
                        {
                            continue;
                        }

                        StringBuilder builder = new StringBuilder();
                        string        elementKindDisplayName =
                            "types";

                        builder.AppendLine("Derived " + elementKindDisplayName + ":");
                        foreach (var derived in derivedClasses)
                        {
                            builder.AppendLine("    " + derived.GetFullTypeName());
                        }

                        int               nameIndex = node.Token;
                        Token             token     = parseTree.LexData.Tokens[nameIndex];
                        ITextSnapshotLine line      = snapshot.GetLineFromLineNumber(token.StartPosition.Line);
                        SnapshotSpan      span      = new SnapshotSpan(snapshot, new Span(line.Start + token.StartPosition.Character, token.EndPosition.Character - token.StartPosition.Character));

                        InheritanceGlyph tag = type.IsInterface ? InheritanceGlyph.HasImplementations : InheritanceGlyph.Overridden;

                        var targets = derivedClasses.Select(i => new TypeTarget(i.GetFullTypeName(), i.SymbolicIdentifier));
                        tags.Add(new TagSpan <IInheritanceTag>(span, _tagFactory.CreateTag(tag, builder.ToString().TrimEnd(), targets)));
                    }

                    nodes = parseTree.SelectMethodsPropertiesAndFields();
                    nodes = nodes.SelectMany(SelectDeclaratorsFromFields);
                    foreach (var node in nodes)
                    {
                        if (node is AccessorDeclarationNode)
                        {
                            // these nodes always result in an ArgumentException in GetMemberFromMemberDeclaration
                            continue;
                        }

                        CSharpMember member;
                        try
                        {
                            member = compilation.GetMemberFromMemberDeclaration(node);
                        }
                        catch (ArgumentException)
                        {
                            continue;
                        }

                        if (member == null)
                        {
                            MarkDirty(true);
                            return;
                        }

                        if (!SpecializedMatchingMemberCollector.IsSupportedMemberType(member))
                        {
                            continue;
                        }

                        // methods which this method implements
                        ISet <CSharpMemberIdentifier> implementedMethods = collector.GetImplementedInterfaceMembers(member.SymbolicIdentifier);

                        // methods which this method overrides
                        ISet <CSharpMemberIdentifier> overriddenMethods = collector.GetOverriddenBaseMembers(member.SymbolicIdentifier);

                        // methods which override this method
                        ISet <CSharpMemberIdentifier> overridingMethods = collector.GetOverridersFromDerivedTypes(member.SymbolicIdentifier);

                        // methods which implement this method
                        ISet <CSharpMemberIdentifier> implementingMethods = collector.GetImplementorsForInterfaceMember(member.SymbolicIdentifier);

                        if (implementingMethods.Count == 0 && implementedMethods.Count == 0 && overriddenMethods.Count == 0 && overridingMethods.Count == 0)
                        {
                            continue;
                        }

                        StringBuilder builder = new StringBuilder();
                        string        elementKindDisplayName =
                            member.IsProperty ? "properties" :
                            member.IsEvent ? "events" :
                            "methods";

                        if (implementedMethods.Count > 0)
                        {
                            builder.AppendLine("Implemented " + elementKindDisplayName + ":");
                            foreach (var methodId in implementedMethods)
                            {
                                builder.AppendLine("    " + methodId.ToString());
                            }
                        }

                        if (overriddenMethods.Count > 0)
                        {
                            builder.AppendLine("Overridden " + elementKindDisplayName + ":");
                            foreach (var methodId in overriddenMethods)
                            {
                                builder.AppendLine("    " + methodId.ToString());
                            }
                        }

                        if (implementingMethods.Count > 0)
                        {
                            builder.AppendLine("Implementing " + elementKindDisplayName + " in derived types:");
                            foreach (var methodId in implementingMethods)
                            {
                                builder.AppendLine("    " + methodId.ToString());
                            }
                        }

                        if (overridingMethods.Count > 0)
                        {
                            builder.AppendLine("Overriding " + elementKindDisplayName + " in derived types:");
                            foreach (var methodId in overridingMethods)
                            {
                                builder.AppendLine("    " + methodId.ToString());
                            }
                        }

                        int               nameIndex = node.Token;
                        Token             token     = parseTree.LexData.Tokens[nameIndex];
                        ITextSnapshotLine line      = snapshot.GetLineFromLineNumber(token.StartPosition.Line);
                        SnapshotSpan      span      = new SnapshotSpan(snapshot, new Span(line.Start + token.StartPosition.Character, token.EndPosition.Character - token.StartPosition.Character));

                        InheritanceGlyph tag;
                        if (implementedMethods.Count > 0)
                        {
                            if (overridingMethods.Count > 0)
                            {
                                tag = InheritanceGlyph.ImplementsAndOverridden;
                            }
                            else if (implementingMethods.Count > 0)
                            {
                                tag = InheritanceGlyph.ImplementsAndHasImplementations;
                            }
                            else
                            {
                                tag = InheritanceGlyph.Implements;
                            }
                        }
                        else if (implementingMethods.Count > 0)
                        {
                            tag = InheritanceGlyph.HasImplementations;
                        }
                        else if (overriddenMethods.Count > 0)
                        {
                            if (overridingMethods.Count > 0)
                            {
                                tag = InheritanceGlyph.OverridesAndOverridden;
                            }
                            else
                            {
                                tag = InheritanceGlyph.Overrides;
                            }
                        }
                        else
                        {
                            tag = InheritanceGlyph.Overridden;
                        }

                        List <CSharpMemberIdentifier> members = new List <CSharpMemberIdentifier>();
                        members.AddRange(implementedMethods);
                        members.AddRange(overriddenMethods);
                        members.AddRange(implementingMethods);
                        members.AddRange(overridingMethods);

                        var targets = members.Select(i => new MemberTarget(i));
                        tags.Add(new TagSpan <IInheritanceTag>(span, _tagFactory.CreateTag(tag, builder.ToString().TrimEnd(), targets)));
                    }
                }

                InheritanceParseResultEventArgs result = new InheritanceParseResultEventArgs(snapshot, stopwatch.Elapsed, tags);
                OnParseComplete(result);
            }
            catch (InvalidOperationException)
            {
                MarkDirty(true);
                throw;
            }
        }
Exemple #3
0
 public InheritanceTag(InheritanceGlyph glyph, string tooltip, List <IInheritanceTarget> members)
 {
     this._glyph   = glyph;
     this._tooltip = tooltip;
     this._targets = members;
 }
Exemple #4
0
 /// <inheritdoc/>
 public IInheritanceTag CreateTag(InheritanceGlyph glyph, string tooltip, IEnumerable <IInheritanceTarget> targets)
 {
     return(new InheritanceTag(glyph, tooltip, targets.ToList()));
 }
 public IInheritanceTag CreateTag(InheritanceGlyph glyph, string displayName, IEnumerable<IInheritanceTarget> targets)
 {
     return new InheritanceTag(glyph, displayName, targets.ToList());
 }
 public InheritanceTag(InheritanceGlyph glyph, string tooltip, List<IInheritanceTarget> members)
 {
     this._glyph = glyph;
     this._tooltip = tooltip;
     this._targets = members;
 }
 public IInheritanceTag CreateTag(InheritanceGlyph glyph, string displayName, IEnumerable <IInheritanceTarget> targets)
 {
     return(new InheritanceTag(glyph, displayName, targets.ToList()));
 }