public async Task <SignatureHelp> SignatureHelp(IEditor editor, List <UnsavedFile> unsavedFiles, int offset, string methodName)
        {
            var dataAssociation = GetAssociatedData(editor);

            var workspace = RoslynWorkspace.GetWorkspace(dataAssociation.Solution);

            var document = workspace.GetDocument(editor.SourceFile);

            var invocation = await GetInvocation(document, offset);

            if (invocation != null)
            {
                return(invocation.BuildSignatureHelp());
            }

            return(null);
        }
示例#2
0
        public override async Task UnloadAsync()
        {
            await base.UnloadAsync();

            fileWatcher?.Dispose();

            lock (s_unloadLock)
            {
                RoslynProject = null;

                var workspace = RoslynWorkspace.GetWorkspace(Solution, false);

                if (workspace != null)
                {
                    RoslynWorkspace.DisposeWorkspace(Solution);
                }
            }
        }
示例#3
0
        public static async Task <OmniSharpProject> Create(ISolution solution, string path)
        {
            var(project, projectReferences, targetPath) = await RoslynWorkspace.GetWorkspace(solution).AddProject(solution.CurrentDirectory, path);

            if (project == null)
            {
                return(null);
            }

            var roslynProject       = project;
            var references          = projectReferences;
            OmniSharpProject result = new OmniSharpProject(path)
            {
                Solution             = solution,
                RoslynProject        = roslynProject,
                UnresolvedReferences = references,
                detectedTargetPath   = targetPath
            };

            return(result);
        }
        public async Task <Symbol> GetSymbolAsync(IEditor editor, List <UnsavedFile> unsavedFiles, int offset)
        {
            var dataAssociation = GetAssociatedData(editor);

            var workspace = RoslynWorkspace.GetWorkspace(dataAssociation.Solution);

            var document = GetDocument(dataAssociation, editor.SourceFile, workspace);

            var semanticModel = await document.GetSemanticModelAsync();

            var symbol = await SymbolFinder.FindSymbolAtPositionAsync(semanticModel, offset, workspace);

            Symbol result = null;

            if (symbol != null)
            {
                result = SymbolFromRoslynSymbol(offset, semanticModel, symbol);
            }

            return(result);
        }
示例#5
0
        private async Task <int> Execute()
        {
            var projectPath = Project.HasValue() ? Project.Value() : Directory.GetCurrentDirectory();

            if (Directory.Exists(projectPath))
            {
                projectPath = Path.Combine(Path.GetFullPath(projectPath), Path.GetFileName(projectPath) + ".csproj");
            }

            if (!File.Exists(projectPath))
            {
                Console.WriteLine($"Project file {projectPath} not found.");
                return(1);
            }

            Console.WriteLine("Analyzing project...");
            var builder = new MsBuildProjectContextBuilder(projectPath, Program.TargetDirectory);
            var context = builder.Build();

            var workspace   = new RoslynWorkspace(context);
            var project     = workspace.CurrentSolution.Projects.Single();
            var compilation = await project.GetCompilationAsync().ConfigureAwait(false);

            var startup = await StartupAnalysis.AnalyzeCompilation(compilation).ConfigureAwait(false);

            Console.WriteLine("Found services:");
            foreach (var service in startup.Services)
            {
                Console.WriteLine($"{service}");
            }
            Console.WriteLine();

            Console.WriteLine("Found middleware:");
            foreach (var middleware in startup.Middleware)
            {
                Console.WriteLine($"{middleware.ToString()}");
            }
            Console.WriteLine();
            return(0);
        }
示例#6
0
        /*
         * This is currently quite flawed - getting missing method exceptions for methods that clearly exist
         * when trying to instantiate types in the loaded assembly.
         * The intent behind this was to instantiate the DbContext to get EF's model metadata and use that
         * for code generation, since its going to be more correct & consistent than our guesses about the data model.
         *
         * public Assembly GetAssembly()
         * {
         *  //return null;
         *  var projectFileName = Path.GetFileName(_projectContext.ProjectFilePath);
         *  var project = _projectWorkspace.CurrentSolution.Projects
         *      .SingleOrDefault(p => Path.GetFileName(p.FilePath) == projectFileName);
         *
         *  using (var assemblyStream = new MemoryStream())
         *  {
         *      using (var pdbStream = new MemoryStream())
         *      {
         *          var result = GetProjectCompilation().Emit(
         *              assemblyStream,
         *              pdbStream);
         *
         *          if (!result.Success)
         *          {
         *              throw new TypeLoadException($"Couldn't emit assembly for project {_projectContext.ProjectFilePath}");
         *          }
         *
         *          assemblyStream.Seek(0, SeekOrigin.Begin);
         *          pdbStream.Seek(0, SeekOrigin.Begin);
         *
         *          //var domain = AppDomain.CreateDomain($"{_projectContext.ProjectFilePath}-compilation");
         *          //domain.ExecuteAssembly(project.OutputFilePath);
         *          //foreach (var file in _projectContext.CompilationAssemblies)
         *          //{
         *          //    try
         *          //    {
         *          //        domain.Load(AssemblyName.GetAssemblyName(file.ResolvedPath));
         *          //    }
         *          //    catch { }
         *          //}
         *
         *          AppDomain.CurrentDomain.AssemblyLoad += (sender, args) => Console.WriteLine(args.LoadedAssembly.ToString());
         *
         *          AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
         *          {
         *              var name = new AssemblyName(args.Name);
         *              var match = _projectContext.CompilationAssemblies.FirstOrDefault(a => AssemblyName.GetAssemblyName(a.ResolvedPath).Name == name.Name);
         *              if (match != null)
         *              {
         *                  return Assembly.LoadFrom(match.ResolvedPath);
         *              }
         *              return null;
         *          };
         *
         *          var assembly = Assembly.Load(assemblyStream.ToArray(), pdbStream.ToArray());
         *          //var assembly = Assembly.LoadFrom(project.OutputFilePath);
         *          var contextType = assembly.GetType("Intellitect.Myriad.Data.AppDbContext");
         *          var instance = Activator.CreateInstance(contextType);
         *
         *          return assembly;
         *      }
         *  }
         * }
         */

        public static RoslynTypeLocator FromProjectContext(RoslynProjectContext project)
        {
            var workspace = new RoslynWorkspace(project.MsBuildProjectContext, project.MsBuildProjectContext.Configuration);

            workspace.WorkspaceFailed += (object sender, WorkspaceDiagnosticEventArgs e) =>
            {
                if (e.Diagnostic.Kind == WorkspaceDiagnosticKind.Failure)
                {
                    // NB: Ultimately an InvalidCast happens with the TypeScript FindConfigFilesTask (compiled
                    //     against v4.0 of Microsoft.Build) trying to cast to a ITask in Microsoft.Build v15.0
                    //     Therefore we must ignore an empty error message.
                    Debug.WriteLine(e.Diagnostic.Message);
                    if (!e.Diagnostic.Message.Contains(
                            "Unable to cast object of type 'Microsoft.CodeAnalysis.BuildTasks.Csc' to type 'Microsoft.Build.Framework.ITask'."))
                    {
                        throw new InvalidProjectFileException(e.Diagnostic.Message);
                    }
                }
            };

            return(new RoslynTypeLocator(workspace, project));
        }
示例#7
0
        public void SupportFileLocationForExistingLayoutFileTest(bool leadTilde, bool leadSeparator, string[] existingLayoutFileParts, string[] expectedSupportFileLocationParts, string[] expectedLayoutFileParts)
        {
            string expectedSupportFileLocation;
            string expectedLayoutFile;

            if (expectedSupportFileLocationParts.Length > 0)
            {
                expectedSupportFileLocation = Path.Combine(expectedSupportFileLocationParts);
            }
            else
            {
                expectedSupportFileLocation = IdentityGeneratorTemplateModelBuilder._DefaultSupportLocation;
            }

            if (expectedLayoutFileParts.Length > 0)
            {
                expectedLayoutFile = Path.Combine(expectedLayoutFileParts);
            }
            else
            {
                expectedLayoutFile = Path.Combine(IdentityGeneratorTemplateModelBuilder._DefaultSupportLocation, IdentityGeneratorTemplateModelBuilder._LayoutFileName);
            }
            expectedLayoutFile = expectedLayoutFile.Replace("\\", "/");

            string existingLayoutFile = string.Empty;

            if (leadTilde)
            {
                existingLayoutFile += "~";
            }

            if (leadSeparator)
            {
                existingLayoutFile += Path.DirectorySeparatorChar;
            }

            if (existingLayoutFileParts.Length > 0)
            {
                existingLayoutFile = existingLayoutFile + Path.Combine(existingLayoutFileParts);
            }

            IdentityGeneratorCommandLineModel commandLineModel = new IdentityGeneratorCommandLineModel();

            commandLineModel.Layout = existingLayoutFile;

            IApplicationInfo     applicationInfo = new ApplicationInfo("test", LayoutFileLocationTestProjectBasePath);
            CommonProjectContext context         = new CommonProjectContext();

            context.ProjectFullPath       = LayoutFileLocationTestProjectBasePath;
            context.ProjectName           = "TestProject";
            context.AssemblyName          = "TestAssembly";
            context.CompilationItems      = new List <string>();
            context.CompilationAssemblies = new List <ResolvedReference>();

            Workspace workspace = new RoslynWorkspace(context);
            ICodeGenAssemblyLoadContext assemblyLoadContext = new DefaultAssemblyLoadContext();
            IFileSystem mockFileSystem = new MockFileSystem();
            ILogger     logger         = new ConsoleLogger();

            IdentityGeneratorTemplateModelBuilder modelBuilder = new IdentityGeneratorTemplateModelBuilder(commandLineModel, applicationInfo, context, workspace, assemblyLoadContext, mockFileSystem, logger);

            modelBuilder.DetermineSupportFileLocation(out string supportFileLocation, out string layoutFile);
            Assert.Equal(expectedSupportFileLocation, supportFileLocation);
            Assert.Equal(expectedLayoutFile, layoutFile);
        }
示例#8
0
 public DocumentTrackingService(Workspace workspace)
 {
     _workspace = (RoslynWorkspace)workspace;
 }
        private Microsoft.CodeAnalysis.Document GetDocument(CSharpDataAssociation dataAssociation, ISourceFile file, RoslynWorkspace workspace = null)
        {
            if (file is MetaDataFile metaDataFile)
            {
                return(metaDataFile.Document);
            }
            else
            {
                if (workspace == null)
                {
                    workspace = RoslynWorkspace.GetWorkspace(dataAssociation.Solution);
                }

                return(workspace.GetDocument(file));
            }
        }
        public async Task <QuickInfoResult> QuickInfo(IEnumerable <UnsavedFile> unsavedFiles, int offset)
        {
            var dataAssociation = GetAssociatedData(_editor);

            var workspace = RoslynWorkspace.GetWorkspace(dataAssociation.Solution);

            var document = GetDocument(dataAssociation, _editor.SourceFile, workspace);

            var semanticModel = await document.GetSemanticModelAsync();

            var descriptionService = workspace.Services.GetLanguageServices(semanticModel.Language).GetService <ISymbolDisplayService>();

            var root = semanticModel.SyntaxTree.GetRoot(CancellationToken.None);

            SyntaxToken syntaxToken;

            try
            {
                syntaxToken = root.FindToken(offset);
            }
            catch (ArgumentOutOfRangeException)
            {
                return(null);
            }

            if (!syntaxToken.Span.IntersectsWith(offset))
            {
                return(null);
            }

            var node = GetBestFitResolveableNode(syntaxToken.Parent);

            var symbolInfo = semanticModel.GetSymbolInfo(node, CancellationToken.None);

            var symbol = symbolInfo.Symbol ?? semanticModel.GetDeclaredSymbol(node, CancellationToken.None);

            if (symbol != null)
            {
                var sections = await descriptionService.ToDescriptionGroupsAsync(workspace, semanticModel, offset, new[] { symbol }.AsImmutable(), default(CancellationToken)).ConfigureAwait(false);

                ImmutableArray <TaggedText> parts;

                var styledText = StyledText.Create();
                var theme      = ColorScheme.CurrentColorScheme;


                if (sections.TryGetValue(SymbolDescriptionGroups.MainDescription, out parts))
                {
                    TaggedTextUtil.AppendTaggedText(styledText, theme, parts);
                }

                // if generating quick info for an attribute, bind to the class instead of the constructor
                if (symbol.ContainingType?.IsAttribute() == true)
                {
                    symbol = symbol.ContainingType;
                }

                var formatter     = workspace.Services.GetLanguageServices(semanticModel.Language).GetService <IDocumentationCommentFormattingService>();
                var documentation = symbol.GetDocumentationParts(semanticModel, offset, formatter, CancellationToken.None);

                if (documentation != null && documentation.Any())
                {
                    styledText.AppendLine();
                    TaggedTextUtil.AppendTaggedText(styledText, theme, documentation);
                }

                if (sections.TryGetValue(SymbolDescriptionGroups.AnonymousTypes, out parts))
                {
                    if (!parts.IsDefaultOrEmpty)
                    {
                        styledText.AppendLine();
                        TaggedTextUtil.AppendTaggedText(styledText, theme, parts);
                    }
                }

                if (sections.TryGetValue(SymbolDescriptionGroups.AwaitableUsageText, out parts))
                {
                    if (!parts.IsDefaultOrEmpty)
                    {
                        styledText.AppendLine();
                        TaggedTextUtil.AppendTaggedText(styledText, theme, parts);
                    }
                }

                if (sections.TryGetValue(SymbolDescriptionGroups.Exceptions, out parts))
                {
                    if (!parts.IsDefaultOrEmpty)
                    {
                        styledText.AppendLine();
                        TaggedTextUtil.AppendTaggedText(styledText, theme, parts);
                    }
                }

                if (sections.TryGetValue(SymbolDescriptionGroups.Captures, out parts))
                {
                    if (!parts.IsDefaultOrEmpty)
                    {
                        styledText.AppendLine();
                        TaggedTextUtil.AppendTaggedText(styledText, theme, parts);
                    }
                }

                return(new QuickInfoResult(styledText));
            }

            return(null);
        }
        public async Task <CodeCompletionResults> CodeCompleteAtAsync(int index, int line, int column, IEnumerable <UnsavedFile> unsavedFiles, char previousChar, string filter)
        {
            if (_editor.SourceFile is MetaDataFile)
            {
                return(null);
            }

            var result = new CodeCompletionResults();

            var dataAssociation = GetAssociatedData(_editor);

            var workspace     = RoslynWorkspace.GetWorkspace(dataAssociation.Solution);
            var document      = workspace.GetDocument(_editor.SourceFile);
            var semanticModel = await document.GetSemanticModelAsync();

            var completionService = CompletionService.GetService(document);
            var data = await completionService.GetCompletionsAsync(document, index);

            if (data != null)
            {
                var recommendedSymbols = await Microsoft.CodeAnalysis.Recommendations.Recommender.GetRecommendedSymbolsAtPositionAsync(semanticModel, index, workspace);

                foreach (var completion in data.Items)
                {
                    var insertionText = completion.DisplayText;

                    if (completion.Properties.ContainsKey("InsertionText"))
                    {
                        insertionText = completion.Properties["InsertionText"];
                    }

                    var selectionBehavior = Languages.CompletionItemSelectionBehavior.Default;
                    int priority          = 0;

                    if (completion.Rules.SelectionBehavior != Microsoft.CodeAnalysis.Completion.CompletionItemSelectionBehavior.Default)
                    {
                        selectionBehavior = (Languages.CompletionItemSelectionBehavior)completion.Rules.SelectionBehavior;
                        priority          = completion.Rules.MatchPriority;
                    }

                    if (completion.Properties.ContainsKey("Provider") && completion.Properties["Provider"] == "Microsoft.CodeAnalysis.CSharp.Completion.Providers.SymbolCompletionProvider")
                    {
                        var symbols = recommendedSymbols.Where(x => x.Name == completion.Properties["SymbolName"] && (int)x.Kind == int.Parse(completion.Properties["SymbolKind"])).Distinct();

                        if (symbols != null && symbols.Any())
                        {
                            foreach (var symbol in symbols)
                            {
                                if (symbol != null)
                                {
                                    var newCompletion = new CodeCompletionData(symbol.Name, completion.FilterText, insertionText, null, selectionBehavior, priority);

                                    if (completion.Properties.ContainsKey("SymbolKind"))
                                    {
                                        newCompletion.Kind = FromOmniSharpKind(completion.Properties["SymbolKind"]);
                                    }

                                    var xmlDocumentation = symbol.GetDocumentationCommentXml();

                                    if (xmlDocumentation != string.Empty)
                                    {
                                        var docComment = DocumentationComment.From(xmlDocumentation, Environment.NewLine);
                                        newCompletion.BriefComment = docComment.SummaryText;
                                    }

                                    result.Completions.Add(newCompletion);
                                }
                            }
                        }
                    }
                    else
                    {
                        var newCompletion = new CodeCompletionData(completion.DisplayText, completion.FilterText, insertionText, null, selectionBehavior, priority);

                        if (completion.Properties.ContainsKey("SymbolKind"))
                        {
                            newCompletion.Kind = FromOmniSharpKind(completion.Properties["SymbolKind"]);
                        }

                        result.Completions.Add(newCompletion);
                    }
                }

                result.Contexts = Languages.CompletionContext.AnyType;
            }

            return(result);
        }
        public async Task <GotoDefinitionInfo> GotoDefinition(int offset)
        {
            var dataAssociation = GetAssociatedData(_editor);

            var document = GetDocument(dataAssociation, _editor.SourceFile);

            var semanticModel = await document.GetSemanticModelAsync();

            var symbol = await SymbolFinder.FindSymbolAtPositionAsync(semanticModel, _editor.Offset, RoslynWorkspace.GetWorkspace(dataAssociation.Solution));

            if (symbol != null && !(symbol is Microsoft.CodeAnalysis.INamespaceSymbol))
            {
                // for partial methods, pick the one with body
                if (symbol is Microsoft.CodeAnalysis.IMethodSymbol method)
                {
                    symbol = method.PartialImplementationPart ?? symbol;
                }

                var location = symbol.Locations.First();

                if (location.IsInSource)
                {
                    var lineSpan = symbol.Locations.First().GetMappedLineSpan();
                    return(new GotoDefinitionInfo
                    {
                        FileName = lineSpan.Path,
                        Line = lineSpan.StartLinePosition.Line + 1,
                        Column = lineSpan.StartLinePosition.Character + 1
                    });
                }
                else if (location.IsInMetadata)
                {
                    var timeout            = 5000;
                    var cancellationSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(timeout));
                    var(metadataDocument, _) = await _metadataHelper.GetAndAddDocumentFromMetadata(document.Project, symbol, cancellationSource.Token);

                    if (metadataDocument != null)
                    {
                        cancellationSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(timeout));

                        var metadataLocation = await _metadataHelper.GetSymbolLocationFromMetadata(symbol, metadataDocument, cancellationSource.Token);

                        var lineSpan = metadataLocation.GetMappedLineSpan();

                        var metaDataFile = new MetaDataFile(_editor.SourceFile.Project, metadataDocument, metadataDocument.Name, _metadataHelper.GetSymbolName(symbol));

                        return(new GotoDefinitionInfo
                        {
                            FileName = lineSpan.Path,
                            Line = lineSpan.StartLinePosition.Line + 1,
                            Column = lineSpan.StartLinePosition.Character + 1,
                            MetaDataFile = metaDataFile
                        });
                    }
                }
            }

            return(null);
        }
        private void TrackDocument()
        {
            // Make sure the path is correct
            AssetItem.UpdateSourceFolders();

            // Capture full path before going in a Task (might be renamed in between)
            var fullPath = AssetItem.FullPath.ToWindowsPath();

            DocumentId = Task.Run(async() =>
            {
                // Find DocumentId
                var xenkoAssets = await XenkoAssetsViewModel.InstanceTask;
                workspace       = await xenkoAssets.Code.Workspace;

                // If possible, we use AbsoluteSourceLocation which is the path from where it was loaded (in case it moved afterwise)
                var foundDocumentId = workspace.CurrentSolution.GetDocumentIdsWithFilePath(fullPath).FirstOrDefault();
                if (foundDocumentId == null)
                {
                    // New asset, let's create it in the workspace
                    // TODO: Differentiate document (newly created should be added in the project by the asset creation code) and additional documents (not in project)?
                    AssetItem.UpdateSourceFolders();
                    var sourceProject = AssetItem.SourceProject?.ToWindowsPath();
                    if (sourceProject == null)
                    {
                        throw new InvalidOperationException($"Could not find project associated to asset [{AssetItem}]");
                    }

                    var project = workspace.CurrentSolution.Projects.FirstOrDefault(x => x.FilePath == sourceProject);
                    if (project == null)
                    {
                        throw new InvalidOperationException($"Could not find project [{sourceProject}] in workspace");
                    }

                    // When opening document, loads it from the asset
                    foundDocumentId = workspace.AddDocument(project.Id, fullPath, loader: new ScriptTextLoader(this));
                }

                // Register to notifications in case of reloading or text updated
                workspace.TrackDocument(foundDocumentId, AllowReload, TextUpdated, ExternalChangesDetected);

                // This is to make sure that the file will stay dirty until saved after just creating it (since it will only be stored in memory)
                existsOnDisk = File.Exists(FullPath);

                // Check if the file changed from the file on the disk
                if (existsOnDisk)
                {
                    try
                    {
                        var diskContent = File.ReadAllText(FullPath);
                        if (diskContent != Asset.Text)
                        {
                            // Prompt for reload from source file
                            Dispatcher.Invoke(() => UpdateAssetFromSource(new LoggerResult()));
                        }
                    }
                    catch (Exception)
                    {
                        // In this case the file either does not exist anymore or can somehow not be read, just mark file as dirty and continue as usual
                        hasExternalChanges = true;
                    }
                }

                UpdateDirtiness();

                return(foundDocumentId);
            });
        }
示例#14
0
        public void RegisterSourceFile(IEditor editor)
        {
            if (dataAssociations.TryGetValue(editor, out CSharpDataAssociation association))
            {
                throw new Exception("Source file already registered with language service.");
            }

            IndentationStrategy = new CSharpIndentationStrategy(new AvaloniaEdit.TextEditorOptions {
                ConvertTabsToSpaces = true
            });

            association = new CSharpDataAssociation
            {
                Solution = editor.SourceFile.Project.Solution
            };

            dataAssociations.Add(editor, association);

            if (!(editor.SourceFile is MetaDataFile))
            {
                var avaloniaEditTextContainer = new AvalonEditTextContainer(editor.Document)
                {
                    Editor = editor
                };

                RoslynWorkspace.GetWorkspace(association.Solution).OpenDocument(editor.SourceFile, avaloniaEditTextContainer, (diagnostics) =>
                {
                    var dataAssociation = GetAssociatedData(editor);

                    var results = new List <Diagnostic>();

                    var fadedCode = new SyntaxHighlightDataList();

                    foreach (var diagnostic in diagnostics.Diagnostics)
                    {
                        if (diagnostic.CustomTags.Contains("Unnecessary"))
                        {
                            fadedCode.Add(new OffsetSyntaxHighlightingData
                            {
                                Start  = diagnostic.TextSpan.Start,
                                Length = diagnostic.TextSpan.Length,
                                Type   = HighlightType.Unnecessary
                            });
                        }
                        else
                        {
                            results.Add(FromRoslynDiagnostic(diagnostic, editor.SourceFile.Location, editor.SourceFile.Project));
                        }
                    }

                    DiagnosticsUpdated?.Invoke(this, new DiagnosticsUpdatedEventArgs(diagnostics.Id, editor.SourceFile, (DiagnosticsUpdatedKind)diagnostics.Kind, results.ToImmutableArray(), fadedCode));
                });

                association.TextInputHandler = (sender, e) =>
                {
                    switch (e.Text)
                    {
                    case "}":
                    case ";":
                        editor.IndentLine(editor.Line);
                        break;

                    case "{":
                        if (IndentationStrategy != null)
                        {
                            editor.IndentLine(editor.Line);
                        }
                        break;
                    }

                    OpenBracket(editor, editor.Document, e.Text);
                    CloseBracket(editor, editor.Document, e.Text);
                };

                association.BeforeTextInputHandler = (sender, e) =>
                {
                    switch (e.Text)
                    {
                    case "\n":
                    case "\r\n":
                        var nextChar = ' ';

                        if (editor.CaretOffset != editor.Document.TextLength)
                        {
                            nextChar = editor.Document.GetCharAt(editor.CaretOffset);
                        }

                        if (nextChar == '}')
                        {
                            var newline = "\r\n";     // TextUtilities.GetNewLineFromDocument(editor.Document, editor.TextArea.Caret.Line);
                            editor.Document.Insert(editor.CaretOffset, newline);

                            editor.Document.TrimTrailingWhiteSpace(editor.Line - 1);

                            editor.IndentLine(editor.Line);

                            editor.CaretOffset -= newline.Length;
                        }
                        break;
                    }
                };

                editor.TextEntered  += association.TextInputHandler;
                editor.TextEntering += association.BeforeTextInputHandler;
            }
        }
示例#15
0
        Task EnsureAnalysisDocumentIsOpen()
        {
            if (analysisDocument != null)
            {
                Microsoft.CodeAnalysis.Document doc;
                try {
                    doc = RoslynWorkspace.CurrentSolution.GetDocument(analysisDocument);
                    if (doc == null && RoslynWorkspace.CurrentSolution.ContainsAdditionalDocument(analysisDocument))
                    {
                        return(Task.CompletedTask);
                    }
                } catch (Exception) {
                    doc = null;
                }
                if (doc != null)
                {
                    return(Task.CompletedTask);
                }
            }
            if (Editor == null)
            {
                UnsubscribeAnalysisDocument();
                return(Task.CompletedTask);
            }
            if (Project != null && !IsUnreferencedSharedProject(Project))
            {
                lock (analysisDocumentLock) {
                    UnsubscribeRoslynWorkspace();
                    RoslynWorkspace = TypeSystemService.GetWorkspace(this.Project.ParentSolution);
                    if (RoslynWorkspace == null)                     // Solution not loaded yet
                    {
                        return(Task.CompletedTask);
                    }
                    SubscribeRoslynWorkspace();
                    analysisDocument = FileName != null?TypeSystemService.GetDocumentId(this.Project, this.FileName) : null;

                    if (analysisDocument != null && !RoslynWorkspace.CurrentSolution.ContainsAdditionalDocument(analysisDocument) && !RoslynWorkspace.IsDocumentOpen(analysisDocument))
                    {
                        TypeSystemService.InformDocumentOpen(analysisDocument, Editor, this);
                        OnAnalysisDocumentChanged(EventArgs.Empty);
                    }
                    return(Task.CompletedTask);
                }
            }
            lock (adhocProjectLock) {
                var token = analysisDocumentSrc.Token;
                if (adhocProject != null || IsInProjectSettingLoadingProcess)
                {
                    return(Task.CompletedTask);
                }

                if (Editor != null)
                {
                    var node = TypeSystemService.GetTypeSystemParserNode(Editor.MimeType, BuildAction.Compile);
                    if (Editor.MimeType == "text/x-csharp" || node?.Parser.CanGenerateAnalysisDocument(Editor.MimeType, BuildAction.Compile, new string[0]) == true)
                    {
                        var newProject = Services.ProjectService.CreateDotNetProject("C#");

                        this.adhocProject = newProject;

                        newProject.Name = "InvisibleProject";
                        newProject.References.Add(ProjectReference.CreateAssemblyReference("mscorlib"));
                        newProject.References.Add(ProjectReference.CreateAssemblyReference("System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"));
                        newProject.References.Add(ProjectReference.CreateAssemblyReference("System.Core"));

                        // Use a different name for each project, otherwise the msbuild builder will complain about duplicate projects.
                        newProject.FileName = "adhoc_" + (++adhocProjectCount) + ".csproj";
                        if (!Window.ViewContent.IsUntitled)
                        {
                            adHocFile = Editor.FileName;
                        }
                        else
                        {
                            adHocFile = (Platform.IsWindows ? "C:\\" : "/") + Window.ViewContent.UntitledName + ".cs";
                        }

                        newProject.Files.Add(new ProjectFile(adHocFile, BuildAction.Compile));

                        adhocSolution = new Solution();
                        adhocSolution.AddConfiguration("", true);
                        adhocSolution.DefaultSolutionFolder.AddItem(newProject);
                        return(TypeSystemService.Load(adhocSolution, new ProgressMonitor(), token, false).ContinueWith(task => {
                            if (token.IsCancellationRequested)
                            {
                                return;
                            }
                            UnsubscribeRoslynWorkspace();
                            RoslynWorkspace = task.Result.FirstOrDefault();                              // 1 solution loaded ->1 workspace as result
                            SubscribeRoslynWorkspace();
                            analysisDocument = RoslynWorkspace.CurrentSolution.Projects.First().DocumentIds.First();
                            TypeSystemService.InformDocumentOpen(RoslynWorkspace, analysisDocument, Editor, this);
                            OnAnalysisDocumentChanged(EventArgs.Empty);
                        }));
                    }
                }
            }
            return(Task.CompletedTask);
        }
示例#16
0
        public void RegisterSourceFile(IEditor editor)
        {
            if (dataAssociations.TryGetValue(editor, out CSharpDataAssociation association))
            {
                throw new Exception("Source file already registered with language service.");
            }

            IndentationStrategy = new CSharpIndentationStrategy(new AvaloniaEdit.TextEditorOptions {
                ConvertTabsToSpaces = true
            });

            association = new CSharpDataAssociation
            {
                Solution = editor.SourceFile.Project.Solution
            };

            dataAssociations.Add(editor, association);

            if (!(editor.SourceFile is MetaDataFile))
            {
                var avaloniaEditTextContainer = new AvalonEditTextContainer(editor.Document)
                {
                    Editor = editor
                };

                RoslynWorkspace.GetWorkspace(association.Solution).OpenDocument(editor.SourceFile, avaloniaEditTextContainer, (diagnostics) =>
                {
                    var dataAssociation = GetAssociatedData(editor);

                    //var results = new TextSegmentCollection<Diagnostic>();

                    //foreach (var diagnostic in diagnostics.Diagnostics)
                    //{
                    //    results.Add(FromRoslynDiagnostic(diagnostic, editor.SourceFile.Location, editor.SourceFile.Project));
                    //}

                    //(Diagnostics as Subject<TextSegmentCollection<Diagnostic>>).OnNext(results);
                });

                association.TextInputHandler = (sender, e) =>
                {
                    switch (e.Text)
                    {
                    case "}":
                    case ";":
                        editor.IndentLine(editor.Line);
                        break;

                    case "{":
                        if (IndentationStrategy != null)
                        {
                            editor.IndentLine(editor.Line);
                        }
                        break;
                    }

                    OpenBracket(editor, editor.Document, e.Text);
                    CloseBracket(editor, editor.Document, e.Text);
                };

                association.BeforeTextInputHandler = (sender, e) =>
                {
                    switch (e.Text)
                    {
                    case "\n":
                    case "\r\n":
                        var nextChar = ' ';

                        if (editor.CaretOffset != editor.Document.TextLength)
                        {
                            nextChar = editor.Document.GetCharAt(editor.CaretOffset);
                        }

                        if (nextChar == '}')
                        {
                            var newline = "\r\n";     // TextUtilities.GetNewLineFromDocument(editor.Document, editor.TextArea.Caret.Line);
                            editor.Document.Insert(editor.CaretOffset, newline);

                            editor.Document.TrimTrailingWhiteSpace(editor.Line - 1);

                            editor.IndentLine(editor.Line);

                            editor.CaretOffset -= newline.Length;
                        }
                        break;
                    }
                };

                editor.TextEntered  += association.TextInputHandler;
                editor.TextEntering += association.BeforeTextInputHandler;
            }
        }
示例#17
0
        public async Task <IEnumerable <SymbolRenameInfo> > RenameSymbol(IEditor editor, string renameTo = "")
        {
            if (editor.SourceFile is MetaDataFile)
            {
                return(null);
            }

            var dataAssociation = GetAssociatedData(editor);

            var workspace = RoslynWorkspace.GetWorkspace(dataAssociation.Solution);

            var document = GetDocument(dataAssociation, editor.SourceFile, workspace);

            if (document != null)
            {
                var sourceText = await document.GetTextAsync();

                var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, editor.CaretOffset);

                var solution = workspace.CurrentSolution;

                if (symbol != null)
                {
                    if (renameTo == string.Empty)
                    {
                        renameTo = "Test" + symbol.Name + "1";
                    }

                    try
                    {
                        solution = await Renamer.RenameSymbolAsync(solution, symbol, renameTo, workspace.Options);
                    }
                    catch (ArgumentException e)
                    {
                        return(null);
                    }
                }

                var changes         = new Dictionary <string, SymbolRenameInfo>();
                var solutionChanges = solution.GetChanges(workspace.CurrentSolution);

                foreach (var projectChange in solutionChanges.GetProjectChanges())
                {
                    foreach (var changedDocumentId in projectChange.GetChangedDocuments())
                    {
                        var changedDocument = solution.GetDocument(changedDocumentId);

                        if (!changes.TryGetValue(changedDocument.FilePath, out var modifiedFileResponse))
                        {
                            modifiedFileResponse = new SymbolRenameInfo(changedDocument.FilePath);
                            changes[changedDocument.FilePath] = modifiedFileResponse;
                        }

                        var originalDocument            = workspace.CurrentSolution.GetDocument(changedDocumentId);
                        var linePositionSpanTextChanges = await TextChanges.GetAsync(changedDocument, originalDocument);

                        modifiedFileResponse.Changes = modifiedFileResponse.Changes != null
                            ? modifiedFileResponse.Changes.Union(linePositionSpanTextChanges)
                            : linePositionSpanTextChanges;
                    }
                }

                return(changes.Values);
            }

            return(null);
        }
示例#18
0
        public async Task <IProject> LoadAsync(ISolution solution, string filePath)
        {
            await RoslynWorkspace.CreateWorkspaceAsync(solution);

            return(await OmniSharpProject.Create(solution, filePath));
        }
示例#19
0
        public OmniSharpProject(string location) : base(true)
        {
            Location          = location;
            ExcludedFiles     = new List <string>();
            Items             = new ObservableCollection <IProjectItem>();
            References        = new ObservableCollection <IProject>();
            ToolchainSettings = new ExpandoObject();
            DebugSettings     = new ExpandoObject();
            Settings          = new ExpandoObject();
            Project           = this;

            Items.InsertSorted(new ReferenceFolder(this));

            ExcludedFiles.Add("bin");
            ExcludedFiles.Add("obj");

            try
            {
                fileWatcher = new FileSystemWatcher(CurrentDirectory, Path.GetFileName(Location))
                {
                    EnableRaisingEvents   = true,
                    IncludeSubdirectories = false,

                    NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite
                };

                fileWatcher.Changed += async(sender, e) =>
                {
                    var lastWriteTime = File.GetLastWriteTime(e.FullPath);

                    if (lastWriteTime != lastProjectFileRead)
                    {
                        lastProjectFileRead = lastWriteTime;

                        RestoreRequired = true;

                        var statusBar = IoC.Get <IStatusBar>();

                        statusBar.SetText($"Project: {Name} has changed, running restore...");

                        await Restore(null, statusBar);

                        RestoreRequired = false;

                        statusBar.SetText($"Project: {Name} has changed, re-evaluating project...");

                        // todo restore packages and re-evaluate.
                        await RoslynWorkspace.GetWorkspace(Solution).ReevaluateProject(this);

                        statusBar.ClearText();
                    }
                };
            }
            catch (System.IO.IOException e)
            {
                var console = IoC.Get <IConsole>();

                console.WriteLine("Reached Max INotify Limit, to use AvalonStudio on Unix increase the INotify Limit");
                console.WriteLine("often it is set here: '/proc/sys/fs/inotify/max_user_watches'");

                console.WriteLine(e.Message);
            }

            FileAdded += (sender, e) =>
            {
                switch (e.Extension)
                {
                case ".cs":
                    RoslynWorkspace.GetWorkspace(Solution).AddDocument(RoslynProject, e);
                    break;
                }
            };
        }