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); }
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); } } }
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); }
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); }
/* * 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)); }
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); }
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); }); }
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; } }
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); }
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; } }
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); }
public async Task <IProject> LoadAsync(ISolution solution, string filePath) { await RoslynWorkspace.CreateWorkspaceAsync(solution); return(await OmniSharpProject.Create(solution, filePath)); }
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; } }; }