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);
                }
            }
        }
Example #5
0
 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()));
            }
        }
Example #7
0
        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));
                }
            }
        }
Example #8
0
        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));
        }
Example #9
0
        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);
        }
Example #18
0
        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()));
            }
        }
Example #19
0
        /// <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);
                }
            }
        }
Example #20
0
        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));
        }
Example #21
0
        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>());
            }
        }
Example #23
0
        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)));
        }
Example #24
0
            public Analyzer(AnalyzerOptions options)
            {
                StyleCopSettings settings = options.GetStyleCopSettings();

                this.documentationSettings = settings.DocumentationRules;
            }
Example #25
0
        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)));
        }
Example #26
0
            public Analyzer(AnalyzerOptions options)
            {
                StyleCopSettings settings = options.GetStyleCopSettings();

                this.namingSettings = settings.NamingRules;
            }
Example #27
0
 public static AnalyzerOptions NewWorkspaceAnalyzerOptions(AnalyzerOptions options, OptionSet optionSet, Solution solution) =>
 _newWorkspaceAnalyzerOptions(options, optionSet, solution);
Example #28
0
        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));
                        }
                    }
                }
            }
        }
Example #29
0
#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));
        }
Example #30
0
 abstract protected void LanguageSpecificAnalyzeSyntax(SyntaxNodeAnalysisContext context, SyntaxTree syntaxTree, AnalyzerOptions options, CancellationToken cancellationToken);
Example #31
0
 /// <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);
        }
Example #33
0
 /// <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);
        }
Example #35
0
        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));
     }
 }
Example #37
0
 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;
 }
Example #39
0
        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();
        }