public async Task <GraphBuilder> GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken) { var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false); foreach (var node in context.InputNodes) { var symbol = graphBuilder.GetSymbol(node); if (!(symbol is INamedTypeSymbol namedType)) { continue; } if (namedType.TypeKind == TypeKind.Class) { var derivedTypes = await DependentTypeFinder.FindImmediatelyDerivedClassesAsync( namedType, solution, cancellationToken).ConfigureAwait(false); foreach (var derivedType in derivedTypes) { var symbolNode = await graphBuilder.AddNodeAsync( derivedType, relatedNode : node).ConfigureAwait(false); graphBuilder.AddLink(symbolNode, CodeLinkCategories.InheritsFrom, node); } } else if (namedType.TypeKind == TypeKind.Interface) { var derivedTypes = await DependentTypeFinder.FindImmediatelyDerivedAndImplementingTypesAsync( namedType, solution, cancellationToken).ConfigureAwait(false); foreach (var derivedType in derivedTypes) { var symbolNode = await graphBuilder.AddNodeAsync( derivedType, relatedNode : node).ConfigureAwait(false); graphBuilder.AddLink(symbolNode, CodeLinkCategories.InheritsFrom, node); } } } return(graphBuilder); }
public async Task ImmediatelyDerivedInterfaces_VisualBasic() { var solution = new AdhocWorkspace().CurrentSolution; // create portable assembly with an interface solution = AddProjectWithMetadataReferences(solution, "PortableProject", LanguageNames.VisualBasic, @" Namespace N Public Interface IBaseInterface End Interface End Namespace ", MscorlibRefPortable); var portableProject = GetPortableProject(solution); // create a normal assembly with a type implementing that interface solution = AddProjectWithMetadataReferences(solution, "NormalProject", LanguageNames.VisualBasic, @" Imports N Namespace M Public Class ImplementingClass Implements IBaseInterface End Class End Namespace ", MscorlibRef, portableProject.Id); // get symbols for types var portableCompilation = await GetPortableProject(solution).GetCompilationAsync(); var baseInterfaceSymbol = portableCompilation.GetTypeByMetadataName("N.IBaseInterface"); var normalCompilation = await solution.Projects.Single(p => p.Name == "NormalProject").GetCompilationAsync(); var implementingClassSymbol = normalCompilation.GetTypeByMetadataName("M.ImplementingClass"); // verify that the symbols are different (due to retargeting) Assert.NotEqual(baseInterfaceSymbol, implementingClassSymbol.Interfaces.Single()); // verify that the implementing types of `N.IBaseInterface` correctly resolve to `M.ImplementingClass` var typesThatImplementInterface = await DependentTypeFinder.FindImmediatelyDerivedAndImplementingTypesAsync( SymbolAndProjectId.Create(baseInterfaceSymbol, portableProject.Id), solution, CancellationToken.None); Assert.Equal(implementingClassSymbol, typesThatImplementInterface.Single().Symbol); }
public async Task ImmediatelyDerivedInterfaces_CSharp() { var solution = new AdhocWorkspace().CurrentSolution; // create portable assembly with an interface solution = AddProjectWithMetadataReferences(solution, "PortableProject", LanguageNames.CSharp, @" namespace N { public interface IBaseInterface { } } ", MscorlibRefPortable); // create a normal assembly with a type implementing that interface solution = AddProjectWithMetadataReferences(solution, "NormalProject", LanguageNames.CSharp, @" using N; namespace M { public class ImplementingClass : IBaseInterface { } } ", MscorlibRef, solution.Projects.Single(pid => pid.Name == "PortableProject").Id); // get symbols for types var portableCompilation = await solution.Projects.Single(p => p.Name == "PortableProject").GetCompilationAsync(); var baseInterfaceSymbol = portableCompilation.GetTypeByMetadataName("N.IBaseInterface"); var normalCompilation = await solution.Projects.Single(p => p.Name == "NormalProject").GetCompilationAsync(); var implementingClassSymbol = normalCompilation.GetTypeByMetadataName("M.ImplementingClass"); // verify that the symbols are different (due to retargeting) Assert.NotEqual(baseInterfaceSymbol, implementingClassSymbol.Interfaces.Single()); // verify that the implementing types of `N.IBaseInterface` correctly resolve to `M.ImplementingClass` var typesThatImplementInterface = await DependentTypeFinder.FindImmediatelyDerivedAndImplementingTypesAsync( baseInterfaceSymbol, solution, CancellationToken.None); Assert.Equal(implementingClassSymbol, typesThatImplementInterface.Single().Symbol); }