public bool TryGetLoaderFromProjectPath(string projectFilePath, DiagnosticReportingMode mode, out IProjectFileLoader loader) { using (_dataGuard.DisposableWait()) { var extension = Path.GetExtension(projectFilePath); if (extension.Length > 0 && extension[0] == '.') { extension = extension.Substring(1); } if (_extensionToLanguageMap.TryGetValue(extension, out var language)) { if (_workspaceServices.SupportedLanguages.Contains(language)) { loader = _workspaceServices.GetLanguageServices(language).GetService <IProjectFileLoader>(); } else { loader = null; _diagnosticReporter.Report(mode, string.Format(WorkspacesResources.Cannot_open_project_0_because_the_language_1_is_not_supported, projectFilePath, language)); return(false); } } else { loader = ProjectFileLoader.GetLoaderForProjectFileExtension(_workspaceServices, extension); if (loader == null) { _diagnosticReporter.Report(mode, string.Format(WorkspacesResources.Cannot_open_project_0_because_the_file_extension_1_is_not_associated_with_a_language, projectFilePath, Path.GetExtension(projectFilePath))); return(false); } } // since we have both C# and VB loaders in this same library, it no longer indicates whether we have full language support available. if (loader != null) { language = loader.Language; // check for command line parser existing... if not then error. var commandLineParser = _workspaceServices .GetLanguageServices(language) .GetService <ICommandLineParserService>(); if (commandLineParser == null) { loader = null; _diagnosticReporter.Report(mode, string.Format(WorkspacesResources.Cannot_open_project_0_because_the_language_1_is_not_supported, projectFilePath, language)); return(false); } } return(loader != null); } }
public static HostLanguageServices?GetLanguageServices( this HostWorkspaceServices workspaceServices, ITextBuffer textBuffer ) { return(workspaceServices.GetLanguageServices(textBuffer.ContentType)); }
internal static IEnumerable <ClassifiedSpan> GetClassifiedSpans( HostWorkspaceServices workspaceServices, SemanticModel semanticModel, TextSpan textSpan, ClassificationOptions options, CancellationToken cancellationToken) { var service = workspaceServices.GetLanguageServices(semanticModel.Language).GetRequiredService <ISyntaxClassificationService>(); var syntaxClassifiers = service.GetDefaultSyntaxClassifiers(); var extensionManager = workspaceServices.GetRequiredService <IExtensionManager>(); var getNodeClassifiers = extensionManager.CreateNodeExtensionGetter(syntaxClassifiers, c => c.SyntaxNodeTypes); var getTokenClassifiers = extensionManager.CreateTokenExtensionGetter(syntaxClassifiers, c => c.SyntaxTokenKinds); using var _1 = ArrayBuilder <ClassifiedSpan> .GetInstance(out var syntacticClassifications); using var _2 = ArrayBuilder <ClassifiedSpan> .GetInstance(out var semanticClassifications); var root = semanticModel.SyntaxTree.GetRoot(cancellationToken); service.AddSyntacticClassifications(root, textSpan, syntacticClassifications, cancellationToken); service.AddSemanticClassifications(semanticModel, textSpan, getNodeClassifiers, getTokenClassifiers, semanticClassifications, options, cancellationToken); var allClassifications = new List <ClassifiedSpan>(semanticClassifications.Where(s => s.TextSpan.OverlapsWith(textSpan))); var semanticSet = semanticClassifications.Select(s => s.TextSpan).ToSet(); allClassifications.AddRange(syntacticClassifications.Where( s => s.TextSpan.OverlapsWith(textSpan) && !semanticSet.Contains(s.TextSpan))); allClassifications.Sort((s1, s2) => s1.TextSpan.Start - s2.TextSpan.Start); return(allClassifications); }
/// <summary> /// Clean up the provided spans in the node. /// This will only cleanup stuff that doesn't require semantic information. /// </summary> public static Task <SyntaxNode> CleanupAsync(SyntaxNode root, ImmutableArray <TextSpan> spans, SyntaxFormattingOptions options, HostWorkspaceServices services, ImmutableArray <ICodeCleanupProvider> providers = default, CancellationToken cancellationToken = default) { var languageServices = services.GetLanguageServices(root.Language); var cleanupService = languageServices.GetRequiredService <ICodeCleanerService>(); return(cleanupService.CleanupAsync(root, spans, options, services, providers, cancellationToken)); }
private static Dictionary <string, string> CreateContentTypeMap(HostWorkspaceServices hostWorkspaceServices) { // Are we being hosted in a MEF host? If so, we can get content type information directly from the // metadata and avoid actually loading the assemblies var mefHostServices = (IMefHostExportProvider)hostWorkspaceServices.HostServices; if (mefHostServices != null) { // Two assemblies may export the same language to content type mapping during development cycles where // a type is moving to a new assembly. Avoid failing during content type discovery by de-duplicating // services with identical metadata, opting to instead fail only in cases where the impacted service // instance is used. var exports = mefHostServices.GetExports <ILanguageService, ContentTypeLanguageMetadata>(); return(exports .Where(lz => !string.IsNullOrEmpty(lz.Metadata.DefaultContentType)) .Select(lz => (lz.Metadata.Language, lz.Metadata.DefaultContentType)) .Distinct() .ToDictionary(lz => lz.Language, lz => lz.DefaultContentType)); } // We can't do anything special, so fall back to the expensive path return(hostWorkspaceServices.SupportedLanguages.ToDictionary( l => l, l => hostWorkspaceServices.GetLanguageServices(l).GetRequiredService <IContentTypeLanguageService>().GetDefaultContentType().TypeName)); }
private IOptionsSerializationService GetOptionsSerializationService(string languageName) => _lazyLanguageSerializationService.GetOrAdd( languageName, n => _workspaceServices .GetLanguageServices(n) .GetRequiredService <IOptionsSerializationService>() );
#pragma warning disable RS0030 // Do not used banned API 'GetLanguageServices', use 'GetExtendedLanguageServices' instead - allow in this helper which computes the extended language services. /// <summary> /// Gets extended host language services, which includes language services from <see cref="HostWorkspaceServices.GetLanguageServices(string)"/>. /// </summary> public static HostLanguageServices GetExtendedLanguageServices(this HostWorkspaceServices hostWorkspaceServices, string languageName) { var languageServices = hostWorkspaceServices.GetLanguageServices(languageName); #if CODE_STYLE languageServices = CodeStyleHostLanguageServices.GetRequiredMappedCodeStyleLanguageServices(languageServices); #endif return(languageServices); }
public VisualStudioProjectOptionsProcessor(VisualStudioProject project, HostWorkspaceServices workspaceServices) { _project = project ?? throw new ArgumentNullException(nameof(project)); _workspaceServices = workspaceServices; _commandLineParserService = workspaceServices.GetLanguageServices(project.Language).GetRequiredService <ICommandLineParserService>(); // Set up _commandLineArgumentsForCommandLine to a default. No lock taken since we're in the constructor so nothing can race. ReparseCommandLine_NoLock(); }
public static HostLanguageServices GetExtendedLanguageServices(this HostWorkspaceServices hostWorkspaceServices, string languageName) { var languageServices = hostWorkspaceServices.GetLanguageServices(languageName); #if CODE_STYLE // TODO: Uncomment the below once we enable language service detection in CodeStyle layer. //languageServices = CodeStyleHostLanguageServices.GetRequiredMappedCodeStyleLanguageServices(languageServices); #endif return(languageServices); }
public override HostLanguageServices GetLanguageServices(string languageName) { if (languageName == RazorLanguage.Name) { return(_razorLanguageServices); } // Fallback to default host services to resolve roslyn specific features. return(_fallbackServices.GetLanguageServices(languageName)); }
private static Task <SyntaxToken> GetTokenAtPositionAsync( SemanticModel semanticModel, int position, HostWorkspaceServices services, CancellationToken cancellationToken) { var syntaxTree = semanticModel.SyntaxTree; var syntaxFacts = services.GetLanguageServices(semanticModel.Language).GetRequiredService <ISyntaxFactsService>(); return(syntaxTree.GetTouchingTokenAsync(position, syntaxFacts.IsBindableToken, cancellationToken, findInsideTrivia: true)); }
internal static ProjectInfo CreateMiscellaneousProjectInfoForDocument( string filePath, TextLoader textLoader, LanguageInformation languageInformation, HostWorkspaceServices services, ImmutableArray <MetadataReference> metadataReferences) { var fileExtension = PathUtilities.GetExtension(filePath); var languageServices = services.GetLanguageServices(languageInformation.LanguageName); var compilationOptions = languageServices.GetService <ICompilationFactoryService>()?.GetDefaultCompilationOptions(); // Use latest language version which is more permissive, as we cannot find out language version of the project which the file belongs to // https://devdiv.visualstudio.com/DevDiv/_workitems/edit/575761 var parseOptions = languageServices.GetService <ISyntaxTreeFactoryService>()?.GetDefaultParseOptionsWithLatestLanguageVersion(); if (parseOptions != null && compilationOptions != null && fileExtension == languageInformation.ScriptExtension) { parseOptions = parseOptions.WithKind(SourceCodeKind.Script); compilationOptions = GetCompilationOptionsWithScriptReferenceResolvers(services, compilationOptions, filePath); } var projectId = ProjectId.CreateNewId(debugName: "Miscellaneous Files Project for " + filePath); var documentId = DocumentId.CreateNewId(projectId, debugName: filePath); var sourceCodeKind = parseOptions?.Kind ?? SourceCodeKind.Regular; var documentInfo = DocumentInfo.Create( documentId, filePath, sourceCodeKind: sourceCodeKind, loader: textLoader, filePath: filePath); // The assembly name must be unique for each collection of loose files. Since the name doesn't matter // a random GUID can be used. var assemblyName = Guid.NewGuid().ToString("N"); var projectInfo = ProjectInfo.Create( projectId, VersionStamp.Create(), name: FeaturesResources.Miscellaneous_Files, assemblyName, languageInformation.LanguageName, compilationOptions: compilationOptions, parseOptions: parseOptions, documents: SpecializedCollections.SingletonEnumerable(documentInfo), metadataReferences: metadataReferences); // Miscellaneous files projects are never fully loaded since, by definition, it won't know // what the full set of information is except when the file is script code. return(projectInfo.WithHasAllInformation(hasAllInformation: sourceCodeKind == SourceCodeKind.Script)); }
public static HostLanguageServices GetLanguageServices( this HostWorkspaceServices workspaceServices, IContentType contentType) { foreach (var language in workspaceServices.SupportedLanguages) { if (LanguageMatches(language, contentType, workspaceServices)) { return(workspaceServices.GetLanguageServices(language)); } } return(null); }
/// <summary> /// Returns true if the character recently inserted or deleted in the text should trigger completion. /// </summary> /// <param name="text">The document text to trigger completion within </param> /// <param name="caretPosition">The position of the caret after the triggering action.</param> /// <param name="trigger">The potential triggering action.</param> /// <param name="roles">Optional set of roles associated with the editor state.</param> /// <param name="options">Optional options that override the default options.</param> /// <remarks> /// This API uses SourceText instead of Document so implementations can only be based on text, not syntax or semantics. /// </remarks> public bool ShouldTriggerCompletion( SourceText text, int caretPosition, CompletionTrigger trigger, ImmutableHashSet <string>?roles = null, OptionSet?options = null) { var document = text.GetOpenDocumentInCurrentContextWithChanges(); var languageServices = document?.Project.LanguageServices ?? _services.GetLanguageServices(Language); // Publicly available options do not affect this API. var completionOptions = CompletionOptions.Default; var passThroughOptions = options ?? document?.Project.Solution.Options ?? OptionValueSet.Empty; return(ShouldTriggerCompletion(document?.Project, languageServices, text, caretPosition, trigger, completionOptions, passThroughOptions, roles)); }
public VisualStudioProjectOptionsProcessor( VisualStudioProject project, HostWorkspaceServices workspaceServices) { _project = project ?? throw new ArgumentNullException(nameof(project)); _workspaceServices = workspaceServices; _commandLineParserService = workspaceServices.GetLanguageServices(project.Language).GetRequiredService <ICommandLineParserService>(); _temporaryStorageService = workspaceServices.GetRequiredService <ITemporaryStorageService>(); // Set up _commandLineArgumentsForCommandLine to a default. No lock taken since we're in // the constructor so nothing can race. // Silence NRT warning. This will be initialized by the call below to ReparseCommandLineIfChanged_NoLock. _commandLineArgumentsForCommandLine = null !; ReparseCommandLineIfChanged_NoLock(commandLine: ""); }
public VisualStudioProjectOptionsProcessor(VisualStudioProject project, HostWorkspaceServices workspaceServices) { _project = project ?? throw new ArgumentNullException(nameof(project)); _workspaceServices = workspaceServices; _commandLineParserService = workspaceServices.GetLanguageServices(project.Language).GetRequiredService <ICommandLineParserService>(); // Set up _commandLineArgumentsForCommandLine to a default. No lock taken since we're in the constructor so nothing can race. ReparseCommandLine_NoLock(); _optionService = workspaceServices.GetRequiredService <IOptionService>(); // For C#, we need to listen to the options for NRT analysis // that can change in VS through tools > options if (_project.Language == LanguageNames.CSharp) { _optionService.OptionChanged += OptionService_OptionChanged; } }
private static Dictionary <string, string> CreateContentTypeMap(HostWorkspaceServices hostWorkspaceServices) { // Are we being hosted in a MEF host? If so, we can get content type information directly from the // metadata and avoid actually loading the assemblies var mefHostServices = (IMefHostExportProvider)hostWorkspaceServices.HostServices; if (mefHostServices != null) { var registry = mefHostServices.GetExports <IContentTypeRegistryService>().Single().Value; return(mefHostServices.GetExports <ILanguageService, ContentTypeLanguageMetadata>() .Where(lz => !string.IsNullOrEmpty(lz.Metadata.DefaultContentType)) .ToDictionary(lz => lz.Metadata.Language, lz => lz.Metadata.DefaultContentType)); } // We can't do anything special, so fall back to the expensive path return(hostWorkspaceServices.SupportedLanguages.ToDictionary( l => l, l => hostWorkspaceServices.GetLanguageServices(l).GetRequiredService <IContentTypeLanguageService>().GetDefaultContentType().TypeName)); }
public static async Task <QuickInfoItem> CreateQuickInfoItemAsync( HostWorkspaceServices services, SemanticModel semanticModel, TextSpan span, ImmutableArray <ISymbol> symbols, SupportedPlatformData?supportedPlatforms, bool showAwaitReturn, NullableFlowState flowState, SymbolDescriptionOptions options, CancellationToken cancellationToken) { var descriptionService = services.GetLanguageServices(semanticModel.Language).GetRequiredService <ISymbolDisplayService>(); var groups = await descriptionService.ToDescriptionGroupsAsync(semanticModel, span.Start, symbols, options, cancellationToken).ConfigureAwait(false); using var _1 = ArrayBuilder <QuickInfoSection> .GetInstance(out var sections); var symbol = symbols.First(); if (showAwaitReturn) { // We show a special message if the Task being awaited has no return if (symbol is INamedTypeSymbol { SpecialType : SpecialType.System_Void })
private TLanguageService GetLanguageService <TLanguageService>(string languageName) where TLanguageService : ILanguageService => _workspaceServices .GetLanguageServices(languageName) .GetService <TLanguageService>();
internal ValueTask <TOptions> GetOptionsAsync(string language, CancellationToken cancellationToken) => _optionsProvider.GetOptionsAsync(_services.GetLanguageServices(language), cancellationToken);
public static TokenSemanticInfo GetSemanticInfo( this SemanticModel semanticModel, SyntaxToken token, HostWorkspaceServices services, CancellationToken cancellationToken) { var languageServices = services.GetLanguageServices(token.Language); var syntaxFacts = languageServices.GetRequiredService <ISyntaxFactsService>(); if (!syntaxFacts.IsBindableToken(token)) { return(TokenSemanticInfo.Empty); } var semanticFacts = languageServices.GetRequiredService <ISemanticFactsService>(); IAliasSymbol?aliasSymbol; ITypeSymbol? type; ITypeSymbol? convertedType; ISymbol? declaredSymbol; ImmutableArray <ISymbol?> allSymbols; var overriddingIdentifier = syntaxFacts.GetDeclarationIdentifierIfOverride(token); if (overriddingIdentifier.HasValue) { // on an "override" token, we'll find the overridden symbol aliasSymbol = null; var overriddingSymbol = semanticFacts.GetDeclaredSymbol(semanticModel, overriddingIdentifier.Value, cancellationToken); var overriddenSymbol = overriddingSymbol.GetOverriddenMember(); // on an "override" token, the overridden symbol is the only part of TokenSemanticInfo used by callers, so type doesn't matter type = null; convertedType = null; declaredSymbol = null; allSymbols = overriddenSymbol is null ? ImmutableArray <ISymbol?> .Empty : ImmutableArray.Create <ISymbol?>(overriddenSymbol); } else { aliasSymbol = semanticModel.GetAliasInfo(token.Parent !, cancellationToken); var bindableParent = syntaxFacts.TryGetBindableParent(token); var typeInfo = bindableParent != null?semanticModel.GetTypeInfo(bindableParent, cancellationToken) : default; type = typeInfo.Type; convertedType = typeInfo.ConvertedType; declaredSymbol = MapSymbol(semanticFacts.GetDeclaredSymbol(semanticModel, token, cancellationToken), type); var skipSymbolInfoLookup = declaredSymbol.IsKind(SymbolKind.RangeVariable); allSymbols = skipSymbolInfoLookup ? ImmutableArray <ISymbol?> .Empty : semanticFacts .GetBestOrAllSymbols(semanticModel, bindableParent, token, cancellationToken) .WhereAsArray(s => !s.Equals(declaredSymbol)) .SelectAsArray(s => MapSymbol(s, type)); } // NOTE(cyrusn): This is a workaround to how the semantic model binds and returns // information for VB event handlers. Namely, if you have: // // Event X]() // Sub Goo() // Dim y = New $$XEventHandler(AddressOf bar) // End Sub // // Only GetTypeInfo will return any information for XEventHandler. So, in this // case, we upgrade the type to be the symbol we return. if (type != null && allSymbols.Length == 0) { if (type.Kind == SymbolKind.NamedType) { var namedType = (INamedTypeSymbol)type; if (namedType.TypeKind == TypeKind.Delegate || namedType.AssociatedSymbol != null) { allSymbols = ImmutableArray.Create <ISymbol?>(type); type = null; } } } if (allSymbols.Length == 0 && syntaxFacts.IsQueryKeyword(token)) { type = null; convertedType = null; } return(new TokenSemanticInfo(declaredSymbol, aliasSymbol, allSymbols, type, convertedType, token.Span)); }
private AbstractProject GetOrCreateProjectFromArgumentsAndReferences( IWorkspaceProjectContextFactory workspaceProjectContextFactory, IAnalyzerAssemblyLoader analyzerAssemblyLoader, string projectFilename, IReadOnlyDictionary <string, DeferredProjectInformation> allProjectInfos, IReadOnlyDictionary <string, string> targetPathsToProjectPaths) { var languageName = GetLanguageOfProject(projectFilename); if (languageName == null) { return(null); } if (!allProjectInfos.TryGetValue(projectFilename, out var projectInfo)) { // This could happen if we were called recursively about a dangling P2P reference // that isn't actually in the solution. return(null); } var commandLineParser = _workspaceServices.GetLanguageServices(languageName).GetService <ICommandLineParserService>(); var projectDirectory = PathUtilities.GetDirectoryName(projectFilename); var commandLineArguments = commandLineParser.Parse( projectInfo.CommandLineArguments, projectDirectory, isInteractive: false, sdkDirectory: RuntimeEnvironment.GetRuntimeDirectory()); // TODO: Should come from sln file? var projectName = PathUtilities.GetFileName(projectFilename, includeExtension: false); // `AbstractProject` only sets the filename if it actually exists. Since we want // our ids to match, mimic that behavior here. var projectId = File.Exists(projectFilename) ? GetOrCreateProjectIdForPath(projectFilename, projectName) : GetOrCreateProjectIdForPath(projectName, projectName); // See if we've already created this project and we're now in a recursive call to // hook up a P2P ref. if (_projectMap.TryGetValue(projectId, out var project)) { return(project); } OutputToOutputWindow($"\tCreating '{projectName}':\t{commandLineArguments.SourceFiles.Length} source files,\t{commandLineArguments.MetadataReferences.Length} references."); var solution5 = _serviceProvider.GetService(typeof(SVsSolution)) as IVsSolution5; // If the index is stale, it might give us a path that doesn't exist anymore that the // solution doesn't know about - be resilient to that case. Guid projectGuid; try { projectGuid = solution5.GetGuidOfProjectFile(projectFilename); } catch (ArgumentException) { var message = $"Failed to get the project guid for '{projectFilename}' from the solution, using random guid instead."; Debug.Fail(message); OutputToOutputWindow(message); projectGuid = Guid.NewGuid(); } // NOTE: If the indexing service fails for a project, it will give us an *empty* // target path, which we aren't prepared to handle. Instead, convert it to a *null* // value, which we do handle. var outputPath = projectInfo.TargetPath; if (outputPath == string.Empty) { outputPath = null; } var projectContext = workspaceProjectContextFactory.CreateProjectContext( languageName, projectName, projectFilename, projectGuid: projectGuid, hierarchy: null, binOutputPath: outputPath); project = (AbstractProject)projectContext; projectContext.SetOptions(projectInfo.CommandLineArguments.Join(" ")); foreach (var sourceFile in commandLineArguments.SourceFiles) { projectContext.AddSourceFile(sourceFile.Path); } foreach (var sourceFile in commandLineArguments.AdditionalFiles) { projectContext.AddAdditionalFile(sourceFile.Path); } var metadataReferences = commandLineArguments.ResolveMetadataReferences(project.CurrentCompilationOptions.MetadataReferenceResolver).AsImmutable(); var addedProjectReferences = new HashSet <string>(); foreach (var projectReferencePath in projectInfo.ReferencedProjectFilePaths) { var referencedProject = TryFindExistingProjectForProjectReference(projectReferencePath, metadataReferences); if (referencedProject == null) { referencedProject = GetOrCreateProjectFromArgumentsAndReferences( workspaceProjectContextFactory, analyzerAssemblyLoader, projectReferencePath, allProjectInfos, targetPathsToProjectPaths); } var referencedProjectContext = referencedProject as IWorkspaceProjectContext; if (referencedProjectContext != null) { // TODO: Can we get the properties from corresponding metadata reference in // commandLineArguments? addedProjectReferences.Add(projectReferencePath); projectContext.AddProjectReference( referencedProjectContext, new MetadataReferenceProperties()); } else if (referencedProject != null) { // This project was already created by the regular project system. See if we // can find the matching project somehow. var existingReferenceOutputPath = referencedProject?.BinOutputPath; if (existingReferenceOutputPath != null) { addedProjectReferences.Add(projectReferencePath); projectContext.AddMetadataReference( existingReferenceOutputPath, new MetadataReferenceProperties()); } } else { // We don't know how to create this project. Another language or something? OutputToOutputWindow($"Failed to create a project for '{projectReferencePath}'."); } } foreach (var reference in metadataReferences) { var path = GetReferencePath(reference); if (targetPathsToProjectPaths.TryGetValue(path, out var possibleProjectReference) && addedProjectReferences.Contains(possibleProjectReference)) { // We already added a P2P reference for this, we don't need to add the file reference too. continue; } projectContext.AddMetadataReference(path, reference.Properties); } foreach (var reference in commandLineArguments.ResolveAnalyzerReferences(analyzerAssemblyLoader)) { var path = reference.FullPath; if (!PathUtilities.IsAbsolute(path)) { path = PathUtilities.CombineAbsoluteAndRelativePaths( projectDirectory, path); } projectContext.AddAnalyzerReference(path); } return((AbstractProject)projectContext); }
private AbstractProject GetOrCreateProjectFromArgumentsAndReferences( IWorkspaceProjectContextFactory workspaceProjectContextFactory, IAnalyzerAssemblyLoader analyzerAssemblyLoader, string projectFilename, IReadOnlyDictionary <string, DeferredProjectInformation> allProjectInfos, IReadOnlyDictionary <string, string> targetPathsToProjectPaths) { var languageName = GetLanguageOfProject(projectFilename); if (languageName == null) { return(null); } if (!allProjectInfos.TryGetValue(projectFilename, out var projectInfo)) { // This could happen if we were called recursively about a dangling P2P reference // that isn't actually in the solution. return(null); } // TODO: Should come from .sln file? var projectName = PathUtilities.GetFileName(projectFilename, includeExtension: false); // `AbstractProject` only sets the filename if it actually exists. Since we want // our ids to match, mimic that behavior here. var projectId = File.Exists(projectFilename) ? GetOrCreateProjectIdForPath(projectFilename, projectName) : GetOrCreateProjectIdForPath(projectName, projectName); // See if something has already created this project - it's not deferred, the AnyCode design time build // failed so we force loaded it, or we already created a deferred project and we're in a recursive call // to find a ProjectReference if (_projectMap.TryGetValue(projectId, out var project)) { return(project); } // If the project system has opted this project out of deferred loading, or AnyCode // was unable to get command line info for it, we can't create a project for it. // NOTE: We need to check this even though it happened in CreateDeferredProjects // because we could be in a recursive call from a project reference below. var solution7 = (IVsSolution7)_vsSolution; if (DesignTimeBuildFailed(projectInfo) || !solution7.IsDeferredProjectLoadAllowed(projectFilename)) { return(null); } var commandLineParser = _workspaceServices.GetLanguageServices(languageName).GetService <ICommandLineParserService>(); var projectDirectory = PathUtilities.GetDirectoryName(projectFilename); var commandLineArguments = commandLineParser.Parse( projectInfo.CommandLineArguments, projectDirectory, isInteractive: false, sdkDirectory: RuntimeEnvironment.GetRuntimeDirectory()); OutputToOutputWindow($"\tCreating '{projectName}':\t{commandLineArguments.SourceFiles.Length} source files,\t{commandLineArguments.MetadataReferences.Length} references."); var projectGuid = GetProjectGuid(projectFilename); var projectContext = workspaceProjectContextFactory.CreateProjectContext( languageName, projectName, projectFilename, projectGuid: projectGuid, hierarchy: null, binOutputPath: projectInfo.TargetPath); project = (AbstractProject)projectContext; projectContext.SetOptions(projectInfo.CommandLineArguments.Join(" ")); var addedSourceFilePaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase); foreach (var sourceFile in commandLineArguments.SourceFiles) { if (addedSourceFilePaths.Add(sourceFile.Path)) { projectContext.AddSourceFile(sourceFile.Path); } } var addedAdditionalFilePaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase); foreach (var additionalFile in commandLineArguments.AdditionalFiles) { if (addedAdditionalFilePaths.Add(additionalFile.Path)) { projectContext.AddAdditionalFile(additionalFile.Path); } } var metadataReferences = commandLineArguments.ResolveMetadataReferences(project.CurrentCompilationOptions.MetadataReferenceResolver).AsImmutable(); var addedProjectReferences = new HashSet <string>(); foreach (var projectReferencePath in projectInfo.ReferencedProjectFilePaths) { var referencedProject = TryFindExistingProjectForProjectReference(projectReferencePath, metadataReferences); if (referencedProject == null) { referencedProject = GetOrCreateProjectFromArgumentsAndReferences( workspaceProjectContextFactory, analyzerAssemblyLoader, projectReferencePath, allProjectInfos, targetPathsToProjectPaths); } var referencedProjectContext = referencedProject as IWorkspaceProjectContext; if (referencedProjectContext != null) { // TODO: Can we get the properties from corresponding metadata reference in // commandLineArguments? addedProjectReferences.Add(projectReferencePath); projectContext.AddProjectReference( referencedProjectContext, new MetadataReferenceProperties()); } else if (referencedProject != null) { // This project was already created by the regular project system. See if we // can find the matching project somehow. var existingReferenceOutputPath = referencedProject?.BinOutputPath; if (existingReferenceOutputPath != null) { addedProjectReferences.Add(projectReferencePath); projectContext.AddMetadataReference( existingReferenceOutputPath, new MetadataReferenceProperties()); } } else { // We don't know how to create this project. Another language or something? OutputToOutputWindow($"\t\tFailed to create a project for '{projectReferencePath}'."); } } var addedReferencePaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase); foreach (var reference in metadataReferences) { var path = GetReferencePath(reference); if (targetPathsToProjectPaths.TryGetValue(path, out var possibleProjectReference) && addedProjectReferences.Contains(possibleProjectReference)) { // We already added a P2P reference for this, we don't need to add the file reference too. continue; } if (addedReferencePaths.Add(path)) { projectContext.AddMetadataReference(path, reference.Properties); } } var addedAnalyzerPaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase); foreach (var reference in commandLineArguments.ResolveAnalyzerReferences(analyzerAssemblyLoader)) { var path = reference.FullPath; if (!PathUtilities.IsAbsolute(path)) { path = PathUtilities.CombineAbsoluteAndRelativePaths( projectDirectory, path); } if (addedAnalyzerPaths.Add(path)) { projectContext.AddAnalyzerReference(path); } } return((AbstractProject)projectContext); }
private IOptionsSerializationService GetOptionsSerializationService(string languageName) { return(_lazyLanguageSerializationService.GetOrAdd(languageName, n => _workspaceServices.GetLanguageServices(n).GetService <IOptionsSerializationService>())); }
public static async Task <CompletionDescription> CreateDescriptionAsync( HostWorkspaceServices workspaceServices, SemanticModel semanticModel, int position, ISymbol symbol, int overloadCount, SymbolDescriptionOptions options, SupportedPlatformData?supportedPlatforms, CancellationToken cancellationToken) { var symbolDisplayService = workspaceServices.GetLanguageServices(semanticModel.Language).GetRequiredService <ISymbolDisplayService>(); var formatter = workspaceServices.GetLanguageServices(semanticModel.Language).GetRequiredService <IDocumentationCommentFormattingService>(); // TODO(cyrusn): Figure out a way to cancel this. var sections = await symbolDisplayService.ToDescriptionGroupsAsync(semanticModel, position, ImmutableArray.Create(symbol), options, cancellationToken).ConfigureAwait(false); if (!sections.ContainsKey(SymbolDescriptionGroups.MainDescription)) { return(CompletionDescription.Empty); } var textContentBuilder = new List <TaggedText>(); textContentBuilder.AddRange(sections[SymbolDescriptionGroups.MainDescription]); switch (symbol.Kind) { case SymbolKind.Method: case SymbolKind.Property: case SymbolKind.NamedType: if (overloadCount > 0) { var isGeneric = symbol.GetArity() > 0; textContentBuilder.AddSpace(); textContentBuilder.AddPunctuation("("); textContentBuilder.AddPunctuation("+"); textContentBuilder.AddText(NonBreakingSpaceString + overloadCount.ToString()); AddOverloadPart(textContentBuilder, overloadCount, isGeneric); textContentBuilder.AddPunctuation(")"); } break; } AddDocumentationPart(textContentBuilder, symbol, semanticModel, position, formatter, cancellationToken); if (sections.TryGetValue(SymbolDescriptionGroups.AwaitableUsageText, out var parts)) { textContentBuilder.AddRange(parts); } if (sections.TryGetValue(SymbolDescriptionGroups.StructuralTypes, out parts)) { if (!parts.IsDefaultOrEmpty) { textContentBuilder.AddLineBreak(); textContentBuilder.AddLineBreak(); textContentBuilder.AddRange(parts); } } if (supportedPlatforms != null) { textContentBuilder.AddLineBreak(); textContentBuilder.AddRange(supportedPlatforms.ToDisplayParts().ToTaggedText()); } return(CompletionDescription.Create(textContentBuilder.AsImmutable())); }
protected Document CreateDocument(DocumentId documentId, string languageName, SourceText sourceText, string filePath) { var languageServices = _services.GetLanguageServices(languageName); return(new Document(languageServices, documentId, sourceText, filePath, null, null, null)); }
protected Document CreateDocument(DocumentId documentId, string languageName, SourceFile file) { var languageServices = _services.GetLanguageServices(languageName); return(new Document(languageServices, documentId, file)); }
private async Task <IReadOnlyList <TagHelperDescriptor> > GetTagHelperInitializationTaskCore(ProjectSnapshot snapshot) { var resolver = _services.GetLanguageServices(RazorLanguage.Name).GetRequiredService <TagHelperResolver>(); return((await resolver.GetTagHelpersAsync(snapshot)).Descriptors); }