public int GetIndexForSymbolId(SymbolKey id) { int nextId; _nextIds.TryGetValue(id, out nextId); _nextIds[id] = nextId + 1; return nextId; }
private CodeTypeRef(CodeModelState state, object parent, ProjectId projectId, ITypeSymbol typeSymbol) : base(state) { _parentHandle = new ParentHandle<object>(parent); _projectId = projectId; _symbolId = typeSymbol.GetSymbolKey(); }
private ExternalNamespaceEnumerator(CodeModelState state, ProjectId projectId, SymbolKey namespaceSymbolId) { _state = state; _projectId = projectId; _namespaceSymbolId = namespaceSymbolId; _childEnumerator = ChildrenOfNamespace(state, projectId, namespaceSymbolId).GetEnumerator(); }
protected AbstractCallFinder(ISymbol symbol, Project project, IAsynchronousOperationListener asyncListener, CallHierarchyProvider provider) { _asyncListener = asyncListener; _symbol = symbol.GetSymbolKey(); this.SymbolName = symbol.Name; _project = project; this.Provider = provider; }
public Task<SymbolMappingResult> MapSymbolAsync(Document document, SymbolKey symbolId, CancellationToken cancellationToken) { var workspace = document.Project.Solution.Workspace as MetadataAsSourceWorkspace; if (workspace == null) { throw new ArgumentException(EditorFeaturesResources.DocumentMustBeContainedInWorkspace, nameof(document)); } return workspace.FileService.MapSymbolAsync(document, symbolId, cancellationToken); }
public MetadataDefinitionTreeItem(Workspace workspace, ISymbol definition, ProjectId referencingProjectId, ushort glyphIndex) : base(glyphIndex) { _workspace = workspace; _referencingProjectId = referencingProjectId; _symbolKey = definition.GetSymbolKey(); _assemblyName = definition.ContainingAssembly.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat); _symbolDefinition = definition.ToDisplayString(definitionDisplayFormat); this.DisplayText = $"[{_assemblyName}] {_symbolDefinition}"; }
public DefinitionPeekableItem( Workspace workspace, ProjectId projectId, SymbolKey symbolKey, IPeekResultFactory peekResultFactory, IMetadataAsSourceFileService metadataAsSourceService) : base(peekResultFactory) { _workspace = workspace; _projectId = projectId; _symbolKey = symbolKey; _metadataAsSourceFileService = metadataAsSourceService; }
public async Task<SymbolMappingResult> MapSymbolAsync(Document document, SymbolKey symbolId, CancellationToken cancellationToken) { var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); var symbol = symbolId.Resolve(compilation, cancellationToken: cancellationToken).Symbol; if (symbol != null) { return new SymbolMappingResult(document.Project, symbol); } return null; }
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 CallHierarchyItem(ISymbol symbol, ProjectId projectId, IEnumerable<AbstractCallFinder> finders, Func<ImageSource> glyphCreator, CallHierarchyProvider provider, IEnumerable<Location> callsites, Workspace workspace) { _symbolId = symbol.GetSymbolKey(); _projectId = projectId; _finders = finders; _containingTypeName = symbol.ContainingType.ToDisplayString(ContainingTypeFormat); _containingNamespaceName = symbol.ContainingNamespace.ToDisplayString(ContainingNamespaceFormat); _glyphCreator = glyphCreator; _name = symbol.ToDisplayString(MemberNameFormat); _provider = provider; _callsites = callsites.Select(l => new CallHierarchyDetail(l, workspace)); _sortText = symbol.ToDisplayString(); _workspace = workspace; }
public MetadataDefinitionItem( ImmutableArray<string> tags, ImmutableArray<TaggedText> displayParts, bool displayIfNoReferences, Solution solution, ISymbol definition) : base(tags, displayParts, GetOriginationParts(definition), ImmutableArray<DocumentLocation>.Empty, displayIfNoReferences) { _workspace = solution.Workspace; _symbolKey = definition.GetSymbolKey(); _symbolAssemblyIdentity = definition.ContainingAssembly?.Identity; }
public NavigationBarSymbolItem( string text, Glyph glyph, IList<TextSpan> spans, SymbolKey navigationSymbolId, int? navigationSymbolIndex, IList<NavigationBarItem> childItems = null, int indent = 0, bool bolded = false, bool grayed = false) : base(text, glyph, spans, childItems, indent, bolded, grayed) { this.NavigationSymbolId = navigationSymbolId; this.NavigationSymbolIndex = navigationSymbolIndex; }
protected SymbolListItem(ProjectId projectId, ISymbol symbol, string displayText, string fullNameText, string searchText, bool isHidden) : base(projectId, symbol.GetStandardGlyphGroup(), symbol.GetStandardGlyphItem(), isHidden) { _symbolKey = symbol.GetSymbolKey(); _accessibility = symbol.DeclaredAccessibility; _displayText = displayText; _fullNameText = fullNameText; _searchText = searchText; _supportsGoToDefinition = symbol.Kind != SymbolKind.Namespace ? symbol.Locations.Any(l => l.IsInSource) : false; _supportsFindAllReferences = symbol.Kind != SymbolKind.Namespace; }
public MemberInsertionCompletionItem( CompletionListProvider provider, string displayText, TextSpan filterSpan, Func<CancellationToken, Task<ImmutableArray<SymbolDisplayPart>>> descriptionFactory, Glyph? glyph, DeclarationModifiers modifiers, int line, SymbolKey symbolId, SyntaxToken token) : base(provider, displayText, filterSpan, descriptionFactory, glyph) { this.Modifiers = modifiers; this.Line = line; this.SymbolId = symbolId; this.Token = token; }
public static async Task<Location> GetLocationInGeneratedSourceAsync(SymbolKey symbolId, Document generatedDocument, CancellationToken cancellationToken) { var location = symbolId.Resolve( await generatedDocument.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false), ignoreAssemblyKey: true, cancellationToken: cancellationToken) .GetAllSymbols() .Select(s => s.Locations.Where(loc => loc.IsInSource).FirstOrDefault()) .WhereNotNull() .FirstOrDefault(); if (location == null) { // If we cannot find the symbol, then put the caret at the beginning of the file. var tree = await generatedDocument.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); location = Location.Create(tree, new TextSpan(0, 0)); } return location; }
private void NavigateOnForegroundThread(SourceLocation sourceLocation, SymbolKey? symbolId, Project project, Document document) { AssertIsForeground(); // Notify of navigation so third parties can intercept the navigation if (symbolId != null) { var symbolNavigationService = _workspace.Services.GetService<ISymbolNavigationService>(); var symbol = symbolId.Value.Resolve(project.GetCompilationAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None)).Symbol; // Do not allow third party navigation to types or constructors if (symbol != null && !(symbol is ITypeSymbol) && !symbol.IsConstructor() && symbolNavigationService.TrySymbolNavigationNotify(symbol, project.Solution)) { return; } } if (sourceLocation.IsValid) { // We must find the right document in this project. This may not be the // ContextDocumentId if you have a partial member that is shown under one // document, but only exists in the other if (document != null) { var editorWorkspace = document.Project.Solution.Workspace; var navigationService = editorWorkspace.Services.GetService<IDocumentNavigationService>(); navigationService.TryNavigateToLineAndOffset( editorWorkspace, document.Id, sourceLocation.StartPosition.Line, sourceLocation.StartPosition.Character); } } }
internal static IEnumerable<EnvDTE.CodeElement> ChildrenOfNamespace(CodeModelState state, ProjectId projectId, SymbolKey namespaceSymbolId) { var project = state.Workspace.CurrentSolution.GetProject(projectId); if (project == null) { throw Exceptions.ThrowEFail(); } var namespaceSymbol = namespaceSymbolId.Resolve(project.GetCompilationAsync().Result).Symbol as INamespaceSymbol; if (namespaceSymbol == null) { throw Exceptions.ThrowEFail(); } var containingAssembly = project.GetCompilationAsync().Result.Assembly; foreach (var child in namespaceSymbol.GetMembers()) { if (child is INamespaceSymbol) { yield return (EnvDTE.CodeElement)ExternalCodeNamespace.Create(state, projectId, (INamespaceSymbol)child); } else { var namedType = (INamedTypeSymbol)child; if (namedType.IsAccessibleWithin(containingAssembly)) { if (namedType.Locations.Any(l => l.IsInMetadata || l.IsInSource)) { yield return state.CodeModelService.CreateCodeType(state, projectId, namedType); } } } } }
private static ImmutableArray <SerializableImportCompletionItem> ConvertSymbolsToCompletionItems( Compilation compilation, ImmutableArray <IMethodSymbol> extentsionMethodSymbols, ImmutableArray <ITypeSymbol> targetTypeSymbols, CancellationToken cancellationToken) { Dictionary <ITypeSymbol, bool> typeConvertibilityCache = new(); using var _1 = PooledDictionary <INamespaceSymbol, string> .GetInstance(out var namespaceNameCache); using var _2 = PooledDictionary <(string containingNamespace, string methodName, bool isGeneric), (IMethodSymbol bestSymbol, int overloadCount, bool includeInTargetTypedCompletion)> .GetInstance(out var overloadMap); // Aggregate overloads foreach (var symbol in extentsionMethodSymbols) { cancellationToken.ThrowIfCancellationRequested(); IMethodSymbol bestSymbol; int overloadCount; var includeInTargetTypedCompletion = ShouldIncludeInTargetTypedCompletion(compilation, symbol, targetTypeSymbols, typeConvertibilityCache); var containingNamespacename = GetFullyQualifiedNamespaceName(symbol.ContainingNamespace, namespaceNameCache); var overloadKey = (containingNamespacename, symbol.Name, isGeneric : symbol.Arity > 0); // Select the overload convertible to any targeted type (if any) and with minimum number of parameters to display if (overloadMap.TryGetValue(overloadKey, out var currentValue)) { if (currentValue.includeInTargetTypedCompletion == includeInTargetTypedCompletion) { bestSymbol = currentValue.bestSymbol.Parameters.Length > symbol.Parameters.Length ? symbol : currentValue.bestSymbol; } else if (currentValue.includeInTargetTypedCompletion) { bestSymbol = currentValue.bestSymbol; } else { bestSymbol = symbol; } overloadCount = currentValue.overloadCount + 1; includeInTargetTypedCompletion = includeInTargetTypedCompletion || currentValue.includeInTargetTypedCompletion; } else { bestSymbol = symbol; overloadCount = 1; } overloadMap[overloadKey] = (bestSymbol, overloadCount, includeInTargetTypedCompletion); } // Then convert symbols into completion items using var _3 = ArrayBuilder <SerializableImportCompletionItem> .GetInstance(out var itemsBuilder); foreach (var((containingNamespace, _, _), (bestSymbol, overloadCount, includeInTargetTypedCompletion)) in overloadMap) { // To display the count of additional overloads, we need to subtract total by 1. var item = new SerializableImportCompletionItem( SymbolKey.CreateString(bestSymbol, cancellationToken), bestSymbol.Name, bestSymbol.Arity, bestSymbol.GetGlyph(), containingNamespace, additionalOverloadCount: overloadCount - 1, includeInTargetTypedCompletion); itemsBuilder.Add(item); } return(itemsBuilder.ToImmutable()); }
private static async Task <ImmutableArray <TaggedText> > GetDescriptionAsync(Document document, int position, SymbolKey symbolKey, SymbolDescriptionOptions options, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var symbol = symbolKey.Resolve(semanticModel.Compilation, cancellationToken: cancellationToken).Symbol; if (symbol != null) { var symbolDisplayService = document.GetRequiredLanguageService <ISymbolDisplayService>(); var parts = new List <TaggedText>(); var groups = await symbolDisplayService.ToDescriptionGroupsAsync( semanticModel, position, ImmutableArray.Create(symbol), options, cancellationToken).ConfigureAwait(false); parts.AddRange(groups[SymbolDescriptionGroups.MainDescription]); var formatter = document.GetRequiredLanguageService <IDocumentationCommentFormattingService>(); var documentation = symbol.GetDocumentationParts(semanticModel, position, formatter, cancellationToken); if (documentation.Any()) { parts.AddLineBreak(); parts.AddRange(documentation); } if (groups.TryGetValue(SymbolDescriptionGroups.StructuralTypes, out var anonymousTypes)) { if (!anonymousTypes.IsDefaultOrEmpty) { parts.AddLineBreak(); parts.AddLineBreak(); parts.AddRange(anonymousTypes); } } return(parts.ToImmutableArray()); } return(default);
public UniqueDocumentKey(string filePath, MetadataId?metadataId, string language, SymbolKey symbolId, bool signaturesOnly) { Contract.ThrowIfNull(filePath); _filePath = filePath; _metadataId = metadataId; _language = language; _symbolId = symbolId; _signaturesOnly = signaturesOnly; }
internal ExternalNamespaceCollection(CodeModelState state, object parent, ProjectId projectId, INamespaceSymbol namespaceSymbol) : base(state, parent) { _projectId = projectId; _namespaceSymbolId = namespaceSymbol.GetSymbolKey(); }
public async Task <SignatureHelpItems?> GetItemsAsync( Document document, int position, SignatureHelpTriggerInfo triggerInfo, CancellationToken cancellationToken) { var itemsForCurrentDocument = await GetItemsWorkerAsync(document, position, triggerInfo, 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(invalidProjectsForCurrentSymbol, totalProjects, document.Project.Solution.Workspace); finalItems.Add(UpdateItem(item, platformData)); } return(new SignatureHelpItems( finalItems, itemsForCurrentDocument.ApplicableSpan, itemsForCurrentDocument.ArgumentIndex, itemsForCurrentDocument.ArgumentCount, itemsForCurrentDocument.ArgumentName, itemsForCurrentDocument.SelectedItemIndex)); }
public static InlineParameterNameHintsTag Create(string text, double lineHeight, TextFormattingRunProperties format, ITextView textView, SnapshotSpan span, SymbolKey key, InlineParameterNameHintsTaggerProvider taggerProvider) { return(new InlineParameterNameHintsTag(CreateElement(text, lineHeight, format), textView, span, key, taggerProvider)); }
public static string EncodeSymbol(ISymbol symbol) { return(SymbolKey.CreateString(symbol)); }
fields.Select(f => SymbolKey.CreateString(f, cancellationToken)).ToArray(),
private static ISymbol DecodeSymbol(string id, Compilation compilation) { return(SymbolKey.ResolveString(id, compilation).GetAnySymbol()); }
public static async Task <(ImmutableArray <SerializableImportCompletionItem>, StatisticCounter)> GetUnimportedExtensionMethodsInRemoteProcessAsync( RemoteHostClient client, Document document, int position, ITypeSymbol receiverTypeSymbol, ISet <string> namespaceInScope, bool forceIndexCreation, CancellationToken cancellationToken) { var project = document.Project; var(serializableItems, counter) = (await client.TryRunCodeAnalysisRemoteValueAsync <(IList <SerializableImportCompletionItem>, StatisticCounter)>( project.Solution, nameof(IRemoteExtensionMethodImportCompletionService.GetUnimportedExtensionMethodsAsync), new object[] { document.Id, position, SymbolKey.CreateString(receiverTypeSymbol), namespaceInScope.ToArray(), forceIndexCreation }, cancellationToken).ConfigureAwait(false)).GetValueOrDefault(); return(serializableItems.ToImmutableArray(), counter); }
private ExternalMemberCollection(CodeModelState state, object parent, ProjectId projectId, ITypeSymbol typeSymbol) : base(state, parent) { _projectId = projectId; _typeSymbolId = typeSymbol.GetSymbolKey(); }
private static bool TryGetDependentTypes(ConditionalWeakTable<Compilation, ConcurrentDictionary<SymbolKey, List<SymbolKey>>> cache, Compilation compilation, SymbolKey typeId, out List<SymbolKey> dependentTypeIds) { dependentTypeIds = null; ConcurrentDictionary<SymbolKey, List<SymbolKey>> dictionary; return cache.TryGetValue(compilation, out dictionary) && dictionary.TryGetValue(typeId, out dependentTypeIds); }
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 static string EncodeSymbol(ISymbol symbol) => SymbolKey.CreateString(symbol);
public UniqueDocumentKey(AssemblyIdentity assemblyIdentity, string language, SymbolKey symbolId) { Contract.ThrowIfNull(assemblyIdentity); _assemblyIdentity = assemblyIdentity; _language = language; _symbolId = symbolId; }
internal static IEnumerator Create(CodeModelState state, ProjectId projectId, SymbolKey namespaceSymbolId) { var newEnumerator = new ExternalNamespaceEnumerator(state, projectId, namespaceSymbolId); return((IEnumerator)ComAggregate.CreateAggregatedObject(newEnumerator)); }
public void NavigateTo(SymbolKey id, Project project, CancellationToken cancellationToken) { var compilation = project.GetCompilationAsync(cancellationToken).WaitAndGetResult(cancellationToken); var resolution = id.Resolve(compilation, cancellationToken: cancellationToken); project.Solution.Workspace.Services.GetService<ISymbolNavigationService>().TryNavigateToSymbol(resolution.Symbol, project, usePreviewTab: true, cancellationToken: cancellationToken); }
public static Task <Location> GetLocationInGeneratedSourceAsync(ISymbol symbol, Document generatedDocument, CancellationToken cancellationToken) { var symbolKey = SymbolKey.Create(symbol, cancellationToken); return(MetadataAsSourceHelpers.GetLocationInGeneratedSourceAsync(symbolKey, generatedDocument, cancellationToken)); }
public void NavigateTo(SymbolKey id, Project project, CancellationToken cancellationToken) { var compilation = project.GetCompilationAsync(cancellationToken).WaitAndGetResult(cancellationToken); var resolution = id.Resolve(compilation, cancellationToken: cancellationToken); var workspace = project.Solution.Workspace; var options = workspace.Options.WithChangedOption(NavigationOptions.PreferProvisionalTab, true); var symbolNavigationService = workspace.Services.GetService<ISymbolNavigationService>(); symbolNavigationService.TryNavigateToSymbol(resolution.Symbol, project, options, cancellationToken); }
public static async Task <SerializableUnimportedExtensionMethods?> GetUnimportedExtensionMethodsAsync( Document document, int position, ITypeSymbol receiverTypeSymbol, ISet <string> namespaceInScope, ImmutableArray <ITypeSymbol> targetTypesSymbols, bool forceCacheCreation, bool hideAdvancedMembers, CancellationToken cancellationToken) { var project = document.Project; var client = await RemoteHostClient.TryGetClientAsync(project, cancellationToken).ConfigureAwait(false); if (client != null) { var receiverTypeSymbolKeyData = SymbolKey.CreateString(receiverTypeSymbol, cancellationToken); var targetTypesSymbolKeyData = targetTypesSymbols.SelectAsArray(s => SymbolKey.CreateString(s, cancellationToken)); // Call the project overload. Add-import-for-extension-method doesn't search outside of the current // project cone. var result = await client.TryInvokeAsync <IRemoteExtensionMethodImportCompletionService, SerializableUnimportedExtensionMethods?>( project, (service, solutionInfo, cancellationToken) => service.GetUnimportedExtensionMethodsAsync( solutionInfo, document.Id, position, receiverTypeSymbolKeyData, namespaceInScope.ToImmutableArray(), targetTypesSymbolKeyData, forceCacheCreation, hideAdvancedMembers, cancellationToken), cancellationToken).ConfigureAwait(false); return(result.HasValue ? result.Value : null); } else { return(await GetUnimportedExtensionMethodsInCurrentProcessAsync( document, position, receiverTypeSymbol, namespaceInScope, targetTypesSymbols, forceCacheCreation, hideAdvancedMembers, isRemote : false, cancellationToken) .ConfigureAwait(false)); } }
internal static IEnumerable <EnvDTE.CodeElement> ChildrenOfNamespace(CodeModelState state, ProjectId projectId, SymbolKey namespaceSymbolId) { var project = state.Workspace.CurrentSolution.GetProject(projectId); if (project == null) { throw Exceptions.ThrowEFail(); } var namespaceSymbol = namespaceSymbolId.Resolve(project.GetCompilationAsync().Result).Symbol as INamespaceSymbol; if (namespaceSymbol == null) { throw Exceptions.ThrowEFail(); } var containingAssembly = project.GetCompilationAsync().Result.Assembly; foreach (var child in namespaceSymbol.GetMembers()) { if (child is INamespaceSymbol) { yield return((EnvDTE.CodeElement)ExternalCodeNamespace.Create(state, projectId, (INamespaceSymbol)child)); } else { var namedType = (INamedTypeSymbol)child; if (namedType.IsAccessibleWithin(containingAssembly)) { if (namedType.Locations.Any(l => l.IsInMetadata || l.IsInSource)) { yield return(state.CodeModelService.CreateCodeType(state, projectId, namedType)); } } } } }
public UniqueDocumentKey(AssemblyIdentity assemblyIdentity, MetadataId?metadataId, string language, SymbolKey symbolId, bool signaturesOnly) { Contract.ThrowIfNull(assemblyIdentity); _assemblyIdentity = assemblyIdentity; _metadataId = metadataId; _language = language; _symbolId = symbolId; _signaturesOnly = signaturesOnly; }
public UniqueDocumentKey(string filePath, MetadataId?metadataId, string language, SymbolKey symbolId, bool allowDecompilation) { Contract.ThrowIfNull(filePath); _filePath = filePath; _metadataId = metadataId; _language = language; _symbolId = symbolId; _allowDecompilation = allowDecompilation; }
public UniqueDocumentKey(AssemblyIdentity assemblyIdentity, MetadataId?metadataId, string language, SymbolKey symbolId, bool allowDecompilation) { Contract.ThrowIfNull(assemblyIdentity); _assemblyIdentity = assemblyIdentity; _metadataId = metadataId; _language = language; _symbolId = symbolId; _allowDecompilation = allowDecompilation; }
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); var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { InitializeWorkspace(project); Contract.ThrowIfNull(_workspace); var infoKey = await GetUniqueDocumentKey(project, topLevelNamedType, allowDecompilation, cancellationToken).ConfigureAwait(false); fileInfo = _keyToInformation.GetOrAdd(infoKey, _ => new MetadataAsSourceGeneratedFileInfo(GetRootPathWithGuid_NoLock(), project, topLevelNamedType, allowDecompilation)); _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); Contract.ThrowIfNull(temporaryDocument, "The temporary ProjectInfo didn't contain the document it said it would."); var useDecompiler = allowDecompilation; if (useDecompiler) { useDecompiler = !symbol.ContainingAssembly.GetAttributes().Any(attribute => attribute.AttributeClass.Name == nameof(SuppressIldasmAttribute) && attribute.AttributeClass.ToNameDisplayString() == typeof(SuppressIldasmAttribute).FullName); } if (useDecompiler) { try { var decompiledSourceService = temporaryDocument.GetLanguageService <IDecompiledSourceService>(); if (decompiledSourceService != null) { temporaryDocument = await decompiledSourceService.AddSourceToAsync(temporaryDocument, compilation, symbol, cancellationToken).ConfigureAwait(false); } else { useDecompiler = false; } } catch (Exception e) when(FatalError.ReportWithoutCrashUnlessCanceled(e)) { useDecompiler = false; } } if (!useDecompiler) { var sourceFromMetadataService = temporaryDocument.Project.LanguageServices.GetRequiredService <IMetadataAsSourceService>(); temporaryDocument = await sourceFromMetadataService.AddSourceToAsync(temporaryDocument, compilation, 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)); }
public static Func <Document, CancellationToken, Task <ImmutableArray <TaggedText> > >?GetDescriptionFunction(int position, SymbolKey symbolKey, SymbolDescriptionOptions options) => (document, cancellationToken) => GetDescriptionAsync(document, position, symbolKey, options, cancellationToken);
private static bool TryGetDependentTypes(ConditionalWeakTable <Compilation, ConcurrentDictionary <SymbolKey, List <SymbolKey> > > cache, Compilation compilation, SymbolKey typeId, out List <SymbolKey> dependentTypeIds) { dependentTypeIds = null; ConcurrentDictionary <SymbolKey, List <SymbolKey> > dictionary; return(cache.TryGetValue(compilation, out dictionary) && dictionary.TryGetValue(typeId, out dependentTypeIds)); }
protected AbstractGenerateCodeItem(RoslynNavigationBarItemKind kind, string text, Glyph glyph, SymbolKey destinationTypeSymbolKey) : base(kind, text, glyph, bolded: false, grayed: false, indent: 0, childItems: default) { DestinationTypeSymbolKey = destinationTypeSymbolKey; }
private static List <SymbolKey> GetOrAddDependentTypes(ConditionalWeakTable <Compilation, ConcurrentDictionary <SymbolKey, List <SymbolKey> > > cache, Compilation compilation, SymbolKey typeId, List <SymbolKey> dependentTypeIds) { List <SymbolKey> result; if (TryGetDependentTypes(cache, compilation, typeId, out result)) { return(result); } else { return(cache.GetValue(compilation, s_createSymbolDictionary) .GetOrAdd(typeId, dependentTypeIds)); } }
private static List<SymbolKey> GetOrAddDependentTypes(ConditionalWeakTable<Compilation, ConcurrentDictionary<SymbolKey, List<SymbolKey>>> cache, Compilation compilation, SymbolKey typeId, List<SymbolKey> dependentTypeIds) { List<SymbolKey> result; if (TryGetDependentTypes(cache, compilation, typeId, out result)) { return result; } else { return cache.GetValue(compilation, s_createSymbolDictionary) .GetOrAdd(typeId, dependentTypeIds); } }
internal static IEnumerator Create(CodeModelState state, ProjectId projectId, SymbolKey namespaceSymbolId) { var newEnumerator = new ExternalNamespaceEnumerator(state, projectId, namespaceSymbolId); return (IEnumerator)ComAggregate.CreateAggregatedObject(newEnumerator); }
private async Task <Location> RelocateSymbol_NoLock(MetadataAsSourceGeneratedFileInfo fileInfo, SymbolKey symbolId, CancellationToken cancellationToken) { Contract.ThrowIfNull(_workspace); // We need to relocate the symbol in the already existing file. If the file is open, we can just // reuse that workspace. Otherwise, we have to go spin up a temporary project to do the binding. if (_openedDocumentIds.TryGetValue(fileInfo, out var openDocumentId)) { // Awesome, it's already open. Let's try to grab a document for it var document = _workspace.CurrentSolution.GetDocument(openDocumentId); return(await MetadataAsSourceHelpers.GetLocationInGeneratedSourceAsync(symbolId, document, cancellationToken).ConfigureAwait(false)); } // Annoying case: the file is still on disk. Only real option here is to spin up a fake project to go and bind in. var temporaryProjectInfoAndDocumentId = fileInfo.GetProjectInfoAndDocumentId(_workspace, loadFileFromDisk: true); var temporaryDocument = _workspace.CurrentSolution.AddProject(temporaryProjectInfoAndDocumentId.Item1) .GetDocument(temporaryProjectInfoAndDocumentId.Item2); return(await MetadataAsSourceHelpers.GetLocationInGeneratedSourceAsync(symbolId, temporaryDocument, cancellationToken).ConfigureAwait(false)); }
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)); }
internal override bool Equals(SymbolKey other, ComparisonOptions options) { return ReferenceEquals(this, other); }
private async Task <UniqueDocumentKey> GetUniqueDocumentKey(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)); } }