public static List<Phrase> GetPhrases(this Tree root, Rhetorica.Sentence sentence = null, string ignore = "", string punctuation = null, AnalyzerOptions options = AnalyzerOptions.None) { var phrases = new List<Phrase>(); for (java.util.Iterator i = root.iterator(); i.hasNext(); ) { Tree tree = (Tree)i.next(); if (tree.isPhrasal()) { java.util.List children = tree.getChildrenAsList(); if (children.size() == 1 && ((Tree)children.get(0)).isPhrasal()) continue; var current = new Phrase(tree.GetTokens(root, sentence, ignore, punctuation, options)); // If current node matches previous node but for punctuation omission, replace previous with current: bool omitFalseDuplicatePhrases = options.HasFlag(AnalyzerOptions.OmitFalseDuplicatePhrases); if (omitFalseDuplicatePhrases) { if (phrases.Count > 0) { Phrase previous = phrases.Last(); if (previous.EqualExceptPunctuationOmission(current)) { phrases[phrases.Count - 1] = current; continue; } } } if (current.Count == 0) continue; phrases.Add(current); } } return phrases; }
public DiagnosticAnalyzerDriver( Project project, BaseDiagnosticIncrementalAnalyzer owner, CancellationToken cancellationToken) { _project = project; _owner = owner; _syntaxNodeAnalyzerService = project.LanguageServices.GetService<ISyntaxNodeAnalyzerService>(); _cancellationToken = cancellationToken; _generatedCodeService = project.Solution.Workspace.Services.GetService<IGeneratedCodeRecognitionService>(); _analyzerDriverService = project.LanguageServices.GetService<IAnalyzerDriverService>(); _analyzerOptions = new WorkspaceAnalyzerOptions(project.AnalyzerOptions, project.Solution.Workspace); _onAnalyzerException = owner.GetOnAnalyzerException(project.Id); _onAnalyzerException_NoTelemetryLogging = owner.GetOnAnalyzerException_NoTelemetryLogging(project.Id); }
public static List<Phrase> GetClauses(this Tree root, Rhetorica.Sentence sentence = null, string ignore = "", string punctuation = null, AnalyzerOptions options = AnalyzerOptions.None) { var phrases = new List<Phrase>(); for (java.util.Iterator i = root.iterator(); i.hasNext(); ) { Tree tree = (Tree)i.next(); var treeLabel = tree.label().value(); var clauseRe = @"^(S|SBAR|SBARQ|SINV|SQ|FRAG)$"; bool isClausal = Regex.IsMatch(treeLabel, clauseRe, RegexOptions.IgnoreCase); if (isClausal) { var current = new Phrase(tree.GetTokens(root, sentence, ignore, punctuation, options)); // If current node matches previous node but for punctuation omission, replace previous with current: bool omitFalseDuplicatePhrases = options.HasFlag(AnalyzerOptions.OmitFalseDuplicatePhrases); if (omitFalseDuplicatePhrases) { if (phrases.Count > 0) { Phrase previous = phrases.Last(); if (previous.EqualExceptPunctuationOmission(current)) { phrases[phrases.Count - 1] = current; continue; } } } if (current.Count == 0) continue; phrases.Add(current); } } if (phrases.Count == 0) { // Since 'root' has been identified as a sentence, it should have at least one clause associated with it. var pseudoClauses = root.GetPhrases(sentence, ignore, punctuation, options); if (pseudoClauses.Count > 0) phrases.Add(pseudoClauses[0]); } return phrases; }
public void AnalyzeSymbol(ISymbol symbol, Compilation compilation, Action <Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken) { var methodSymbol = (IMethodSymbol)symbol; var httpControllerInterfaceSymbol = compilation.GetTypeByMetadataName("System.Web.Http.Controllers.IHttpController"); if (methodSymbol.ContainingType.AllInterfaces.Any(x => x.MetadataName == httpControllerInterfaceSymbol.MetadataName)) { var postAttributeSymbol = compilation.GetTypeByMetadataName("System.Web.Http.HttpPostAttribute"); if (methodSymbol.ReturnsVoid && (methodSymbol.MetadataName.ToLowerInvariant().StartsWith("post") || methodSymbol.GetAttributes().Any(x => x.AttributeClass.MetadataName == postAttributeSymbol.MetadataName))) { var diagnostic = Diagnostic.Create(Rule, methodSymbol.Locations[0], methodSymbol.Name); addDiagnostic(diagnostic); } } }
protected abstract void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilation, Action <Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken);
public void AnalyzeNode(SyntaxNode node, SemanticModel semanticModel, Action <Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken) { SwitchStatementSyntax switchNode = (SwitchStatementSyntax)node; if (!HasAtLeastThreeLabels(switchNode)) { addDiagnostic(Diagnostic.Create(Rule, node.GetLocation())); } }
protected override void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilation, Action <Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken) { if (symbol.IsAbstract) { // TODO: Should we also check symbol.GetResultantVisibility() == SymbolVisibility.Public? var hasAnyPublicConstructors = symbol.InstanceConstructors.Any( (constructor) => constructor.DeclaredAccessibility == Accessibility.Public); if (hasAnyPublicConstructors) { addDiagnostic(symbol.CreateDiagnostic(Rule, symbol.Name)); } } }
private CompilationWithAnalyzers GetCompilationWithAnalyzers([NotNull] Document document, TestValidationMode validationMode, [NotNull] AnalyzerOptions options) { ImmutableArray <DiagnosticAnalyzer> analyzers = ImmutableArray.Create(CreateAnalyzer()); Compilation compilation = document.Project.GetCompilationAsync().Result; ImmutableArray <Diagnostic> compilerDiagnostics = compilation.GetDiagnostics(CancellationToken.None); if (validationMode != TestValidationMode.AllowCompileErrors) { ValidateCompileErrors(compilerDiagnostics); } return(compilation.WithAnalyzers(analyzers, options)); }
protected bool TrySimplifyTypeNameExpression(SemanticModel model, SyntaxNode node, AnalyzerOptions analyzerOptions, out Diagnostic diagnostic, CancellationToken cancellationToken) { diagnostic = default(Diagnostic); var syntaxTree = node.SyntaxTree; var optionSet = analyzerOptions.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult(); if (optionSet == null) { return(false); } if (!CanSimplifyTypeNameExpressionCore(model, node, optionSet, out var issueSpan, out string diagnosticId, cancellationToken)) { return(false); } if (model.SyntaxTree.OverlapsHiddenPosition(issueSpan, cancellationToken)) { return(false); } PerLanguageOption <CodeStyleOption <bool> > option; DiagnosticDescriptor descriptor; switch (diagnosticId) { case IDEDiagnosticIds.SimplifyNamesDiagnosticId: descriptor = s_descriptorSimplifyNames; break; case IDEDiagnosticIds.SimplifyMemberAccessDiagnosticId: descriptor = s_descriptorSimplifyMemberAccess; break; case IDEDiagnosticIds.RemoveQualificationDiagnosticId: descriptor = GetRemoveQualificationDiagnosticDescriptor(model, node, optionSet, cancellationToken); break; case IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInDeclarationsDiagnosticId: option = CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration; descriptor = GetApplicablePredefinedTypeDiagnosticDescriptor( IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInDeclarationsDiagnosticId, option, optionSet); break; case IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInMemberAccessDiagnosticId: option = CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess; descriptor = GetApplicablePredefinedTypeDiagnosticDescriptor( IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInMemberAccessDiagnosticId, option, optionSet); break; default: throw ExceptionUtilities.Unreachable; } if (descriptor == null) { return(false); } var tree = model.SyntaxTree; var builder = ImmutableDictionary.CreateBuilder <string, string>(); builder["OptionName"] = nameof(CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess); // TODO: need the actual one builder["OptionLanguage"] = model.Language; diagnostic = Diagnostic.Create(descriptor, tree.GetLocation(issueSpan), builder.ToImmutable()); return(true); }
// internal for testing purposes internal DiagnosticAnalyzerDriver( Project project, ISyntaxNodeAnalyzerService syntaxNodeAnalyzerService, CancellationToken cancellationToken) { _project = project; _cancellationToken = cancellationToken; _syntaxNodeAnalyzerService = syntaxNodeAnalyzerService; _generatedCodeService = project.Solution.Workspace.Services.GetService<IGeneratedCodeRecognitionService>(); _analyzerDriverService = project.LanguageServices.GetService<IAnalyzerDriverService>(); _descendantExecutableNodesMap = null; _analyzerOptions = _project.AnalyzerOptions; }
// internal for testing purposes internal DiagnosticAnalyzerDriver( Document document, TextSpan? span, SyntaxNode root, ISyntaxNodeAnalyzerService syntaxNodeAnalyzerService, CancellationToken cancellationToken, bool testOnly_DonotCatchAnalyzerExceptions = false) { _document = document; _span = span; _root = root; _project = document.Project; _syntaxNodeAnalyzerService = syntaxNodeAnalyzerService; _cancellationToken = cancellationToken; _descendantExecutableNodesMap = new Dictionary<SyntaxNode, ImmutableArray<SyntaxNode>>(); _syntaxFacts = document.Project.LanguageServices.GetService<ISyntaxFactsService>(); _generatedCodeService = document.Project.Solution.Workspace.Services.GetService<IGeneratedCodeRecognitionService>(); _analyzerDriverService = document.Project.LanguageServices.GetService<IAnalyzerDriverService>(); _analyzerOptions = new WorkspaceAnalyzerOptions(_project.AnalyzerOptions, _project.Solution.Workspace); _testOnly_DonotCatchAnalyzerExceptions = testOnly_DonotCatchAnalyzerExceptions; }
public static List<Phrase> GetPrePreTerminalPhrases(this Tree root, Rhetorica.Sentence sentence = null, string ignore = "", string punctuation = null, AnalyzerOptions options = AnalyzerOptions.None) { var phrases = new List<Phrase>(); for (java.util.Iterator i = root.iterator(); i.hasNext(); ) { Tree tree = (Tree)i.next(); if (tree.isPreTerminal() || tree.isPrePreTerminal()) { if (tree.isPreTerminal() && tree.parent(root) != null) { if (tree.parent(root).isPrePreTerminal()) continue; } var current = new Phrase(tree.GetTokens(root, sentence, ignore, punctuation, options)); // If current node matches previous node but for punctuation omission, replace previous with current: bool omitFalseDuplicatePhrases = options.HasFlag(AnalyzerOptions.OmitFalseDuplicatePhrases); if (omitFalseDuplicatePhrases) { if (phrases.Count > 0) { Phrase previous = phrases.Last(); if (previous.EqualExceptPunctuationOmission(current)) { phrases[phrases.Count - 1] = current; continue; } } } if (current.Count == 0) continue; phrases.Add(current); } } // If "phrase" is a single token which is a preposition (IN) or infinitival to (TO), then join it to the subsequent phrase. for (int i = 0; i < phrases.Count; ++i) { if (phrases[i].Count == 1 && Regex.IsMatch(phrases[i][0].TagEquivalent, @"^(IN|TO)$", RegexOptions.IgnoreCase) && i != phrases.Count - 1) { phrases[i + 1].Tokens.InsertRange(0, phrases[i].Tokens); phrases.RemoveAt(i); i =- 1; } } return phrases; }
public static Phrase GetTokens(this Tree tree, Tree root = null, Rhetorica.Sentence sentence = null, string ignore = "", string punctuation = null, AnalyzerOptions options = AnalyzerOptions.None) { var tokens = new Phrase(sentence: sentence); java.util.List leaves = tree.getLeaves(); for (java.util.Iterator i = leaves.iterator(); i.hasNext(); ) { Tree leaf = (Tree)i.next(); string token = leaf.value().Trim(); Tree preterminal = leaf.parent(tree); if (preterminal == null) continue; string tag = preterminal.value().Trim(); bool ignoreMeansInclude = options.HasFlag(AnalyzerOptions.IgnoreMeansInclude); if (ignore != string.Empty) { bool isMatch = Regex.IsMatch(token, ignore); if (ignoreMeansInclude) { if (!isMatch) continue; } else { if (isMatch) continue; } } bool omitPunctuation = options.HasFlag(AnalyzerOptions.OmitPunctuationTokens); if (omitPunctuation) { // Leave out certain types of punctuation: bool isPunctuation = Regex.IsMatch(tag, punctuation ?? Analyzer.PunctuationPatterns) || Regex.IsMatch(token, punctuation ?? Analyzer.PunctuationPatterns); if (isPunctuation) { tokens.IsPunctuationOmitted = true; continue; } // But also remove any straggler punctuation missed within a token...? Maybe not. Use RegExp 'FloatingPunctuationPatterns' if so. } root = root ?? tree; int depth = root.depth() - root.depth(preterminal); var characterEdges = new CharacterEdges(root.leftCharEdge(leaf), root.rightCharEdge(leaf)); tokens.Add(new Token(token, tag, depth, characterEdges)); } return tokens; }
private static TaintedDataAnalysisResult?TryGetOrComputeResult( ControlFlowGraph cfg, Compilation compilation, ISymbol containingMethod, AnalyzerOptions analyzerOptions, TaintedDataSymbolMap <SourceInfo> taintedSourceInfos, TaintedDataSymbolMap <SanitizerInfo> taintedSanitizerInfos, TaintedDataSymbolMap <SinkInfo> taintedSinkInfos, InterproceduralAnalysisConfiguration interproceduralAnalysisConfig) { if (cfg == null) { Debug.Fail("Expected non-null CFG"); return(null); } WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation); ValueContentAnalysisResult?valueContentAnalysisResult = null; CopyAnalysisResult? copyAnalysisResult = null; PointsToAnalysisResult? pointsToAnalysisResult = null; if (taintedSourceInfos.RequiresValueContentAnalysis || taintedSanitizerInfos.RequiresValueContentAnalysis || taintedSinkInfos.RequiresValueContentAnalysis) { valueContentAnalysisResult = ValueContentAnalysis.TryGetOrComputeResult( cfg, containingMethod, analyzerOptions, wellKnownTypeProvider, interproceduralAnalysisConfig, out copyAnalysisResult, out pointsToAnalysisResult, pessimisticAnalysis: true, performCopyAnalysis: false); if (valueContentAnalysisResult == null) { return(null); } } else { pointsToAnalysisResult = PointsToAnalysis.TryGetOrComputeResult( cfg, containingMethod, analyzerOptions, wellKnownTypeProvider, interproceduralAnalysisConfig, interproceduralAnalysisPredicateOpt: null, pessimisticAnalysis: true, performCopyAnalysis: false); if (pointsToAnalysisResult == null) { return(null); } } TaintedDataAnalysisContext analysisContext = TaintedDataAnalysisContext.Create( TaintedDataAbstractValueDomain.Default, wellKnownTypeProvider, cfg, containingMethod, analyzerOptions, interproceduralAnalysisConfig, pessimisticAnalysis: false, copyAnalysisResultOpt: copyAnalysisResult, pointsToAnalysisResult: pointsToAnalysisResult, valueContentAnalysisResult: valueContentAnalysisResult, tryGetOrComputeAnalysisResult: TryGetOrComputeResultForAnalysisContext, taintedSourceInfos: taintedSourceInfos, taintedSanitizerInfos: taintedSanitizerInfos, taintedSinkInfos: taintedSinkInfos); return(TryGetOrComputeResultForAnalysisContext(analysisContext)); }
/// <summary> /// Given classes in the form of strings, their language, and an IDiagnosticAnalyzer to apply to it, return the diagnostics found in the string after converting it to a document. /// </summary> /// <param name="sources">Classes in the form of strings.</param> /// <param name="language">The language the source classes are in.</param> /// <param name="analyzer">The analyzer to be run on the sources.</param> /// <param name="options">The options that have to be provided to the analyzer.</param> /// <returns>An IEnumerable of Diagnostics that surfaced in the source code, sorted by Location.</returns> private static Diagnostic[] GetSortedDiagnostics(string[] sources, string language, DiagnosticAnalyzer analyzer, AnalyzerOptions options = null) { return(GetSortedDiagnosticsFromDocuments(analyzer, GetDocuments(sources, language), options)); }
protected virtual bool IsConfiguredDisallowedExceptionType(INamedTypeSymbol namedTypeSymbol, IMethodSymbol containingMethod, Compilation compilation, AnalyzerOptions analyzerOptions, CancellationToken cancellationToken) { return(false); }
/// <summary> /// Given an analyzer and a document to apply it to, run the analyzer and gather an array of diagnostics found in it. /// The returned diagnostics are then ordered by location in the source document. /// </summary> /// <param name="analyzer">The analyzer to run on the documents.</param> /// <param name="documents">The Documents that the analyzer will be run on.</param> /// <param name="options">The options that have to be provided to the analyzer.</param> /// <returns>An IEnumerable of Diagnostics that surfaced in the source code, sorted by Location.</returns> protected static Diagnostic[] GetSortedDiagnosticsFromDocuments(DiagnosticAnalyzer analyzer, Document[] documents, AnalyzerOptions options = null) { _ = documents ?? throw new ArgumentNullException(nameof(documents)); var projects = new HashSet <Project>(); foreach (Document document in documents) { projects.Add(document.Project); } var diagnostics = new List <Diagnostic>(); foreach (Project project in projects) { CompilationWithAnalyzers compilationWithAnalyzers; if (options == null) { compilationWithAnalyzers = project.GetCompilationAsync().Result.WithAnalyzers(ImmutableArray.Create(analyzer)); } else { compilationWithAnalyzers = project.GetCompilationAsync().Result.WithAnalyzers(ImmutableArray.Create(analyzer), options); } foreach (Diagnostic diagnostic in compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().Result) { if (diagnostic.Location == Location.None || diagnostic.Location.IsInMetadata) { diagnostics.Add(diagnostic); } else { foreach (Document document in documents) { SyntaxTree tree = document.GetSyntaxTreeAsync().Result; if (tree == diagnostic.Location.SourceTree) { diagnostics.Add(diagnostic); } } } } } Diagnostic[] results = SortDiagnostics(diagnostics); diagnostics.Clear(); return(results); }
public void AnalyzeNode(SyntaxNode node, SemanticModel semanticModel, Action <Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken) { IfStatementSyntax ifStatement = (IfStatementSyntax)node; if (IsElseIfWithoutElse(ifStatement)) { addDiagnostic(Diagnostic.Create(Rule, node.GetLocation())); } }
/// <summary> /// csc.exe and vbc.exe entry point. /// </summary> public virtual int Run(TextWriter consoleOutput, CancellationToken cancellationToken) { Debug.Assert(!Arguments.IsInteractive); cancellationToken.ThrowIfCancellationRequested(); if (Arguments.DisplayLogo) { PrintLogo(consoleOutput); } if (Arguments.DisplayHelp) { PrintHelp(consoleOutput); return(Succeeded); } if (PrintErrors(Arguments.Errors, consoleOutput)) { return(Failed); } var touchedFilesLogger = (Arguments.TouchedFilesPath != null) ? new TouchedFileLogger() : null; Compilation compilation = CreateCompilation(consoleOutput, touchedFilesLogger); if (compilation == null) { return(Failed); } var diagnostics = new List <DiagnosticInfo>(); var analyzers = ResolveAnalyzersFromArguments(diagnostics, MessageProvider, touchedFilesLogger); if (PrintErrors(diagnostics, consoleOutput)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); var analyzerOptions = new AnalyzerOptions(Arguments.AdditionalStreams, Arguments.AdditionalOptions); AnalyzerDriver analyzerDriver = null; if (!analyzers.IsDefaultOrEmpty) { analyzerDriver = AnalyzerDriver.Create(compilation, analyzers, analyzerOptions, out compilation, cancellationToken); } // Print the diagnostics produced during the parsing stage and exit if there were any errors. if (PrintErrors(compilation.GetParseDiagnostics(), consoleOutput)) { return(Failed); } if (PrintErrors(compilation.GetDeclarationDiagnostics(), consoleOutput)) { return(Failed); } EmitResult emitResult; // EDMAURER: Don't yet know if there are method body errors. don't overwrite // any existing output files until the compilation is known to be successful. string tempExeFilename = null; string tempPdbFilename = null; // NOTE: as native compiler does, we generate the documentation file // NOTE: 'in place', replacing the contents of the file if it exists try { tempExeFilename = CreateTempFile(consoleOutput); // Can happen when temp directory is "full" if (tempExeFilename == null) { return(Failed); } FileStream output = OpenFile(tempExeFilename, consoleOutput); if (output == null) { return(Failed); } string finalOutputPath; string finalPdbFilePath; string finalXmlFilePath; using (output) { FileStream pdb = null; FileStream xml = null; cancellationToken.ThrowIfCancellationRequested(); if (Arguments.EmitPdb) { tempPdbFilename = CreateTempFile(consoleOutput); if (tempPdbFilename == null) { return(Failed); } pdb = OpenFile(tempPdbFilename, consoleOutput); if (pdb == null) { return(Failed); } } cancellationToken.ThrowIfCancellationRequested(); finalXmlFilePath = Arguments.DocumentationPath; if (finalXmlFilePath != null) { xml = OpenFile(finalXmlFilePath, consoleOutput, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete); if (xml == null) { return(Failed); } xml.SetLength(0); } cancellationToken.ThrowIfCancellationRequested(); IEnumerable <DiagnosticInfo> errors; using (var win32Res = GetWin32Resources(Arguments, compilation, out errors)) using (pdb) using (xml) { if (PrintErrors(errors, consoleOutput)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); string outputName = GetOutputFileName(compilation, cancellationToken); finalOutputPath = Path.Combine(Arguments.OutputDirectory, outputName); finalPdbFilePath = Arguments.PdbPath ?? Path.ChangeExtension(finalOutputPath, ".pdb"); // NOTE: Unlike the PDB path, the XML doc path is not embedded in the assembly, so we don't need to pass it to emit. emitResult = compilation.Emit(output, outputName, finalPdbFilePath, pdb, xml, win32Res, Arguments.ManifestResources, cancellationToken); } } GenerateSqmData(Arguments.CompilationOptions, emitResult.Diagnostics); if (PrintErrors(emitResult.Diagnostics, consoleOutput)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); if (analyzerDriver != null) { var analyzerDiagnostics = analyzerDriver.GetDiagnosticsAsync().Result; if (PrintErrors(analyzerDiagnostics, consoleOutput)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); } if (!TryDeleteFile(finalOutputPath, consoleOutput) || !TryMoveFile(tempExeFilename, finalOutputPath, consoleOutput)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); if (tempPdbFilename != null) { if (!TryDeleteFile(finalPdbFilePath, consoleOutput) || !TryMoveFile(tempPdbFilename, finalPdbFilePath, consoleOutput)) { return(Failed); } } cancellationToken.ThrowIfCancellationRequested(); if (Arguments.TouchedFilesPath != null) { Debug.Assert(touchedFilesLogger != null); touchedFilesLogger.AddWritten(tempExeFilename); touchedFilesLogger.AddWritten(finalOutputPath); if (tempPdbFilename != null) { touchedFilesLogger.AddWritten(tempPdbFilename); touchedFilesLogger.AddWritten(finalPdbFilePath); } if (finalXmlFilePath != null) { touchedFilesLogger.AddWritten(finalXmlFilePath); } var readStream = OpenFile(Arguments.TouchedFilesPath + ".read", consoleOutput, FileMode.OpenOrCreate); if (readStream == null) { return(Failed); } using (var writer = new StreamWriter(readStream)) { touchedFilesLogger.WriteReadPaths(writer); } var writtenStream = OpenFile(Arguments.TouchedFilesPath + ".write", consoleOutput, FileMode.OpenOrCreate); if (writtenStream == null) { return(Failed); } using (var writer = new StreamWriter(writtenStream)) { touchedFilesLogger.WriteWrittenPaths(writer); } } return(Succeeded); } finally { if (tempExeFilename != null) { TryDeleteFile(tempExeFilename, consoleOutput: null); } if (tempPdbFilename != null) { TryDeleteFile(tempPdbFilename, consoleOutput: null); } } }
private IEnumerable <Diagnostic> EnumerateDiagnosticsForDocument([NotNull] Document document, TestValidationMode validationMode, DiagnosticsCaptureMode diagnosticsCaptureMode, [NotNull] AnalyzerOptions options) { CompilationWithAnalyzers compilationWithAnalyzers = GetCompilationWithAnalyzers(document, validationMode, options); SyntaxTree tree = document.GetSyntaxTreeAsync().Result; return(EnumerateAnalyzerDiagnostics(compilationWithAnalyzers, tree, diagnosticsCaptureMode)); }
override protected void LanguageSpecificAnalyzeSyntax(SyntaxNodeAnalysisContext context, SyntaxTree syntaxTree, AnalyzerOptions options, CancellationToken cancellationToken) { var parseOptions = (CSharpParseOptions)syntaxTree.Options; switch (context.Node.Kind()) { case SyntaxKind.NameColon: ReportDiagnosticsIfNeeded((NameColonSyntax)context.Node, context, options, syntaxTree, cancellationToken); break; case SyntaxKind.NameEquals: ReportDiagnosticsIfNeeded((NameEqualsSyntax)context.Node, context, options, syntaxTree, cancellationToken); break; } }
public static System.Collections.Generic.IReadOnlyList <string> GetAdditionalAllowTypes(this AnalyzerOptions option) { Microsoft.CodeAnalysis.AdditionalText?config = option.AdditionalFiles.FirstOrDefault(x => System.IO.Path.GetFileName(x.Path).Equals("MessagePackAnalyzer.json", StringComparison.OrdinalIgnoreCase)); if (config != null) { try { var l = new List <string>(); var raw = config.GetText().ToString(); using (var sr = new StringReader(raw)) using (var tr = new TinyJsonReader(sr)) { while (tr.Read()) { if (tr.TokenType == TinyJsonToken.String) { l.Add((string)tr.Value !); } } } return(l); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("Can't load MessagePackAnalyzer.json:" + ex.ToString()); return(Array.Empty <string>()); } } else { return(Array.Empty <string>()); } }
private void ReportDiagnosticsIfNeeded(NameColonSyntax nameColon, SyntaxNodeAnalysisContext context, AnalyzerOptions options, SyntaxTree syntaxTree, CancellationToken cancellationToken) { if (!nameColon.Parent.IsKind(SyntaxKind.Argument, out ArgumentSyntax? argument)) { return; } RoslynDebug.Assert(context.Compilation is object); var parseOptions = (CSharpParseOptions)syntaxTree.Options; var preference = options.GetOption( CodeStyleOptions2.PreferInferredTupleNames, context.Compilation.Language, syntaxTree, cancellationToken); if (!preference.Value || !CSharpInferredMemberNameSimplifier.CanSimplifyTupleElementName(argument, parseOptions)) { return; } // Create a normal diagnostic context.ReportDiagnostic( DiagnosticHelper.Create( Descriptor, nameColon.GetLocation(), preference.Notification.Severity, additionalLocations: null, properties: null)); // Also fade out the part of the name-colon syntax RoslynDebug.AssertNotNull(UnnecessaryWithoutSuggestionDescriptor); var fadeSpan = TextSpan.FromBounds(nameColon.Name.SpanStart, nameColon.ColonToken.Span.End); context.ReportDiagnostic( Diagnostic.Create( UnnecessaryWithoutSuggestionDescriptor, syntaxTree.GetLocation(fadeSpan))); }
public Analyzer(AnalyzerOptions options) { StyleCopSettings settings = options.GetStyleCopSettings(); this.documentationSettings = settings.DocumentationRules; }
private void ReportDiagnosticsIfNeeded(NameEqualsSyntax nameEquals, SyntaxNodeAnalysisContext context, AnalyzerOptions options, SyntaxTree syntaxTree, CancellationToken cancellationToken) { if (!nameEquals.Parent.IsKind(SyntaxKind.AnonymousObjectMemberDeclarator, out AnonymousObjectMemberDeclaratorSyntax? anonCtor)) { return; } RoslynDebug.Assert(context.Compilation is object); var preference = options.GetOption( CodeStyleOptions2.PreferInferredAnonymousTypeMemberNames, context.Compilation.Language, syntaxTree, cancellationToken); if (!preference.Value || !CSharpInferredMemberNameSimplifier.CanSimplifyAnonymousTypeMemberName(anonCtor)) { return; } // Create a normal diagnostic context.ReportDiagnostic( DiagnosticHelper.Create( Descriptor, nameEquals.GetLocation(), preference.Notification.Severity, additionalLocations: null, properties: null)); // Also fade out the part of the name-equals syntax RoslynDebug.AssertNotNull(UnnecessaryWithoutSuggestionDescriptor); var fadeSpan = TextSpan.FromBounds(nameEquals.Name.SpanStart, nameEquals.EqualsToken.Span.End); context.ReportDiagnostic( Diagnostic.Create( UnnecessaryWithoutSuggestionDescriptor, syntaxTree.GetLocation(fadeSpan))); }
public Analyzer(AnalyzerOptions options) { StyleCopSettings settings = options.GetStyleCopSettings(); this.namingSettings = settings.NamingRules; }
public static AnalyzerOptions NewWorkspaceAnalyzerOptions(AnalyzerOptions options, OptionSet optionSet, Solution solution) => _newWorkspaceAnalyzerOptions(options, optionSet, solution);
protected override void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilation, Action <Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken) { // TODO: should this be restricted to class types? // static holder types are not already static/sealed and must be public or protected if (!symbol.IsStatic && !symbol.IsSealed && (symbol.DeclaredAccessibility == Accessibility.Public || symbol.DeclaredAccessibility == Accessibility.Protected)) { // only get the explicitly declared members var allMembers = symbol.GetMembers().Where(member => !member.IsImplicitlyDeclared); if (!allMembers.Any()) { return; } // to be a static holder type, all members must be static and not operator overloads if (allMembers.All(member => (member.IsStatic || symbol.InstanceConstructors.Contains(member)) && !IsUserdefinedOperator(member))) { // Has a default constructor that is implicitly defined if (!symbol.InstanceConstructors.IsEmpty) { if (symbol.InstanceConstructors.Count() == 1 && symbol.InstanceConstructors.First().Parameters.IsEmpty) { // If there is just the default constructor, we can make the type static. // Produce Diagnostic CA1052 addDiagnostic(symbol.CreateDiagnostic(CA1052Rule, symbol.Name)); } else if (symbol.InstanceConstructors.Count() > 0) { // If there are explicitly defined constructors then we cannot make the type static instead just show a diagnostic. // Instead we show a Diagnostic CA1053 with no fix addDiagnostic(symbol.CreateDiagnostic(CA1053Rule, symbol.Name)); } } } } }
#pragma warning disable RS1012 // Start action has no registered actions. internal static StyleCopSettings GetStyleCopSettings(this CompilationStartAnalysisContext context, AnalyzerOptions options, DeserializationFailureBehavior failureBehavior, CancellationToken cancellationToken) #pragma warning restore RS1012 // Start action has no registered actions. { SourceText text = TryGetStyleCopSettingsText(options, cancellationToken); if (text == null) { return(new StyleCopSettings()); } if (failureBehavior == DeserializationFailureBehavior.ReturnDefaultSettings) { StyleCopSettings settings; if (!context.TryGetValue(text, SettingsValueProvider, out settings)) { return(new StyleCopSettings()); } return(settings); } return(GetStyleCopSettings(SettingsFileName, text, failureBehavior)); }
abstract protected void LanguageSpecificAnalyzeSyntax(SyntaxNodeAnalysisContext context, SyntaxTree syntaxTree, AnalyzerOptions options, CancellationToken cancellationToken);
/// <summary> /// Gets the StyleCop settings. /// </summary> /// <remarks> /// <para>If a <see cref="JsonParseException"/> or <see cref="InvalidSettingsException"/> occurs while /// deserializing the settings file, a default settings instance is returned.</para> /// </remarks> /// <param name="options">The analyzer options that will be used to determine the StyleCop settings.</param> /// <param name="cancellationToken">The cancellation token that the operation will observe.</param> /// <returns>A <see cref="StyleCopSettings"/> instance that represents the StyleCop settings for the given context.</returns> internal static StyleCopSettings GetStyleCopSettings(this AnalyzerOptions options, CancellationToken cancellationToken) { return(GetStyleCopSettings(options, DeserializationFailureBehavior.ReturnDefaultSettings, cancellationToken)); }
protected bool TrySimplifyTypeNameExpression(SemanticModel model, SyntaxNode node, AnalyzerOptions analyzerOptions, out Diagnostic diagnostic, CancellationToken cancellationToken) { diagnostic = default(Diagnostic); var optionSet = GetOptionSet(analyzerOptions); string diagnosticId; TextSpan issueSpan; if (!CanSimplifyTypeNameExpressionCore(model, node, optionSet, out issueSpan, out diagnosticId, cancellationToken)) { return(false); } if (model.SyntaxTree.OverlapsHiddenPosition(issueSpan, cancellationToken)) { return(false); } DiagnosticDescriptor descriptor; switch (diagnosticId) { case IDEDiagnosticIds.SimplifyNamesDiagnosticId: descriptor = s_descriptorSimplifyNames; break; case IDEDiagnosticIds.SimplifyMemberAccessDiagnosticId: descriptor = s_descriptorSimplifyMemberAccess; break; case IDEDiagnosticIds.SimplifyThisOrMeDiagnosticId: descriptor = s_descriptorSimplifyThisOrMe; break; default: throw ExceptionUtilities.Unreachable; } var tree = model.SyntaxTree; diagnostic = Diagnostic.Create(descriptor, tree.GetLocation(issueSpan)); return(true); }
/// <summary> /// Gets the StyleCop settings. /// </summary> /// <param name="options">The analyzer options that will be used to determine the StyleCop settings.</param> /// <param name="failureBehavior">The behavior of the method when a <see cref="JsonParseException"/> or /// <see cref="InvalidSettingsException"/> occurs while deserializing the settings file.</param> /// <param name="cancellationToken">The cancellation token that the operation will observe.</param> /// <returns>A <see cref="StyleCopSettings"/> instance that represents the StyleCop settings for the given context.</returns> internal static StyleCopSettings GetStyleCopSettings(this AnalyzerOptions options, DeserializationFailureBehavior failureBehavior, CancellationToken cancellationToken) { return(GetStyleCopSettings(options != null ? options.AdditionalFiles : ImmutableArray.Create <AdditionalText>(), failureBehavior, cancellationToken)); }
/// <summary> /// Analyzers should use BatchGetOrComputeHazardousUsages instead. Gets hazardous usages of an object based on a set of its properties. /// </summary> /// <param name="cfg">Control flow graph of the code.</param> /// <param name="compilation">Compilation containing the code.</param> /// <param name="owningSymbol">Symbol of the code to examine.</param> /// <param name="typeToTrackMetadataNames">Names of the types to track.</param> /// <param name="constructorMapper">How constructor invocations map to <see cref="PropertySetAbstractValueKind"/>s.</param> /// <param name="propertyMappers">How property assignments map to <see cref="PropertySetAbstractValueKind"/>.</param> /// <param name="hazardousUsageEvaluators">When and how to evaluate <see cref="PropertySetAbstractValueKind"/>s to for hazardous usages.</param> /// <param name="interproceduralAnalysisConfig">Interprocedural dataflow analysis configuration.</param> /// <param name="pessimisticAnalysis">Whether to be pessimistic.</param> /// <returns>Property set analysis result.</returns> internal static PropertySetAnalysisResult?GetOrComputeResult( ControlFlowGraph cfg, Compilation compilation, ISymbol owningSymbol, AnalyzerOptions analyzerOptions, ImmutableHashSet <string> typeToTrackMetadataNames, ConstructorMapper constructorMapper, PropertyMapperCollection propertyMappers, HazardousUsageEvaluatorCollection hazardousUsageEvaluators, InterproceduralAnalysisConfiguration interproceduralAnalysisConfig, bool pessimisticAnalysis = false) { if (constructorMapper == null) { throw new ArgumentNullException(nameof(constructorMapper)); } if (propertyMappers == null) { throw new ArgumentNullException(nameof(propertyMappers)); } if (hazardousUsageEvaluators == null) { throw new ArgumentNullException(nameof(hazardousUsageEvaluators)); } constructorMapper.Validate(propertyMappers.PropertyValuesCount); var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation); PointsToAnalysisResult? pointsToAnalysisResult; ValueContentAnalysisResult?valueContentAnalysisResultOpt; if (!constructorMapper.RequiresValueContentAnalysis && !propertyMappers.RequiresValueContentAnalysis) { pointsToAnalysisResult = PointsToAnalysis.TryGetOrComputeResult( cfg, owningSymbol, analyzerOptions, wellKnownTypeProvider, PointsToAnalysisKind.Complete, interproceduralAnalysisConfig, interproceduralAnalysisPredicateOpt: null, pessimisticAnalysis, performCopyAnalysis: false); if (pointsToAnalysisResult == null) { return(null); } valueContentAnalysisResultOpt = null; } else { valueContentAnalysisResultOpt = ValueContentAnalysis.TryGetOrComputeResult( cfg, owningSymbol, analyzerOptions, wellKnownTypeProvider, PointsToAnalysisKind.Complete, interproceduralAnalysisConfig, out var copyAnalysisResult, out pointsToAnalysisResult, pessimisticAnalysis, performCopyAnalysis: false); if (valueContentAnalysisResultOpt == null) { return(null); } } var analysisContext = PropertySetAnalysisContext.Create( PropertySetAbstractValueDomain.Default, wellKnownTypeProvider, cfg, owningSymbol, analyzerOptions, interproceduralAnalysisConfig, pessimisticAnalysis, pointsToAnalysisResult, valueContentAnalysisResultOpt, TryGetOrComputeResultForAnalysisContext, typeToTrackMetadataNames, constructorMapper, propertyMappers, hazardousUsageEvaluators); var result = TryGetOrComputeResultForAnalysisContext(analysisContext); return(result); }
internal static StyleCopSettings GetStyleCopSettings(this AnalysisContext context, AnalyzerOptions options, DeserializationFailureBehavior failureBehavior, CancellationToken cancellationToken) { SourceText text = TryGetStyleCopSettingsText(options, cancellationToken); if (text == null) { return(new StyleCopSettings()); } if (failureBehavior == DeserializationFailureBehavior.ReturnDefaultSettings) { StyleCopSettings settings; if (!context.TryGetValue(text, SettingsValueProvider, out settings)) { return(new StyleCopSettings()); } return(settings); } return(GetStyleCopSettings(SettingsFileName, text, failureBehavior)); }
protected override void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compilation, Action <Diagnostic> addDiagnostic, AnalyzerOptions options, CancellationToken cancellationToken) { if (symbol.GetMembers().Any(member => IsDllImport(member)) && !IsTypeNamedCorrectly(symbol.Name)) { addDiagnostic(symbol.CreateDiagnostic(Rule)); } }
internal static StyleCopSettings GetStyleCopSettings(this CompilationStartAnalysisContext context, AnalyzerOptions options, CancellationToken cancellationToken) { return(GetStyleCopSettings(context, options, DeserializationFailureBehavior.ReturnDefaultSettings, cancellationToken)); }
public WorkspaceAnalyzerOptions(AnalyzerOptions options, Workspace workspace) : base(options.AdditionalFiles) { this.Workspace = workspace; }
public Analyzer(string path, DocumentPreprocessor.DocType docType = null, string ignore = "", string punctuation = null, AnalyzerOptions options = AnalyzerOptions.None) : this() { _path = path; _docType = docType; _ignore = ignore; _options = options; _punctuation = punctuation ?? PunctuationPatterns; Open(); }