public static IEnumerable<SyntaxNode> GetUnnecessaryImports(SemanticModel semanticModel, SyntaxNode root, CancellationToken cancellationToken) { var diagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); if (!diagnostics.Any()) { return null; } var unnecessaryImports = new HashSet<UsingDirectiveSyntax>(); foreach (var diagnostic in diagnostics) { if (diagnostic.Id == "CS8019") { var node = root.FindNode(diagnostic.Location.SourceSpan) as UsingDirectiveSyntax; if (node != null) { unnecessaryImports.Add(node); } } } if (cancellationToken.IsCancellationRequested || !unnecessaryImports.Any()) { return null; } return unnecessaryImports; }
private static IEnumerable <SyntaxNode> GetUnusedUsings(SemanticModel model) { SyntaxNode root = model.SyntaxTree.GetRoot(); // find unused Usings with the help of compiler warning code List <SyntaxNode> unusedUsings = new List <SyntaxNode>(); foreach (var diagnostic in model.GetDiagnostics(null).Where(d => d.Id == "CS8019" || d.Id == "CS0105")) { var usingSyntax = root.FindNode(diagnostic.Location.SourceSpan, false, false) as UsingDirectiveSyntax; if (usingSyntax != null) { unusedUsings.Add(usingSyntax); } } return(unusedUsings); }
private static HashSet <SyntaxNode> GetUnusedImportDirectives(SemanticModel model, SyntaxNode root, CancellationToken cancellationToken, Func <SyntaxNode, UsingDirectiveSyntax, bool> markUsingAsUnused) { var unusedImportDirectives = new HashSet <SyntaxNode>(); foreach (var diagnostic in model.GetDiagnostics(null, cancellationToken).Where(d => d.Id == "CS8019" || d.Id == "CS0105")) { var usingDirectiveSyntax = root.FindNode(diagnostic.Location.SourceSpan, false, false) as UsingDirectiveSyntax; if (usingDirectiveSyntax != null) { if (markUsingAsUnused(root, usingDirectiveSyntax)) { unusedImportDirectives.Add(usingDirectiveSyntax); } } } return(unusedImportDirectives); }
protected override void GetUnusedNamespaceImports(SemanticModel model, HashSet <SyntaxNode> namespaceImports, CancellationToken cancellationToken) { var root = model.SyntaxTree.GetRoot(); var diagnostics = model.GetDiagnostics(cancellationToken: cancellationToken); foreach (var diagnostic in diagnostics) { if (diagnostic.Id == CS8019_UnusedUsingDirective) { var node = root.FindNode(diagnostic.Location.SourceSpan) as UsingDirectiveSyntax; if (node != null) { namespaceImports.Add(node); } } } }
public BilibiliCSharpHighlight(string code, bool showError = false, IEnumerable <string> withReferences = null) { this.code = code ?? throw new ArgumentNullException(nameof(code)); styles = new StyleIndex[code.Length]; this.showError = showError; var references = defaultReferences; if (withReferences != null) { references = references.Concat(withReferences.Select(f => MetadataReference.CreateFromFile(f))); } var syntaxTree = CSharpSyntaxTree.ParseText(code, new CSharpParseOptions(LanguageVersion.CSharp8, DocumentationMode.Diagnose, SourceCodeKind.Regular)); var compilation = CSharpCompilation.Create("Bilibili.Highlight", Enumerable.Repeat(syntaxTree, 1), options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary).WithAllowUnsafe(true)).WithReferences(references); model = compilation.GetSemanticModel(syntaxTree, false); var diagnostics = model.GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error).ToArray(); if (diagnostics.Length > 0) { foreach (var d in diagnostics) { Console.WriteLine(d); } Console.WriteLine(); } SetSyntaxStyle(syntaxTree.GetRoot()); var trivias = syntaxTree.GetRoot().DescendantTrivia().ToArray(); foreach (var t in trivias) { if (GetCommentStyle(t.Kind()) is StyleIndex style) { styles.AsSpan(t.FullSpan.Start, t.FullSpan.End - t.FullSpan.Start).Fill(style); } SetDocumentationComment(t); } }
private void GetSemantic(string code, out SemanticModel model, out int pos) { var tree = CSharpSyntaxTree.ParseText(code); //var writer = new ConsoleDumpWalker(); //writer.Visit(tree.GetRoot()); var refs = ReferencedAssemblies.Locations .Distinct() .Select(x => MetadataReference.CreateFromFile(x)); var compilation = CSharpCompilation.Create( "MyCompilation", syntaxTrees: new[] { tree }, references: refs); model = compilation.GetSemanticModel(tree); var diags = model.GetDiagnostics(); foreach (var diag in diags) { if (diag.Id == "CS8019") { continue; // Unnecessary using directive. } Console.WriteLine(diag); Assert.Fail(); } var ns = tree.GetRoot().DescendantNodes().OfType <NamespaceDeclarationSyntax>().First(); pos = ns.OpenBraceToken.SpanStart; // if we use that as a "container" then we get what's in the container *only* // not what we want here, then we have to use the position to determine *scope* //var ss = model.GetDeclaredSymbol(ns); }
/// <summary> /// Compile the source code in the Source /// property into a loaded dynamic assembly /// </summary> /// <param name="dbgMode">Whether to compile as a /// debug assembly or a release assembly</param> public void Compile(bool dbgMode = false) { if (SyntaxTree == null) { // Decide where the source code is coming from. If the // SourceStream property is non-null, source code is read // from there. Otherwise it comes from the Source property. if (SourceStream != null) { using (var ipTextReader = new StreamReader(SourceStream)) Source = ipTextReader.ReadToEnd(); } if (string.IsNullOrWhiteSpace(Source)) { throw new InvalidOperationException("No source code to compile"); } GenerateSyntaxTree(); } var options = new CSharpCompilationOptions ( OutputKind.DynamicallyLinkedLibrary, optimizationLevel: dbgMode ? OptimizationLevel.Debug : OptimizationLevel.Release, allowUnsafe: true ); Compilation = CSharpCompilation.Create (AssemblyName, Enumerable.Repeat(SyntaxTree, 1), metaDataReferences, options); SemanticModel = Compilation.GetSemanticModel(SyntaxTree); Diagnostics = SemanticModel.GetDiagnostics(); if (!HasErrors) { EmitAssembly(dbgMode); } }
/// <remarks>These are tidied up so we can add as many GlobalImports as we want when building compilations</remarks> private CSharpSyntaxNode TidyUsings(CSharpSyntaxNode root) { var diagnostics = _semanticModel.GetDiagnostics().ToList(); var unusedUsings = diagnostics .Where(d => d.Id == UnusedUsingDiagnosticId) .Select(d => root.FindNode(d.Location.SourceSpan)) .OfType <UsingDirectiveSyntax>() .ToList(); var nodesWithUnresolvedTypes = diagnostics .Where(d => d.Id == UnresolvedTypeOrNamespaceDiagnosticId && d.Location.IsInSource) .Select(d => root.FindNode(d.Location.SourceSpan)) .ToLookup(d => d.GetAncestor <UsingDirectiveSyntax>()); unusedUsings = unusedUsings.Except(nodesWithUnresolvedTypes.Select(g => g.Key)).ToList(); if (nodesWithUnresolvedTypes[null].Any() || !unusedUsings.Any()) { return(root); } return(root.RemoveNodes(unusedUsings, SyntaxRemoveOptions.KeepNoTrivia)); }
internal static Diagnostic GetDiagnostic( this SemanticModel semanticModel, string id, TextSpan?span = null, CancellationToken cancellationToken = default) { if (semanticModel == null) { throw new ArgumentNullException(nameof(semanticModel)); } ImmutableArray <Diagnostic> diagnostics = semanticModel.GetDiagnostics(span, cancellationToken); for (int i = 0; i < diagnostics.Length; i++) { if (string.Equals(diagnostics[i].Id, id, StringComparison.Ordinal)) { return(diagnostics[i]); } } return(null); }
CompilationResult CheckSemanticModel(Microsoft.CodeAnalysis.SyntaxTree syntaxTree, string sourceFilePath, AssemblyType assemblyType, CompilationResult compilationResult) { SemanticModel semanticModel = GetSemanticModel(syntaxTree); // run all the semantic code analyzers var diagnostics = new List <CompilerError>(); Profiler.BeginSample("GetDiagnostics"); ImmutableArray <Diagnostic> rawDiagnostics = semanticModel.GetDiagnostics(); Profiler.EndSample(); Profiler.BeginSample("ProcessDiagnostics"); ProcessDiagnostics(rawDiagnostics, diagnostics); Profiler.EndSample(); Profiler.BeginSample("Format"); var codeText = syntaxTree.GetText().ToString(); compilationResult.sourceCode[(int)SourceCodePhases.Final] = codeText; Profiler.EndSample(); if (diagnostics.Any()) { compilationResult.status = CompilationStatus.Failed; compilationResult.errors = diagnostics; } else { compilationResult.status = CompilationStatus.Succeeded; } return(compilationResult); }
static CompilationResult CheckSemanticModel(Microsoft.CodeAnalysis.SyntaxTree syntaxTree, CompilationResult compilationResult) { SemanticModel semanticModel = GetSemanticModel(syntaxTree); // run all the semantic code analyzers var diagnostics = new List <CompilerError>(); Profiler.BeginSample("GetDiagnostics"); ImmutableArray <Diagnostic> rawDiagnostics = semanticModel.GetDiagnostics(); Profiler.EndSample(); Profiler.BeginSample("ProcessDiagnostics"); ProcessDiagnostics(rawDiagnostics, diagnostics); Profiler.EndSample(); if (diagnostics.Any()) { compilationResult.errors = diagnostics; } return(compilationResult); }
/// <summary> /// Verifies that refactoring will be applied correctly using specified <typeparamref name="TRefactoringProvider"/>. /// </summary> /// <param name="data"></param> /// <param name="expected"></param> /// <param name="options"></param> /// <param name="cancellationToken"></param> public async Task VerifyRefactoringAsync( RefactoringTestData data, ExpectedTestState expected, TestOptions options = null, CancellationToken cancellationToken = default) { if (data == null) { throw new ArgumentNullException(nameof(data)); } if (expected == null) { throw new ArgumentNullException(nameof(expected)); } if (data.Spans.IsEmpty) { Fail("Span on which a refactoring should be invoked was not found."); } options ??= Options; TRefactoringProvider refactoringProvider = Activator.CreateInstance <TRefactoringProvider>(); foreach (TextSpan span in data.Spans) { cancellationToken.ThrowIfCancellationRequested(); using (Workspace workspace = new AdhocWorkspace()) { (Document document, ImmutableArray <ExpectedDocument> expectedDocuments) = CreateDocument(workspace.CurrentSolution, data.Source, data.AdditionalFiles, options); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken); ImmutableArray <Diagnostic> compilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); VerifyCompilerDiagnostics(compilerDiagnostics, options); CodeAction action = null; List <CodeAction> candidateActions = null; var context = new CodeRefactoringContext( document, span, a => { if (data.EquivalenceKey == null || string.Equals(a.EquivalenceKey, data.EquivalenceKey, StringComparison.Ordinal)) { if (action != null) { Fail($"Multiple refactorings registered by '{refactoringProvider.GetType().Name}'.", new CodeAction[] { action, a }); } action = a; } else { (candidateActions ??= new List <CodeAction>()).Add(a); } },
public static void VerifyDiagnostics(SemanticModel model, string source, string pattern, params string[] expectedDiagnosticIds) { VerifyDiagnostics(model.GetDiagnostics(FindSpan(source, pattern)), expectedDiagnosticIds); }
public async Task VerifyRefactoringAsync( string source, string expected, TextSpan span, string equivalenceKey = null, string[] additionalSources = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); Document document = CreateDocument(source, additionalSources ?? Array.Empty <string>()); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> compilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); if (options == null) { options = Options; } VerifyCompilerDiagnostics(compilerDiagnostics, options); CodeAction action = null; var context = new CodeRefactoringContext( document, span, a => { if (equivalenceKey == null || string.Equals(a.EquivalenceKey, equivalenceKey, StringComparison.Ordinal)) { if (action == null) { action = a; } } }, CancellationToken.None); await RefactoringProvider.ComputeRefactoringsAsync(context).ConfigureAwait(false); Assert.True(action != null, "No code refactoring has been registered."); document = await document.ApplyCodeActionAsync(action).ConfigureAwait(false); semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> newCompilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); VerifyCompilerDiagnostics(newCompilerDiagnostics, options); if (!options.AllowNewCompilerDiagnostics) { VerifyNoNewCompilerDiagnostics(compilerDiagnostics, newCompilerDiagnostics, options); } string actual = await document.ToFullStringAsync(simplify : true, format : true).ConfigureAwait(false); Assert.Equal(expected, actual); }
private void CreateToolStrip(string declarationFilter) { // Syntax and trivia toggles _syntaxTokenCheckBox = new CheckBox() { BackColor = Color.Transparent, Checked = true, }; _syntaxTriviaCheckBox = new CheckBox() { BackColor = Color.Transparent, Checked = true, }; bool handleChecked = true; // Prevent double handling from adjustments during another handler _syntaxTokenCheckBox.CheckedChanged += (x, e) => { if (handleChecked) { if (!_syntaxTokenCheckBox.Checked) { handleChecked = false; _syntaxTriviaCheckBox.Checked = false; handleChecked = true; } if (_syntaxTokenCheckBox.Checked && _syntaxTriviaCheckBox.Checked) { _treeList.ModelFilter = null; } _treeList.ModelFilter = new SyntaxFilter(_syntaxTokenCheckBox.Checked, _syntaxTriviaCheckBox.Checked); PopulateGraph(); } }; _syntaxTriviaCheckBox.CheckedChanged += (x, e) => { if (handleChecked) { if (!_syntaxTokenCheckBox.Checked) { handleChecked = false; _syntaxTokenCheckBox.Checked = true; handleChecked = true; } if (_syntaxTokenCheckBox.Checked && _syntaxTriviaCheckBox.Checked) { _treeList.ModelFilter = null; } _treeList.ModelFilter = new SyntaxFilter(_syntaxTokenCheckBox.Checked, _syntaxTriviaCheckBox.Checked); PopulateGraph(); } }; // Semantics toggle and diagnostics button _semanticsCheckBox = new CheckBox() { BackColor = Color.Transparent }; _semanticsCheckBox.CheckedChanged += (x, e) => { GetSemanticModel(); }; _diagnosticsButton = new ToolStripButton("Dump Diagnostics", null, (x, e) => { SemanticModel semanticModel = GetSemanticModel(); if (semanticModel != null) { // Exclude duplicate mscorlib reference warnings (referenced in LINQPad.Codeanalysis because ObjectListView is .NET 2.0) semanticModel.GetDiagnostics() .Where(y => y.Id != "CS1701" && !y.Descriptor.Description.ToString().Contains("mscorlib")) .Dump(); } }); // Declaration filter ToolStripTextBox declarationFilterTextBox = new ToolStripTextBox(); if (!string.IsNullOrWhiteSpace(declarationFilter)) { declarationFilterTextBox.Text = declarationFilter; } declarationFilterTextBox.KeyDown += (x, e) => { if (e.KeyCode == Keys.Enter) { SetRoots(declarationFilterTextBox.Text); } }; declarationFilterTextBox.LostFocus += (x, e) => { SetRoots(declarationFilterTextBox.Text); }; // Layout _toolStrip = new ToolStrip( new ToolStripButton("Expand All", null, (x, e) => _treeList.ExpandAll()), new ToolStripButton("Collapse All", null, (x, e) => _treeList.CollapseAll()), new ToolStripSeparator(), new ToolStripLabel("SyntaxNode ") { ForeColor = Color.Blue }, new ToolStripControlHost(_syntaxTokenCheckBox), new ToolStripLabel("SyntaxToken ") { ForeColor = Color.Green }, new ToolStripControlHost(_syntaxTriviaCheckBox), new ToolStripLabel("SyntaxTrivia ") { ForeColor = Color.Maroon }, new ToolStripSeparator(), new ToolStripLabel("Declaration Filter"), declarationFilterTextBox, new ToolStripSeparator(), new ToolStripLabel(" "), new ToolStripControlHost(_semanticsCheckBox), new ToolStripLabel("Semantics "), _diagnosticsButton) { GripStyle = ToolStripGripStyle.Hidden, Renderer = new BorderlessToolStripRenderer(), Padding = new Padding(4) }; _toolStrip.Layout += (x, e) => _toolStrip.Width = _toolStrip.Parent.Width; }
public async Task VerifyRefactoringAsync( string source, string expected, TextSpan span, IEnumerable <string> additionalSources = null, string equivalenceKey = null, CodeVerificationOptions options = null, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); options ??= Options; using (Workspace workspace = new AdhocWorkspace()) { Project project = WorkspaceFactory.AddProject(workspace.CurrentSolution, options); Document document = WorkspaceFactory.AddDocument(project, source, additionalSources); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> compilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); VerifyCompilerDiagnostics(compilerDiagnostics, options); CodeAction action = null; var context = new CodeRefactoringContext( document, span, a => { if (equivalenceKey == null || string.Equals(a.EquivalenceKey, equivalenceKey, StringComparison.Ordinal)) { if (action == null) { action = a; } } }, CancellationToken.None); await RefactoringProvider.ComputeRefactoringsAsync(context).ConfigureAwait(false); Assert.True(action != null, "No code refactoring has been registered."); document = await document.ApplyCodeActionAsync(action).ConfigureAwait(false); semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ImmutableArray <Diagnostic> newCompilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); VerifyCompilerDiagnostics(newCompilerDiagnostics, options); VerifyNoNewCompilerDiagnostics(compilerDiagnostics, newCompilerDiagnostics, options); string actual = await document.ToFullStringAsync(simplify : true, format : true, cancellationToken).ConfigureAwait(false); Assert.Equal(expected, actual); } }
static CommandInfoSet CreateFixMenu(TextEditor editor, DocumentContext ctx, SemanticModel semanticModel, CodeActionContainer container) { if (editor == null) { throw new ArgumentNullException(nameof(editor)); } if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } if (container == null) { throw new ArgumentNullException(nameof(container)); } var result = new CommandInfoSet(); result.Text = GettextCatalog.GetString("Fix"); foreach (var diagnostic in container.CodeFixActions) { var info = new CommandInfo(diagnostic.CodeAction.Title); result.CommandInfos.Add(info, new Action(async() => await new CodeActionEditorExtension.ContextActionRunner(diagnostic.CodeAction, editor, ctx).Run())); } bool firstDiagnosticOption = result.CommandInfos.Count != 0; var warningsAtCaret = semanticModel .GetDiagnostics(new TextSpan(editor.CaretOffset, 0)) .Where(diag => diag.Severity == DiagnosticSeverity.Warning).ToList(); foreach (var warning in warningsAtCaret) { if (firstDiagnosticOption) { result.CommandInfos.AddSeparator(); firstDiagnosticOption = false; } var label = GettextCatalog.GetString("_Options for \"{0}\"", warning.Descriptor.Title); var subMenu = new CommandInfoSet(); subMenu.Text = label; var info = new CommandInfo(GettextCatalog.GetString("_Suppress with #pragma")); subMenu.CommandInfos.Add(info, new Action(async delegate { var fixes = await CSharpSuppressionFixProvider.Instance.GetSuppressionsAsync(ctx.AnalysisDocument, new TextSpan(editor.CaretOffset, 0), new [] { warning }, default(CancellationToken)).ConfigureAwait(false); foreach (var f in fixes) { CodeDiagnosticDescriptor.RunAction(ctx, f.Action, default(CancellationToken)); } })); result.CommandInfos.Add(subMenu); } foreach (var fix in container.DiagnosticsAtCaret) { var inspector = BuiltInCodeDiagnosticProvider.GetCodeDiagnosticDescriptor(fix.Id); if (inspector == null) { continue; } if (firstDiagnosticOption) { result.CommandInfos.AddSeparator(); firstDiagnosticOption = false; } var label = GettextCatalog.GetString("_Options for \"{0}\"", fix.GetMessage()); var subMenu = new CommandInfoSet(); subMenu.Text = label; // if (inspector.CanSuppressWithAttribute) { // var menuItem = new FixMenuEntry (GettextCatalog.GetString ("_Suppress with attribute"), // delegate { // // inspector.SuppressWithAttribute (Editor, DocumentContext, GetTextSpan (fix.Item2)); // }); // subMenu.Add (menuItem); // } if (inspector.CanDisableWithPragma) { var info = new CommandInfo(GettextCatalog.GetString("_Suppress with #pragma")); subMenu.CommandInfos.Add(info, new Action(() => inspector.DisableWithPragma(editor, ctx, fix))); info = new CommandInfo(GettextCatalog.GetString("_Suppress with file")); subMenu.CommandInfos.Add(info, new Action(() => inspector.DisableWithFile(editor, ctx, fix))); } var configInfo = new CommandInfo(GettextCatalog.GetString("_Configure Rule")); subMenu.CommandInfos.Add(configInfo, new Action(() => { IdeApp.Workbench.ShowGlobalPreferencesDialog(null, "C#", dialog => { var panel = dialog.GetPanel <CodeIssuePanel> ("C#"); if (panel == null) { return; } panel.Widget.SelectCodeIssue(inspector.IdString); }); })); foreach (var fix2 in container.CodeFixActions) { var provider = fix2.Diagnostic.GetCodeFixProvider().GetFixAllProvider(); if (provider == null) { continue; } if (!provider.GetSupportedFixAllScopes().Contains(FixAllScope.Document)) { continue; } var subMenu2 = new CommandInfoSet(); subMenu2.Text = GettextCatalog.GetString("Fix all"); var diagnosticAnalyzer = fix2.Diagnostic.GetCodeDiagnosticDescriptor(LanguageNames.CSharp).GetProvider(); if (!diagnosticAnalyzer.SupportedDiagnostics.Contains(fix.Descriptor)) { continue; } var info = new CommandInfo(GettextCatalog.GetString("In _Document")); subMenu2.CommandInfos.Add(info, new Action(async delegate { var fixAllDiagnosticProvider = new CodeActionEditorExtension.FixAllDiagnosticProvider(diagnosticAnalyzer.SupportedDiagnostics.Select(d => d.Id).ToImmutableHashSet(), async(Microsoft.CodeAnalysis.Document doc, ImmutableHashSet <string> diagnostics, CancellationToken token) => { var model = await doc.GetSemanticModelAsync(token); var compilationWithAnalyzer = model.Compilation.WithAnalyzers(new [] { diagnosticAnalyzer }.ToImmutableArray(), null, token); return(await compilationWithAnalyzer.GetAnalyzerSemanticDiagnosticsAsync(model, null, token)); }, (arg1, arg2, arg3, arg4) => { return(Task.FromResult((IEnumerable <Diagnostic>) new Diagnostic [] { })); }); var ctx2 = new FixAllContext( ctx.AnalysisDocument, fix2.Diagnostic.GetCodeFixProvider(), FixAllScope.Document, fix2.CodeAction.EquivalenceKey, diagnosticAnalyzer.SupportedDiagnostics.Select(d => d.Id), fixAllDiagnosticProvider, default(CancellationToken) ); var fixAll = await provider.GetFixAsync(ctx2); using (var undo = editor.OpenUndoGroup()) { CodeDiagnosticDescriptor.RunAction(ctx, fixAll, default(CancellationToken)); } })); subMenu.CommandInfos.Add(subMenu2); } result.CommandInfos.Add(subMenu); } return(result); }
/// <summary> /// Performs all steps of the translation, as detailed in the thesis, except for verification. /// </summary> /// <exception cref="InvalidOperationException">The process was already executed once.</exception> public TranslationProcessResult Execute() { if (this.executed) { throw new InvalidOperationException("The process was already executed once."); } this.executed = true; VerboseLog("Loading mscorlib and Soothsharp.Contracts..."); var mscorlib = MetadataReference.CreateFromFile(typeof(Attribute).Assembly.Location); var contractsLibrary = MetadataReference.CreateFromFile(typeof(Contracts.Contract).Assembly.Location); var systemCore = MetadataReference.CreateFromFile(typeof(ParallelQuery).Assembly.Location); VerboseLog("Initializing compilation..."); CSharpCompilation compilation; try { compilation = CSharpCompilation.Create("translated_assembly", this.compilationUnits.Select(unit => unit.RoslynTree), (new[] { mscorlib, contractsLibrary, systemCore }).Union(this.referencedAssemblies.Select(filename => MetadataReference.CreateFromFile(filename))) ); } catch (System.IO.IOException exception) { return(TranslationProcessResult.Error(null, Diagnostics.SSIL112_FileNotFound, exception.Message)); } VerboseLog("Processing trees..."); HighlevelSequenceSilvernode masterTree = new HighlevelSequenceSilvernode(null); foreach (CompilationUnit compilationUnit in this.compilationUnits) { VerboseLog("Processing " + compilationUnit.RoslynTree.FilePath + "..."); VerboseLog("- Semantic analysis..."); SemanticModel semanticModel = compilation.GetSemanticModel(compilationUnit.RoslynTree, false); VerboseLog("- CONVERSION PHASE begins..."); Sharpnode cSharpTree; #if GLOBAL_TRY_CATCH try { #endif cSharpTree = new CompilationUnitSharpnode(compilationUnit.RoslynTree.GetRoot() as CompilationUnitSyntax); #if GLOBAL_TRY_CATCH } catch (Exception ex) { this.masterErrorList.Add(new Error(Diagnostics.SSIL103_ExceptionConstructingCSharp, compilationUnit.RoslynTree.GetRoot(), ex.ToString())); continue; } #endif VerboseLog("- COLLECTION PHASE begins..."); cSharpTree.CollectTypesInto(this, semanticModel); VerboseLog("- MAIN PHASE begins..."); TranslationResult translationResult; var diags = semanticModel.GetDiagnostics().ToList(); bool skipTranslatingThisTree = false; foreach (var diag in diags) { if (diag.Severity != Microsoft.CodeAnalysis.DiagnosticSeverity.Error) { continue; } masterErrorList.Add(new Error(Diagnostics.SSIL123_ThereIsThisCSharpError, null, diag.ToString())); skipTranslatingThisTree = true; } if (!skipTranslatingThisTree) { #if GLOBAL_TRY_CATCH try { #endif translationResult = cSharpTree.Translate(TranslationContext.StartNew(this, semanticModel, this.Configuration.VerifyUnmarkedItems, compilationUnit.Style)); #if GLOBAL_TRY_CATCH } catch (Exception ex) { this.masterErrorList.Add(new Error(Diagnostics.SSIL104_ExceptionConstructingSilver, compilationUnit.RoslynTree.GetRoot(), ex.ToString())); continue; } #endif masterTree.List.Add(translationResult.Silvernode); this.masterErrorList.AddRange(translationResult.Errors); } } VerboseLog("GLOBAL ADDITION PHASE begins..."); foreach (var collectedType in this.collectedTypes) { masterTree.List.Add(collectedType.GenerateGlobalSilvernode(this)); } if (this.ArraysTranslator.ArraysWereUsed) { masterTree.List.Add(this.ArraysTranslator.GenerateGlobalSilvernode()); } VerboseLog("OPTIMIZATION PHASE begins..."); masterTree.OptimizeRecursively(); VerboseLog("NAME ASSIGNMENT PHASE begins..."); this.IdentifierTranslator.AssignTrueNames(); VerboseLog("POSTPROCESSING PHASE begins..."); masterTree.Postprocess(); return(new TranslationProcessResult(masterTree, this.masterErrorList)); }
public Visitor(SemanticModel model) : base(SyntaxWalkerDepth.Trivia) { _model = model; _modelDiagnostic = _model.GetDiagnostics(); }
/// <summary> /// Verifies that refactoring will be applied correctly using specified <typeparamref name="TRefactoringProvider"/>. /// </summary> /// <param name="state"></param> /// <param name="expected"></param> /// <param name="options"></param> /// <param name="cancellationToken"></param> public async Task VerifyRefactoringAsync( RefactoringTestState state, ExpectedTestState expected, TestOptions options = null, CancellationToken cancellationToken = default) { if (state.Spans.IsEmpty) { Assert.True(false, "Span on which a refactoring should be invoked was not found."); } options ??= Options; TRefactoringProvider refactoringProvider = Activator.CreateInstance <TRefactoringProvider>(); foreach (TextSpan span in state.Spans) { cancellationToken.ThrowIfCancellationRequested(); using (Workspace workspace = new AdhocWorkspace()) { (Document document, ImmutableArray <ExpectedDocument> expectedDocuments) = CreateDocument(workspace.CurrentSolution, state.Source, state.AdditionalFiles, options); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken); ImmutableArray <Diagnostic> compilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); VerifyCompilerDiagnostics(compilerDiagnostics, options); CodeAction action = null; var context = new CodeRefactoringContext( document, span, a => { if (state.EquivalenceKey == null || string.Equals(a.EquivalenceKey, state.EquivalenceKey, StringComparison.Ordinal)) { if (action != null) { Assert.True(false, "Multiple fixes available."); } action = a; } }, cancellationToken); await refactoringProvider.ComputeRefactoringsAsync(context); Assert.True(action != null, "No code refactoring has been registered."); document = await VerifyAndApplyCodeActionAsync(document, action, expected.CodeActionTitle); semanticModel = await document.GetSemanticModelAsync(cancellationToken); ImmutableArray <Diagnostic> newCompilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); VerifyCompilerDiagnostics(newCompilerDiagnostics, options); VerifyNoNewCompilerDiagnostics(compilerDiagnostics, newCompilerDiagnostics, options); await VerifyExpectedDocument(expected, document, cancellationToken); } } }
public Rewriter(SemanticModel pModel) { model = pModel; diagonists = pModel.GetDiagnostics(); }
public override async Task <(Example withSource, Example withoutSource)> AddExample(string className, bool isFlawed, List <string> fileContents) { //Console.WriteLine("AddExample"); StringBuilder features; SyntaxTree syntaxTree; string withoutComments = null; //if (fileContents[0].Contains("MainClass4420{")) //{ withoutComments = RemoveComments(fileContents); features = new StringBuilder(); features.AppendLine(); syntaxTree = CSharpSyntaxTree.ParseText(withoutComments); SyntaxNode root = syntaxTree.GetRoot(); CSharpCompilation compilation = CreateCompilation(syntaxTree); SemanticModel semanticModel = compilation.GetSemanticModel(syntaxTree); #if DEBUG if (semanticModel.GetDiagnostics().Any(d => d.Severity == DiagnosticSeverity.Error)) { foreach (Diagnostic diagnostic in semanticModel.GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error)) { Console.WriteLine(diagnostic.GetMessage()); Console.WriteLine($"{diagnostic.Location.GetLineSpan().Path} {diagnostic.Location.GetLineSpan().StartLinePosition} {diagnostic.Location.GetLineSpan().EndLinePosition}"); } Console.WriteLine(root); Console.WriteLine("Included assemblies: "); foreach (var assembly in compilation.References) { Console.WriteLine(assembly.Display); } Console.ReadLine(); } #endif foreach (SyntaxNode syntaxNode in root.DescendantNodes()) { if ( syntaxNode is ExpressionSyntax expressionSyntax && ( syntaxNode.IsKind(SyntaxKind.InvocationExpression) || syntaxNode.IsKind(SyntaxKind.ObjectCreationExpression) ) && await IsReachable(syntaxNode) ) { string signature = await BuildMethodSignature(expressionSyntax, semanticModel); features.AppendLine(signature); } if (syntaxNode is AssignmentExpressionSyntax assignmentExpressionSyntax && await IsReachable(assignmentExpressionSyntax)) { ISymbol leftSymbol = semanticModel.GetSymbolInfo(assignmentExpressionSyntax.Left).Symbol; if (leftSymbol is IPropertySymbol) { string signature = await BuildMethodSignature(assignmentExpressionSyntax.Left, semanticModel); features.AppendLine(signature); } } if (syntaxNode.IsKind(SyntaxKind.StringLiteralExpression) && syntaxNode.ToString().Contains("^[0-9]*") && await IsReachable(syntaxNode)) { features.AppendLine("HasNumbersOnlyRegex"); //break; } if (syntaxNode.IsKind(SyntaxKind.StringLiteralExpression) && syntaxNode.ToString().Contains(@"^[\\.\\.\\/]+") && await IsReachable(syntaxNode)) { features.AppendLine("HasPathTraversalRegex"); //break; } } // PrintDescendentNodes(root, semanticModel); // Console.WriteLine(withoutComments); // Console.WriteLine(features); // Console.ReadLine(); //} //else //{ // features = new StringBuilder(); //} //Console.WriteLine("Returning Example."); return(AddExamples(className, isFlawed, features, withoutComments)); }
private static void Main(string[] args) { string[] types = { "sbyte", "short", "int", "long", "byte", "ushort", "uint", "ulong", "char", "bool" }; string[] shortNames = { "i08", "i16", "i32", "i64", "u08", "u16", "u32", "u64", "chr", "bol" }; Console.WriteLine("// {0}", string.Join(" ", shortNames)); for (int i = 0; i < types.Length; i++) { Console.Write($"/*{shortNames[i]}*/ {{ "); for (int j = 0; j < types.Length; j++) { if (j > 0) { Console.Write(", "); } SyntaxTree tree = SyntaxFactory.ParseSyntaxTree($@" class C {{ public static void Main() {{ {types[i]} v1 = default; {types[j]} v2 = default; bool b = v1 == v2; }} }}", new CSharpParseOptions(LanguageVersion.CSharp7_3)); CSharpCompilation comp = CSharpCompilation.Create( "R", new[] { tree }, new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location) }); SemanticModel model = comp.GetSemanticModel(tree); if (model.GetDiagnostics().Any(d => d.Severity == DiagnosticSeverity.Error)) { Console.Write("ERR"); continue; } var node = (BinaryExpressionSyntax)tree.GetRoot().DescendantNodes().Single(f => f is BinaryExpressionSyntax); IMethodSymbol symbol = (IMethodSymbol)model.GetSymbolInfo(node).Symbol; Trace.Assert(symbol.Parameters.Length == 2 && symbol.Parameters[0].Type == symbol.Parameters[1].Type); switch (symbol.Parameters[0].Type.SpecialType) { case SpecialType.System_Int32: Console.Write("I32"); break; case SpecialType.System_Int64: Console.Write("I64"); break; case SpecialType.System_UInt32: Console.Write("U32"); break; case SpecialType.System_UInt64: Console.Write("U64"); break; case SpecialType.System_Boolean: Console.Write("BOL"); break; default: throw new Exception("wtf"); } } Console.WriteLine(" },"); } Console.ReadLine(); }
IEnumerable <ITagSpan <NugetPackageTag> > ITagger <NugetPackageTag> .GetTags(NormalizedSnapshotSpanCollection spans) { // TODO temporary if (true) { return(Enumerable.Empty <ITagSpan <NugetPackageTag> >()); } var projectsMap = new Dictionary <string, IEnumerable <ProjectMetadata> >(StringComparer.OrdinalIgnoreCase); var resultTags = new List <ITagSpan <NugetPackageTag> >(); foreach (var span in spans) { try { if (span.Snapshot == null) { continue; } var document = span.Snapshot.GetOpenDocumentInCurrentContextWithChanges(); if (document == null) { continue; } IEnumerable <ProjectMetadata> projects = null; if (projectsMap.Keys.Contains(document.FilePath)) { projects = projectsMap[document.FilePath]; } else { projects = ProjectMetadataProvider.Instance.GetProjects(document.FilePath); projectsMap.Add(document.FilePath, projects); } if (projects == null || !projects.Any()) { // project is unsupported continue; } SemanticModel model = null; ThreadHelper.JoinableTaskFactory.Run(async delegate { model = await document.GetSemanticModelAsync(); }); if (model == null) { continue; } var currentSpanLine = span.Start.GetContainingLine(); if (currentSpanLine == null || currentSpanLine.LineNumber < 0) { continue; } var analyzer = _analyzerFactory.GetAnalyzer(document.FilePath); if (analyzer == null) { // language is unsupported continue; } var diagnostics = model.GetDiagnostics(); if (diagnostics.Any(x => { if (analyzer.SyntaxHelper.SupportedDiagnostics.Any(y => y.Equals(x.Id)) && x.Location.GetLineSpan().StartLinePosition.Line == currentSpanLine.LineNumber) { var suggestions = analyzer.GetSuggestions(x.Location.SourceTree.GetRoot().FindNode(x.Location.SourceSpan), projects); if (suggestions != null && suggestions.Count() > 0) { return(true); } } return(false); })) { resultTags.Add(new TagSpan <NugetPackageTag>(new SnapshotSpan(span.Start, 0), new NugetPackageTag())); } } catch (Exception e) { Debug.Write(e.ToString()); } } return(resultTags); }
private static async Task <(ImmutableArray <Diagnostic> reportedDiagnostics, ImmutableArray <string> unhandledIds)> GetReportedDiagnosticsForIdsAsync( ImmutableHashSet <string> idsToAnalyze, SyntaxNode root, SemanticModel semanticModel, CompilationWithAnalyzers compilationWithAnalyzers, Func <DiagnosticAnalyzer, ImmutableArray <DiagnosticDescriptor> > getSupportedDiagnostics, Func <DiagnosticAnalyzer, bool> getIsCompilationEndAnalyzer, PooledHashSet <string> compilerDiagnosticIds, CancellationToken cancellationToken) { using var _1 = ArrayBuilder <DiagnosticAnalyzer> .GetInstance(out var analyzersBuilder); using var _2 = ArrayBuilder <string> .GetInstance(out var unhandledIds); // First, we compute the relevant analyzers whose reported diagnostics need to be computed. var addedCompilerAnalyzer = false; var hasNonCompilerAnalyzers = idsToAnalyze.Count > compilerDiagnosticIds.Count; foreach (var analyzer in compilationWithAnalyzers.Analyzers) { if (!addedCompilerAnalyzer && analyzer.IsCompilerAnalyzer()) { addedCompilerAnalyzer = true; analyzersBuilder.Add(analyzer); if (!hasNonCompilerAnalyzers) { break; } continue; } if (hasNonCompilerAnalyzers) { Debug.Assert(!analyzer.IsCompilerAnalyzer()); bool?lazyIsUnhandledAnalyzer = null; foreach (var descriptor in getSupportedDiagnostics(analyzer)) { if (!idsToAnalyze.Contains(descriptor.Id)) { continue; } lazyIsUnhandledAnalyzer ??= getIsCompilationEndAnalyzer(analyzer) || analyzer is IPragmaSuppressionsAnalyzer; if (lazyIsUnhandledAnalyzer.Value) { unhandledIds.Add(descriptor.Id); } } if (lazyIsUnhandledAnalyzer.HasValue && !lazyIsUnhandledAnalyzer.Value) { analyzersBuilder.Add(analyzer); } } } // Then, we execute these analyzers on the current file to fetch these diagnostics. // Note that if an analyzer has already executed, then this will be just a cache access // as computed analyzer diagnostics are cached on CompilationWithAnalyzers instance. using var _3 = ArrayBuilder <Diagnostic> .GetInstance(out var reportedDiagnostics); if (!addedCompilerAnalyzer && compilerDiagnosticIds.Count > 0) { // Special case when compiler analyzer could not be found. Debug.Assert(semanticModel.Compilation.Options.ReportSuppressedDiagnostics); reportedDiagnostics.AddRange(root.GetDiagnostics()); reportedDiagnostics.AddRange(semanticModel.GetDiagnostics(cancellationToken: cancellationToken)); cancellationToken.ThrowIfCancellationRequested(); } if (analyzersBuilder.Count > 0) { var analyzers = analyzersBuilder.ToImmutable(); var syntaxDiagnostics = await compilationWithAnalyzers.GetAnalyzerSyntaxDiagnosticsAsync(semanticModel.SyntaxTree, analyzers, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); reportedDiagnostics.AddRange(syntaxDiagnostics); var semanticDiagnostics = await compilationWithAnalyzers.GetAnalyzerSemanticDiagnosticsAsync(semanticModel, filterSpan : null, analyzers, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); reportedDiagnostics.AddRange(semanticDiagnostics); } return(reportedDiagnostics.ToImmutable(), unhandledIds.ToImmutable()); }
internal static async Task ComputeRefactoringAsync(RefactoringContext context, ExpressionSyntax expression) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); foreach (Diagnostic diagnostic in semanticModel.GetDiagnostics(expression.Span, context.CancellationToken)) { if (diagnostic.Id == CSharpErrorCodes.CannotImplicitlyConvertTypeExplicitConversionExists && diagnostic.IsCompilerDiagnostic()) { if (context.Span.IsEmpty || diagnostic.Location.SourceSpan == expression.Span) { expression = expression .Ancestors() .FirstOrDefault(f => f.Span == diagnostic.Location.SourceSpan) as ExpressionSyntax; if (expression != null && semanticModel.GetTypeSymbol(expression, context.CancellationToken)?.IsNullableOf(SpecialType.System_Boolean) == true) { if (semanticModel.GetTypeInfo(expression, context.CancellationToken).ConvertedType?.IsBoolean() == true || IsCondition(expression)) { RegisterRefactoring(context, expression); break; } } } } else if (diagnostic.Id == CSharpErrorCodes.OperatorCannotBeAppliedToOperands && diagnostic.IsCompilerDiagnostic()) { if (context.Span.IsEmpty || diagnostic.Location.SourceSpan == expression.Span) { var binaryExpression = expression .Ancestors() .FirstOrDefault(f => f.Span == diagnostic.Location.SourceSpan) as BinaryExpressionSyntax; if (binaryExpression != null) { ExpressionSyntax left = binaryExpression.Left; if (left.Span.Contains(context.Span)) { if (semanticModel.GetTypeSymbol(left, context.CancellationToken)?.IsNullableOf(SpecialType.System_Boolean) == true) { RegisterRefactoring(context, left); break; } } else { ExpressionSyntax right = binaryExpression.Right; if (right.Span.Contains(context.Span) && semanticModel.GetTypeSymbol(right, context.CancellationToken)?.IsNullableOf(SpecialType.System_Boolean) == true) { RegisterRefactoring(context, right); break; } } } } } } }