public CodeEditorViewAdapterCSharp(AltaxoWorkspaceBase workspace, Microsoft.CodeAnalysis.DocumentId documentID, RoslynSourceTextContainerAdapter sourceText)
        {
            Workspace                      = workspace ?? throw new ArgumentNullException(nameof(workspace));
            DocumentId                     = documentID ?? throw new ArgumentNullException(nameof(documentID));
            SourceTextAdapter              = sourceText ?? throw new ArgumentNullException(nameof(sourceText));
            _roslynHost                    = workspace.RoslynHost;
            SourceTextAdapter.TextChanged += EhSourceTextAdapter_TextChanged;

            HighlightingColorizer     = new SemanticHighlighting.SemanticHighlightingColorizer(Workspace, DocumentId);
            QuickInfoProvider         = _roslynHost.GetService <QuickInfo.IQuickInfoProvider>();
            FoldingStrategy           = new SyntaxTreeFoldingStrategy();
            BraceMatchingService      = _roslynHost.GetService <IBraceMatchingService>();
            ReferenceHighlightService = new ReferenceHighlighting.CSharp.CSharpDocumentHighlightsService();
            CompletionProvider        = new Completion.CodeEditorCompletionProvider(_roslynHost, Workspace, DocumentId);
            RenamingService           = new Renaming.RenamingService();
            IndentationStrategy       = new ICSharpCode.AvalonEdit.Indentation.CSharp.CSharpIndentationStrategy();
            LiveDocumentFormatter     = new LiveDocumentFormatterCSharp();
            ExternalHelpProvider      = new ExternalHelp.ExternalHelpProvider();

            Workspace.SubscribeToDiagnosticsUpdateNotification(DocumentId, EhDiagnosticsUpdated);
        }
Example #2
0
 /// <summary>
 /// Creates a new instance of this project updated to no longer include the specified additional document.
 /// </summary>
 public Project RemoveAdditionalDocument(DocumentId documentId)
 {
     return(this.Solution.RemoveAdditionalDocument(documentId).GetProject(this.Id));
 }
 static void RemoveDocument(ConcurrentDictionary <DocumentId, List <DeclaredSymbolInfo> > result, Microsoft.CodeAnalysis.DocumentId documentId)
 {
     if (result.ContainsKey(documentId))
     {
         List <DeclaredSymbolInfo> val;
         result.TryRemove(documentId, out val);
     }
 }
Example #4
0
 protected static ValueSource <TextAndVersion> CreateRecoverableText(TextLoader loader, DocumentId documentId, SolutionServices services)
 {
     return(new RecoverableTextAndVersion(
                new AsyncLazy <TextAndVersion>(
                    asynchronousComputeFunction: cancellationToken => loader.LoadTextAsync(services.Workspace, documentId, cancellationToken),
                    synchronousComputeFunction: cancellationToken => loader.LoadTextSynchronously(services.Workspace, documentId, cancellationToken),
                    cacheResult: false),
                services.TemporaryStorage));
 }
Example #5
0
 public DocumentState GetDocumentState(DocumentId documentId)
 {
     _documentStates.TryGetValue(documentId, out var state);
     return(state);
 }
Example #6
0
 public bool ContainsDocument(DocumentId documentId)
 {
     return(_documentStates.ContainsKey(documentId));
 }
Example #7
0
        protected static async Task <TextAndVersion> LoadTextAsync(TextLoader loader, DocumentId documentId, SolutionServices services, bool reportInvalidDataException, CancellationToken cancellationToken)
        {
            int retries = 0;

            while (true)
            {
                try
                {
                    using (ExceptionHelpers.SuppressFailFast())
                    {
                        var result = await loader.LoadTextAndVersionAsync(services.Workspace, documentId, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);

                        return(result);
                    }
                }
                catch (OperationCanceledException)
                {
                    // if load text is failed due to a cancellation, make sure we propagate it out to the caller
                    throw;
                }
                catch (IOException e)
                {
                    if (++retries > MaxRetries)
                    {
                        services.Workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.Failure, e.Message, documentId));
                        return(TextAndVersion.Create(SourceText.From(string.Empty, Encoding.UTF8), VersionStamp.Default, documentId.GetDebuggerDisplay()));
                    }

                    // fall out to try again
                }
                catch (InvalidDataException e)
                {
                    // TODO: Adjust this behavior in the future if we add support for non-text additional files
                    if (reportInvalidDataException)
                    {
                        services.Workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.Failure, e.Message, documentId));
                    }

                    return(TextAndVersion.Create(SourceText.From(string.Empty, Encoding.UTF8), VersionStamp.Default, documentId.GetDebuggerDisplay()));
                }

                // try again after a delay
                await Task.Delay(RetryDelay, cancellationToken).ConfigureAwait(false);
            }
        }
Example #8
0
 public DocumentInfo WithId(DocumentId id)
 {
     return(With(attributes: Attributes.With(id: id)));
 }
Example #9
0
        /// <returns>The DocumentId of the current context document attached to the textContainer, if any.</returns>
        private DocumentId UpdateCurrentContextMapping_NoLock(SourceTextContainer textContainer, DocumentId id)
        {
            var documentIds = this.CurrentSolution.GetRelatedDocumentIds(id);
            if (documentIds.Length == 0)
            {
                // no related document. remove map and return no context
                _bufferToDocumentInCurrentContextMap.Remove(textContainer);
                return null;
            }

            if (documentIds.Length == 1 && documentIds[0] == id)
            {
                // only related document is myself. remove map and return no context
                _bufferToDocumentInCurrentContextMap.Remove(textContainer);
                return null;
            }

            if (documentIds[0] != id)
            {
                // there are related documents, set first one as new context.
                _bufferToDocumentInCurrentContextMap[textContainer] = documentIds[0];
                return documentIds[0];
            }

            // there are multiple related documents, and first one is myself. return next one.
            _bufferToDocumentInCurrentContextMap[textContainer] = documentIds[1];
            return documentIds[1];
        }
Example #10
0
 private void UpdateCurrentContextMapping_NoLock(SourceTextContainer textContainer, DocumentId id, bool isCurrentContext)
 {
     if (isCurrentContext || !_bufferToDocumentInCurrentContextMap.ContainsKey(textContainer))
     {
         _bufferToDocumentInCurrentContextMap[textContainer] = id;
     }
 }
Example #11
0
 internal override TextAndVersion LoadTextAndVersionSynchronously(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
 {
     return(TextAndVersion.Create(_container.CurrentText, _version, _filePath));
 }
Example #12
0
 public override Task <TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
 {
     return(Task.FromResult(LoadTextAndVersionSynchronously(workspace, documentId, cancellationToken)));
 }
Example #13
0
 internal override TextAndVersion LoadTextAndVersionSynchronously(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
 {
     return(_textAndVersion);
 }
Example #14
0
 /// <summary>
 /// Load a text and a version of the document in the workspace.
 /// </summary>
 internal virtual TextAndVersion LoadTextAndVersionSynchronously(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
 {
     // this implementation exists in case a custom derived type does not have access to internals
     return(LoadTextAndVersionAsync(workspace, documentId, cancellationToken).WaitAndGetResult_CanCallOnBackground(cancellationToken));
 }
Example #15
0
 /// <summary>
 /// Load a text and a version of the document in the workspace.
 /// </summary>
 public abstract Task <TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken);
Example #16
0
 private SourceTextContainer GetOpenDocumentSourceTextContainer_NoLock(DocumentId documentId)
 {
     // TODO: remove linear search
     return(_bufferToAssociatedDocumentsMap.Where(kvp => kvp.Value.Contains(documentId)).Select(kvp => kvp.Key).FirstOrDefault());
 }
Example #17
0
 /// <summary>
 /// Call this method to tell the host environment to change the current active context to this document. Only supported if
 /// <see cref="CanChangeActiveContextDocument"/> returns true.
 /// </summary>
 internal virtual void SetDocumentContext(DocumentId documentId)
 {
     throw new NotSupportedException();
 }
Example #18
0
 protected static ValueSource <TextAndVersion> CreateStrongText(TextLoader loader, DocumentId documentId, SolutionServices services, bool reportInvalidDataException)
 {
     return(new AsyncLazy <TextAndVersion>(
                c => LoadTextAsync(loader, documentId, services, reportInvalidDataException, c), cacheResult: true));
 }
Example #19
0
 protected static ValueSource <TextAndVersion> CreateRecoverableText(TextLoader loader, DocumentId documentId, SolutionServices services, bool reportInvalidDataException)
 {
     return(new RecoverableTextAndVersion(
                new AsyncLazy <TextAndVersion>(
                    asynchronousComputeFunction: c => LoadTextAsync(loader, documentId, services, reportInvalidDataException, c),
                    synchronousComputeFunction: c => LoadTextSynchronously(loader, documentId, services, reportInvalidDataException, c),
                    cacheResult: false),
                services.TemporaryStorage));
 }
Example #20
0
 /// <summary>
 /// Close the specified document in the host environment.
 /// </summary>
 public virtual void CloseDocument(DocumentId documentId)
 => this.CheckCanOpenDocuments();
Example #21
0
        /// <summary>
        /// Create a <see cref="ProjectInfo"/> structure initialized from a compilers command line arguments.
        /// </summary>
        public static ProjectInfo CreateProjectInfo(string projectName, string language, IEnumerable <string> commandLineArgs, string projectDirectory, Workspace workspace = null)
        {
            // TODO (tomat): the method may throw all sorts of exceptions.
            var tmpWorkspace     = workspace ?? new AdhocWorkspace(DesktopMefHostServices.DefaultServices);
            var languageServices = tmpWorkspace.Services.GetLanguageServices(language);

            if (languageServices == null)
            {
                throw new ArgumentException(WorkspacesResources.UnrecognizedLanguageName);
            }

            var commandLineArgumentsFactory = languageServices.GetRequiredService <ICommandLineArgumentsFactoryService>();
            var commandLineArguments        = commandLineArgumentsFactory.CreateCommandLineArguments(commandLineArgs, projectDirectory, isInteractive: false);

            // TODO (tomat): to match csc.exe/vbc.exe we should use CommonCommandLineCompiler.ExistingReferencesResolver to deal with #r's
            var referenceResolver  = new MetadataFileReferenceResolver(commandLineArguments.ReferencePaths, commandLineArguments.BaseDirectory);
            var referenceProvider  = tmpWorkspace.Services.GetRequiredService <IMetadataService>().GetProvider();
            var xmlFileResolver    = new XmlFileResolver(commandLineArguments.BaseDirectory);
            var strongNameProvider = new DesktopStrongNameProvider(commandLineArguments.KeyFileSearchPaths);

            // resolve all metadata references.
            var boundMetadataReferences      = commandLineArguments.ResolveMetadataReferences(new AssemblyReferenceResolver(referenceResolver, referenceProvider));
            var unresolvedMetadataReferences = boundMetadataReferences.FirstOrDefault(r => r is UnresolvedMetadataReference);

            if (unresolvedMetadataReferences != null)
            {
                throw new ArgumentException(string.Format(WorkspacesResources.CantResolveMetadataReference, ((UnresolvedMetadataReference)unresolvedMetadataReferences).Reference));
            }

            // resolve all analyzer references.
            var boundAnalyzerReferences      = commandLineArguments.ResolveAnalyzerReferences();
            var unresolvedAnalyzerReferences = boundAnalyzerReferences.FirstOrDefault(r => r is UnresolvedAnalyzerReference);

            if (unresolvedAnalyzerReferences != null)
            {
                throw new ArgumentException(string.Format(WorkspacesResources.CantResolveAnalyzerReference, ((UnresolvedAnalyzerReference)unresolvedAnalyzerReferences).Display));
            }

            AssemblyIdentityComparer assemblyIdentityComparer;

            if (commandLineArguments.AppConfigPath != null)
            {
                try
                {
                    using (var appConfigStream = new FileStream(commandLineArguments.AppConfigPath, FileMode.Open, FileAccess.Read))
                    {
                        assemblyIdentityComparer = DesktopAssemblyIdentityComparer.LoadFromXml(appConfigStream);
                    }
                }
                catch (Exception e)
                {
                    throw new ArgumentException(string.Format(WorkspacesResources.ErrorWhileReadingSpecifiedConfigFile, e.Message));
                }
            }
            else
            {
                assemblyIdentityComparer = DesktopAssemblyIdentityComparer.Default;
            }

            var projectId = ProjectId.CreateNewId(debugName: projectName);

            // construct file infos
            var docs = new List <DocumentInfo>();

            foreach (var fileArg in commandLineArguments.SourceFiles)
            {
                var absolutePath = Path.IsPathRooted(fileArg.Path) || string.IsNullOrEmpty(projectDirectory)
                    ? Path.GetFullPath(fileArg.Path)
                    : Path.GetFullPath(Path.Combine(projectDirectory, fileArg.Path));

                var relativePath    = FilePathUtilities.GetRelativePath(projectDirectory, absolutePath);
                var isWithinProject = FilePathUtilities.IsNestedPath(projectDirectory, absolutePath);

                var folderRoot = isWithinProject ? Path.GetDirectoryName(relativePath) : "";
                var folders    = isWithinProject ? GetFolders(relativePath) : null;
                var name       = Path.GetFileName(relativePath);
                var id         = DocumentId.CreateNewId(projectId, absolutePath);

                var doc = DocumentInfo.Create(
                    id: id,
                    name: name,
                    folders: folders,
                    sourceCodeKind: fileArg.IsScript ? SourceCodeKind.Script : SourceCodeKind.Regular,
                    loader: new FileTextLoader(absolutePath, commandLineArguments.Encoding),
                    filePath: absolutePath);

                docs.Add(doc);
            }

            // construct file infos for additional files.
            var additionalDocs = new List <DocumentInfo>();

            foreach (var fileArg in commandLineArguments.AdditionalFiles)
            {
                var absolutePath = Path.IsPathRooted(fileArg.Path) || string.IsNullOrEmpty(projectDirectory)
                        ? Path.GetFullPath(fileArg.Path)
                        : Path.GetFullPath(Path.Combine(projectDirectory, fileArg.Path));

                var relativePath    = FilePathUtilities.GetRelativePath(projectDirectory, absolutePath);
                var isWithinProject = FilePathUtilities.IsNestedPath(projectDirectory, absolutePath);

                var folderRoot = isWithinProject ? Path.GetDirectoryName(relativePath) : "";
                var folders    = isWithinProject ? GetFolders(relativePath) : null;
                var name       = Path.GetFileName(relativePath);
                var id         = DocumentId.CreateNewId(projectId, absolutePath);

                var doc = DocumentInfo.Create(
                    id: id,
                    name: name,
                    folders: folders,
                    sourceCodeKind: SourceCodeKind.Regular,
                    loader: new FileTextLoader(absolutePath, commandLineArguments.Encoding),
                    filePath: absolutePath);

                additionalDocs.Add(doc);
            }

            // If /out is not specified and the project is a console app the csc.exe finds out the Main method
            // and names the compilation after the file that contains it. We don't want to create a compilation,
            // bind Mains etc. here. Besides the msbuild always includes /out in the command line it produces.
            // So if we don't have the /out argument we name the compilation "<anonymous>".
            string assemblyName = (commandLineArguments.OutputFileName != null) ?
                                  Path.GetFileNameWithoutExtension(commandLineArguments.OutputFileName) : "<anonymous>";

            // TODO (tomat): what should be the assemblyName when compiling a netmodule? Should it be /moduleassemblyname

            var projectInfo = ProjectInfo.Create(
                projectId,
                VersionStamp.Create(),
                projectName,
                assemblyName,
                language: language,
                compilationOptions: commandLineArguments.CompilationOptions
                .WithXmlReferenceResolver(xmlFileResolver)
                .WithAssemblyIdentityComparer(assemblyIdentityComparer)
                .WithStrongNameProvider(strongNameProvider)
                .WithMetadataReferenceResolver(new AssemblyReferenceResolver(referenceResolver, referenceProvider)),
                parseOptions: commandLineArguments.ParseOptions,
                documents: docs,
                additionalDocuments: additionalDocs,
                metadataReferences: boundMetadataReferences,
                analyzerReferences: boundAnalyzerReferences);

            return(projectInfo);
        }
Example #22
0
 /// <summary>
 /// Open the specified analyzer config document in the host environment.
 /// </summary>
 public virtual void OpenAnalyzerConfigDocument(DocumentId documentId, bool activate = true)
 => this.CheckCanOpenDocuments();
Example #23
0
 public bool ContainsAdditionalDocument(DocumentId documentId)
 {
     return(_additionalDocumentStates.ContainsKey(documentId));
 }
Example #24
0
 /// <summary>
 /// Close the specified analyzer config document in the host environment.
 /// </summary>
 public virtual void CloseAnalyzerConfigDocument(DocumentId documentId)
 => this.CheckCanOpenDocuments();
Example #25
0
 public TextDocumentState GetAdditionalDocumentState(DocumentId documentId)
 {
     _additionalDocumentStates.TryGetValue(documentId, out var state);
     return(state);
 }
Example #26
0
 protected void ClearOpenDocument(DocumentId documentId, bool isSolutionClosing)
 {
     ClearOpenDocument(documentId);
 }
Example #27
0
 /// <summary>
 /// Open the specified additional document in the host environment.
 /// </summary>
 public virtual void OpenAdditionalDocument(DocumentId documentId, bool activate = true)
 {
     this.CheckCanOpenDocuments();
 }
Example #28
0
 /// <summary>
 /// Close the specified additional document in the host environment.
 /// </summary>
 public virtual void CloseAdditionalDocument(DocumentId documentId)
 {
     this.CheckCanOpenDocuments();
 }
 static void RemoveDocument(ConcurrentDictionary <DocumentId, Dictionary <DeclaredSymbolInfoKind, List <DeclaredSymbolInfo> > > result, Microsoft.CodeAnalysis.DocumentId documentId)
 {
     result.TryRemove(documentId, out Dictionary <DeclaredSymbolInfoKind, List <DeclaredSymbolInfo> > val);
 }
Example #30
0
        /// <summary>
        /// Creates a new additional document in a new instance of this project.
        /// </summary>
        public TextDocument AddAdditionalDocument(string name, string text, IEnumerable <string> folders = null, string filePath = null)
        {
            var id = DocumentId.CreateNewId(this.Id);

            return(this.Solution.AddAdditionalDocument(id, name, text, folders, filePath).GetAdditionalDocument(id));
        }