internal static ISymbol ResolveSymbol(ISymbol originalSymbol, Compilation targetCompilation, SymbolKeyComparison comparison) { var sid = SymbolKey.Create(originalSymbol, CancellationToken.None); var symInfo = sid.Resolve(targetCompilation, (comparison & SymbolKeyComparison.IgnoreAssemblyIds) == SymbolKeyComparison.IgnoreAssemblyIds); return(symInfo.Symbol); }
private static bool IsCompatible <TExpressionSyntax>( ISemanticFactsService semanticFacts, SemanticModel semanticModel, IMethodSymbol constructor, ImmutableArray <TExpressionSyntax> expressions) where TExpressionSyntax : SyntaxNode { Debug.Assert(constructor.Parameters.Length == expressions.Length); // Resolve the constructor into our semantic model's compilation; if the constructor we're looking at is from // another project with a different language. var constructorInCompilation = (IMethodSymbol?)SymbolKey.Create(constructor).Resolve(semanticModel.Compilation).Symbol; Contract.ThrowIfNull(constructorInCompilation); for (var i = 0; i < constructorInCompilation.Parameters.Length; i++) { var constructorParameter = constructorInCompilation.Parameters[i]; if (constructorParameter == null) { return(false); } var conversion = semanticFacts.ClassifyConversion(semanticModel, expressions[i], constructorParameter.Type); if (!conversion.IsIdentity && !conversion.IsImplicit) { return(false); } } return(true); }
public void TestGenericMethodTypeParameterMissing1() { var source1 = @" public class C { void M<T>(T t) { } } "; var source2 = @" public class C { } "; var compilation1 = GetCompilation(source1, LanguageNames.CSharp); var compilation2 = GetCompilation(source2, LanguageNames.CSharp); var methods = GetDeclaredSymbols(compilation1).OfType <IMethodSymbol>(); foreach (var method in methods) { var key = SymbolKey.Create(method); key.Resolve(compilation2); } }
private static bool TryResolveSymbol(ISymbol symbol, Project project, CancellationToken cancellationToken, out ISymbol resolvedSymbol, out Project resolvedProject) { resolvedSymbol = null; resolvedProject = null; var currentProject = project.Solution.Workspace.CurrentSolution.GetProject(project.Id); if (currentProject == null) { return(false); } var originalCompilation = project.GetCompilationAsync(cancellationToken).WaitAndGetResult(cancellationToken); var symbolId = SymbolKey.Create(symbol, cancellationToken); var currentCompilation = currentProject.GetCompilationAsync(cancellationToken).WaitAndGetResult(cancellationToken); var symbolInfo = symbolId.Resolve(currentCompilation, cancellationToken: cancellationToken); if (symbolInfo.Symbol == null) { return(false); } resolvedSymbol = symbolInfo.Symbol; resolvedProject = currentProject; return(true); }
internal static void AssertSymbolKeysEqual(ISymbol symbol1, ISymbol symbol2, SymbolKeyComparison comparison, bool expectEqual = true) { var sid1 = SymbolKey.Create(symbol1, CancellationToken.None); var sid2 = SymbolKey.Create(symbol2, CancellationToken.None); // default is Insensitive var ignoreCase = (comparison & SymbolKeyComparison.IgnoreCase) == SymbolKeyComparison.IgnoreCase; // default is NOT ignore var ignoreAssemblyIds = (comparison & SymbolKeyComparison.IgnoreAssemblyIds) == SymbolKeyComparison.IgnoreAssemblyIds; var message = string.Concat( ignoreCase ? "SymbolID IgnoreCase" : "SymbolID", ignoreAssemblyIds ? " IgnoreAssemblyIds " : " ", "Compare"); var ret = CodeAnalysis.SymbolKey.GetComparer(ignoreCase, ignoreAssemblyIds).Equals(sid2, sid1); if (expectEqual) { Assert.True(ret, message); } else { Assert.False(ret, message); } }
public async Task <IEnumerable <IPeekableItem> > GetPeekableItemsAsync(ISymbol symbol, Project project, IPeekResultFactory peekResultFactory, CancellationToken cancellationToken) { if (symbol == null) { throw new ArgumentNullException(nameof(symbol)); } if (project == null) { throw new ArgumentNullException(nameof(project)); } if (peekResultFactory == null) { throw new ArgumentNullException(nameof(peekResultFactory)); } var results = new List <IPeekableItem>(); var solution = project.Solution; var sourceDefinition = await SymbolFinder.FindSourceDefinitionAsync(symbol, solution, cancellationToken).ConfigureAwait(false); // And if our definition actually is from source, then let's re-figure out what project it came from if (sourceDefinition != null) { var originatingProject = solution.GetProject(sourceDefinition.ContainingAssembly, cancellationToken); project = originatingProject ?? project; } string filePath; int lineNumber; int charOffset; var symbolNavigationService = solution.Workspace.Services.GetService <ISymbolNavigationService>(); if (symbolNavigationService.WouldNavigateToSymbol(symbol, solution, out filePath, out lineNumber, out charOffset)) { var position = new LinePosition(lineNumber, charOffset); results.Add(new ExternalFilePeekableItem(new FileLinePositionSpan(filePath, position, position), PredefinedPeekRelationships.Definitions, peekResultFactory)); } else { var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); var symbolKey = SymbolKey.Create(symbol, compilation, cancellationToken); var firstLocation = symbol.Locations.FirstOrDefault(); if (firstLocation != null) { if (firstLocation.IsInSource || _metadataAsSourceFileService.IsNavigableMetadataSymbol(symbol)) { results.Add(new DefinitionPeekableItem(solution.Workspace, project.Id, symbolKey, peekResultFactory, _metadataAsSourceFileService)); } } } return(results); }
public async Task <IEnumerable <IPeekableItem> > GetPeekableItemsAsync( ISymbol symbol, Project project, IPeekResultFactory peekResultFactory, CancellationToken cancellationToken) { if (symbol == null) { throw new ArgumentNullException(nameof(symbol)); } if (project == null) { throw new ArgumentNullException(nameof(project)); } if (peekResultFactory == null) { throw new ArgumentNullException(nameof(peekResultFactory)); } var results = new List <IPeekableItem>(); var solution = project.Solution; var sourceDefinition = await SymbolFinder.FindSourceDefinitionAsync(symbol, solution, cancellationToken).ConfigureAwait(false); // And if our definition actually is from source, then let's re-figure out what project it came from if (sourceDefinition != null) { var originatingProject = solution.GetProject(sourceDefinition.ContainingAssembly, cancellationToken); project = originatingProject ?? project; } var symbolNavigationService = solution.Workspace.Services.GetService <ISymbolNavigationService>(); var definitionItem = symbol.ToNonClassifiedDefinitionItem(solution, includeHiddenLocations: true); var result = await symbolNavigationService.GetExternalNavigationSymbolLocationAsync(definitionItem, cancellationToken).ConfigureAwait(false); if (result is var(filePath, linePosition)) { results.Add(new ExternalFilePeekableItem(new FileLinePositionSpan(filePath, linePosition, linePosition), PredefinedPeekRelationships.Definitions, peekResultFactory)); } else { var symbolKey = SymbolKey.Create(symbol, cancellationToken); var firstLocation = symbol.Locations.FirstOrDefault(); if (firstLocation != null) { if (firstLocation.IsInSource || _metadataAsSourceFileService.IsNavigableMetadataSymbol(symbol)) { results.Add(new DefinitionPeekableItem(solution.Workspace, project.Id, symbolKey, peekResultFactory, _metadataAsSourceFileService, _globalOptions)); } } } return(results); }
private bool CanResolveSymbolKey(ISymbol m, Compilation compilation) { // SymbolKey doesn't guarantee roundtrip-ability, which we need in order to generate overrides. // Preemptively filter out those methods whose SymbolKeys we won't be able to round trip. var key = SymbolKey.Create(m, _cancellationToken); var result = key.Resolve(compilation, cancellationToken: _cancellationToken); return(result.Symbol != null); }
private static bool IsCompatible <TExpressionSyntax>( ISemanticFactsService semanticFacts, SemanticModel semanticModel, IMethodSymbol constructor, ImmutableArray <TExpressionSyntax?> expressions) where TExpressionSyntax : SyntaxNode { Debug.Assert(constructor.Parameters.Length == expressions.Length); // Resolve the constructor into our semantic model's compilation; if the constructor we're looking at is from // another project with a different language. var constructorInCompilation = (IMethodSymbol?)SymbolKey.Create(constructor).Resolve(semanticModel.Compilation).Symbol; if (constructorInCompilation == null) { // If the constructor can't be mapped into our invocation project, we'll just bail. // Note the logic in this method doesn't handle a complicated case where: // // 1. Project A has some public type. // 2. Project B references A, and has one constructor that uses the public type from A. // 3. Project C, which references B but not A, has an invocation of B's constructor passing some // parameters. // // The algorithm of this class tries to map the constructor in B (that we might delegate to) into // C, but that constructor might not be mappable if the public type from A is not available. // However, theoretically the public type from A could have a user-defined conversion. // The alternative approach might be to map the type of the parameters back into B, and then // classify the conversions in Project B, but that'll run into other issues if the experssions // don't have a natural type (like default). We choose to ignore all complicated cases here. return(false); } for (var i = 0; i < constructorInCompilation.Parameters.Length; i++) { var constructorParameter = constructorInCompilation.Parameters[i]; if (constructorParameter == null) { return(false); } // In VB the argument may not have been specified at all if the parameter is optional if (expressions[i] is null && constructorParameter.IsOptional) { continue; } var conversion = semanticFacts.ClassifyConversion(semanticModel, expressions[i], constructorParameter.Type); if (!conversion.IsIdentity && !conversion.IsImplicit) { return(false); } } return(true); }
public async Task <SymbolMappingResult?> MapSymbolAsync( Document document, ISymbol symbol, CancellationToken cancellationToken ) { return(await MapSymbolAsync( document, SymbolKey.Create(symbol, cancellationToken), cancellationToken ) .ConfigureAwait(false)); }
public async Task TestGetInteriorSymbolsDoesNotCrashOnSpeculativeSemanticModel() { var markup = @" class C { void foo() { System.Func<int> lambda = () => { int x; $$ } } }"; int position; string text; MarkupTestFile.GetPosition(markup, out text, out position); var sourceText = SourceText.From(text); var workspace = new AdhocWorkspace(); var project = workspace.AddProject("Test", LanguageNames.CSharp); var document = workspace.AddDocument(project.Id, "testdocument", sourceText); var firstModel = await document.GetSemanticModelAsync(); var tree1 = await document.GetSyntaxTreeAsync(); var basemethod1 = tree1.FindTokenOnLeftOfPosition(position, CancellationToken.None).GetAncestor <CSharp.Syntax.BaseMethodDeclarationSyntax>(); // Modify the document so we can use the old semantic model as a base. var updated = sourceText.WithChanges(new TextChange(new TextSpan(position, 0), "insertion")); workspace.TryApplyChanges(document.WithText(updated).Project.Solution); document = workspace.CurrentSolution.GetDocument(document.Id); var tree2 = await document.GetSyntaxTreeAsync(); var basemethod2 = tree2.FindTokenOnLeftOfPosition(position, CancellationToken.None).GetAncestor <CSharp.Syntax.BaseMethodDeclarationSyntax>(); var service = new CSharp.CSharpSemanticFactsService(); SemanticModel testModel; var m = service.TryGetSpeculativeSemanticModel(firstModel, basemethod1, basemethod2, out testModel); var xSymbol = testModel.LookupSymbols(position).First(s => s.Name == "x"); // This should not throw an exception. Assert.NotNull(SymbolKey.Create(xSymbol)); }
public void C2CTypeSymbolChanged02() { var src1 = @"using System; namespace NS { public class C1 { public void M() {} } } "; var src2 = @" namespace NS { internal class C1 // add new C1 { public string P { get; set; } } public class C2 // rename C1 to C2 { public void M() {} } } "; var comp1 = (Compilation)CreateCompilation(src1, assemblyName: "Test"); var comp2 = (Compilation)CreateCompilation(src2, assemblyName: "Test"); var namespace1 = comp1.SourceModule.GlobalNamespace.GetMembers("NS").Single() as INamespaceSymbol; var typeSym00 = namespace1.GetTypeMembers("C1").FirstOrDefault() as INamedTypeSymbol; var namespace2 = comp2.SourceModule.GlobalNamespace.GetMembers("NS").Single() as INamespaceSymbol; var typeSym01 = namespace2.GetTypeMembers("C1").FirstOrDefault() as INamedTypeSymbol; var typeSym02 = namespace2.GetTypeMembers("C2").Single() as INamedTypeSymbol; // new C1 resolve to old C1 ResolveAndVerifySymbol(typeSym01, typeSym00, comp1); // old C1 (new C2) NOT resolve to old C1 var symkey = SymbolKey.Create(typeSym02, CancellationToken.None); var syminfo = symkey.Resolve(comp1); Assert.Null(syminfo.Symbol); }
internal static ISymbol ResolveSymbol(ISymbol originalSymbol, Compilation targetCompilation, SymbolKeyComparison comparison) { var sid = SymbolKey.Create(originalSymbol, CancellationToken.None); // Verify that serialization works. var serialized = sid.ToString(); var deserialized = new SymbolKey(serialized); var comparer = SymbolKey.GetComparer(ignoreCase: false, ignoreAssemblyKeys: false); Assert.True(comparer.Equals(sid, deserialized)); var symInfo = sid.Resolve(targetCompilation, (comparison & SymbolKeyComparison.IgnoreAssemblyIds) == SymbolKeyComparison.IgnoreAssemblyIds); return(symInfo.Symbol); }
public static async ValueTask <ValueTrackedItem?> TryCreateAsync(Solution solution, Location location, ISymbol symbol, ValueTrackedItem?parent = null, CancellationToken cancellationToken = default) { Contract.ThrowIfNull(location.SourceTree); var document = solution.GetRequiredDocument(location.SourceTree); var syntaxTree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var sourceText = await syntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false); return(new ValueTrackedItem( SymbolKey.Create(symbol, cancellationToken), sourceText, location.SourceSpan, document.Id, symbol.GetGlyph(), parent)); }
public static async Task <ValueTrackedItem?> TryCreateAsync(Document document, TextSpan textSpan, ISymbol symbol, ValueTrackedItem?parent = null, CancellationToken cancellationToken = default) { var excerptService = document.Services.GetService <IDocumentExcerptService>(); SourceText?sourceText = null; ImmutableArray <ClassifiedSpan> classifiedSpans = default; if (excerptService != null) { var result = await excerptService.TryExcerptAsync(document, textSpan, ExcerptMode.SingleLine, cancellationToken).ConfigureAwait(false); if (result.HasValue) { var value = result.Value; sourceText = value.Content; } } if (sourceText is null) { var options = ClassificationOptions.From(document.Project); var documentSpan = await ClassifiedSpansAndHighlightSpanFactory.GetClassifiedDocumentSpanAsync(document, textSpan, options, cancellationToken).ConfigureAwait(false); var classificationResult = await ClassifiedSpansAndHighlightSpanFactory.ClassifyAsync(documentSpan, options, cancellationToken).ConfigureAwait(false); classifiedSpans = classificationResult.ClassifiedSpans; var syntaxTree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); sourceText = await syntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false); } return(new ValueTrackedItem( SymbolKey.Create(symbol, cancellationToken), sourceText, classifiedSpans, textSpan, document.Id, symbol.GetGlyph(), parent: parent)); }
public override async Task <bool> TryGoToDefinitionAsync( ISymbol symbol, Project project, CancellationToken cancellationToken) { var currentProject = project.Solution.Workspace.CurrentSolution.GetProject(project.Id); if (currentProject == null) { return(false); } var symbolId = SymbolKey.Create(symbol, cancellationToken); var currentCompilation = await currentProject.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); var symbolInfo = symbolId.Resolve(currentCompilation, cancellationToken: cancellationToken); if (symbolInfo.Symbol == null) { return(false); } return(await GoToDefinitionHelpers.TryNavigateToLocationAsync( symbolInfo.Symbol, currentProject.Solution, _threadingContext, _streamingPresenter.Value, cancellationToken).ConfigureAwait(false)); }
public async Task <MetadataAsSourceFile> GetGeneratedFileAsync(Project project, ISymbol symbol, bool allowDecompilation, CancellationToken cancellationToken = default) { if (project == null) { throw new ArgumentNullException(nameof(project)); } if (symbol == null) { throw new ArgumentNullException(nameof(symbol)); } if (symbol.Kind == SymbolKind.Namespace) { throw new ArgumentException(EditorFeaturesResources.symbol_cannot_be_a_namespace, nameof(symbol)); } symbol = symbol.GetOriginalUnreducedDefinition(); MetadataAsSourceGeneratedFileInfo fileInfo; Location navigateLocation = null; var topLevelNamedType = MetadataAsSourceHelpers.GetTopLevelContainingNamedType(symbol); var symbolId = SymbolKey.Create(symbol, cancellationToken); using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { InitializeWorkspace(project); var infoKey = await GetUniqueDocumentKey(project, topLevelNamedType, cancellationToken).ConfigureAwait(false); fileInfo = _keyToInformation.GetOrAdd(infoKey, _ => new MetadataAsSourceGeneratedFileInfo(GetRootPathWithGuid_NoLock(), project, topLevelNamedType)); _generatedFilenameToInformation[fileInfo.TemporaryFilePath] = fileInfo; if (!File.Exists(fileInfo.TemporaryFilePath)) { // We need to generate this. First, we'll need a temporary project to do the generation into. We // avoid loading the actual file from disk since it doesn't exist yet. var temporaryProjectInfoAndDocumentId = fileInfo.GetProjectInfoAndDocumentId(_workspace, loadFileFromDisk: false); var temporaryDocument = _workspace.CurrentSolution.AddProject(temporaryProjectInfoAndDocumentId.Item1) .GetDocument(temporaryProjectInfoAndDocumentId.Item2); var useDecompiler = allowDecompilation; if (useDecompiler) { try { temporaryDocument = await DecompileSymbolAsync(temporaryDocument, symbol, cancellationToken).ConfigureAwait(false); } catch (Exception e) when(FatalError.ReportWithoutCrashUnlessCanceled(e)) { useDecompiler = false; } } if (!useDecompiler) { var sourceFromMetadataService = temporaryDocument.Project.LanguageServices.GetService <IMetadataAsSourceService>(); temporaryDocument = await sourceFromMetadataService.AddSourceToAsync(temporaryDocument, symbol, cancellationToken).ConfigureAwait(false); } // We have the content, so write it out to disk var text = await temporaryDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); // Create the directory. It's possible a parallel deletion is happening in another process, so we may have // to retry this a few times. var directoryToCreate = Path.GetDirectoryName(fileInfo.TemporaryFilePath); while (!Directory.Exists(directoryToCreate)) { try { Directory.CreateDirectory(directoryToCreate); } catch (DirectoryNotFoundException) { } catch (UnauthorizedAccessException) { } } using (var textWriter = new StreamWriter(fileInfo.TemporaryFilePath, append: false, encoding: fileInfo.Encoding)) { text.Write(textWriter); } // Mark read-only new FileInfo(fileInfo.TemporaryFilePath).IsReadOnly = true; // Locate the target in the thing we just created navigateLocation = await MetadataAsSourceHelpers.GetLocationInGeneratedSourceAsync(symbolId, temporaryDocument, cancellationToken).ConfigureAwait(false); } // If we don't have a location yet, then that means we're re-using an existing file. In this case, we'll want to relocate the symbol. if (navigateLocation == null) { navigateLocation = await RelocateSymbol_NoLock(fileInfo, symbolId, cancellationToken).ConfigureAwait(false); } } var documentName = string.Format( "{0} [{1}]", topLevelNamedType.Name, EditorFeaturesResources.from_metadata); var documentTooltip = topLevelNamedType.ToDisplayString(new SymbolDisplayFormat(typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces)); return(new MetadataAsSourceFile(fileInfo.TemporaryFilePath, navigateLocation, documentName, documentTooltip)); }
private async Task <UniqueDocumentKey> GetUniqueDocumentKey(Project project, INamedTypeSymbol topLevelNamedType, CancellationToken cancellationToken) { var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); var peMetadataReference = compilation.GetMetadataReference(topLevelNamedType.ContainingAssembly) as PortableExecutableReference; if (peMetadataReference.FilePath != null) { return(new UniqueDocumentKey(peMetadataReference.FilePath, project.Language, SymbolKey.Create(topLevelNamedType, cancellationToken))); } else { return(new UniqueDocumentKey(topLevelNamedType.ContainingAssembly.Identity, project.Language, SymbolKey.Create(topLevelNamedType, cancellationToken))); } }
public async Task <SymbolMappingResult> MapSymbolAsync(Document document, ISymbol symbol, CancellationToken cancellationToken) { var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); return(await MapSymbolAsync(document, SymbolKey.Create(symbol, cancellationToken), cancellationToken).ConfigureAwait(false)); }
public async Task <SignatureHelpItems?> GetItemsAsync( Document document, int position, SignatureHelpTriggerInfo triggerInfo, SignatureHelpOptions options, CancellationToken cancellationToken) { var itemsForCurrentDocument = await GetItemsWorkerAsync(document, position, triggerInfo, options, cancellationToken).ConfigureAwait(false); if (itemsForCurrentDocument == null) { return(itemsForCurrentDocument); } var relatedDocuments = await FindActiveRelatedDocumentsAsync(position, document, cancellationToken).ConfigureAwait(false); if (relatedDocuments.IsEmpty) { return(itemsForCurrentDocument); } var totalProjects = relatedDocuments.Select(d => d.Project.Id).Concat(document.Project.Id); var semanticModel = await document.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false); var compilation = semanticModel.Compilation; var finalItems = new List <SignatureHelpItem>(); foreach (var item in itemsForCurrentDocument.Items) { if (item is not SymbolKeySignatureHelpItem symbolKeyItem || symbolKeyItem.SymbolKey is not SymbolKey symbolKey || symbolKey.Resolve(compilation, ignoreAssemblyKey: true, cancellationToken).Symbol is not ISymbol symbol) { finalItems.Add(item); continue; } // If the symbol is an instantiated generic method, ensure we use its original // definition for symbol key resolution in related compilations. if (symbol is IMethodSymbol methodSymbol && methodSymbol.IsGenericMethod && methodSymbol != methodSymbol.OriginalDefinition) { symbolKey = SymbolKey.Create(methodSymbol.OriginalDefinition, cancellationToken); } var invalidProjectsForCurrentSymbol = new List <ProjectId>(); foreach (var relatedDocument in relatedDocuments) { // Try to resolve symbolKey in each related compilation, // unresolvable key means the symbol is unavailable in the corresponding project. var relatedSemanticModel = await relatedDocument.ReuseExistingSpeculativeModelAsync(position, cancellationToken).ConfigureAwait(false); if (symbolKey.Resolve(relatedSemanticModel.Compilation, ignoreAssemblyKey: true, cancellationToken).Symbol == null) { invalidProjectsForCurrentSymbol.Add(relatedDocument.Project.Id); } } var platformData = new SupportedPlatformData(document.Project.Solution, invalidProjectsForCurrentSymbol, totalProjects); finalItems.Add(UpdateItem(item, platformData)); } return(new SignatureHelpItems( finalItems, itemsForCurrentDocument.ApplicableSpan, itemsForCurrentDocument.ArgumentIndex, itemsForCurrentDocument.ArgumentCount, itemsForCurrentDocument.ArgumentName, itemsForCurrentDocument.SelectedItemIndex)); }
private async Task <UniqueDocumentKey> GetUniqueDocumentKeyAsync(Project project, INamedTypeSymbol topLevelNamedType, bool allowDecompilation, CancellationToken cancellationToken) { var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); Contract.ThrowIfNull(compilation, "We are trying to produce a key for a language that doesn't support compilations."); var peMetadataReference = compilation.GetMetadataReference(topLevelNamedType.ContainingAssembly) as PortableExecutableReference; if (peMetadataReference?.FilePath != null) { return(new UniqueDocumentKey(peMetadataReference.FilePath, peMetadataReference.GetMetadataId(), project.Language, SymbolKey.Create(topLevelNamedType, cancellationToken), allowDecompilation)); } else { var containingAssembly = topLevelNamedType.ContainingAssembly; return(new UniqueDocumentKey(containingAssembly.Identity, containingAssembly.GetMetadata()?.Id, project.Language, SymbolKey.Create(topLevelNamedType, cancellationToken), allowDecompilation)); } }
public static Task <Location> GetLocationInGeneratedSourceAsync(ISymbol symbol, Document generatedDocument, CancellationToken cancellationToken) { var symbolKey = SymbolKey.Create(symbol, cancellationToken); return(MetadataAsSourceHelpers.GetLocationInGeneratedSourceAsync(symbolKey, generatedDocument, cancellationToken)); }
public static string GetSymbolKeyString( this ISymbol symbol, CancellationToken cancellationToken ) => SymbolKey.Create(symbol, cancellationToken).ToString();