Esempio n. 1
0
            private void GetPartialCompilationState(
                SolutionState solution,
                DocumentId id,
                out ProjectState inProgressProject,
                out Compilation inProgressCompilation,
                CancellationToken cancellationToken)
            {
                var state       = ReadState();
                var compilation = state.Compilation?.GetValueOrNull(cancellationToken);

                // check whether we can bail out quickly for typing case
                var inProgressState = state as InProgressState;

                // all changes left for this document is modifying the given document.
                // we can use current state as it is since we will replace the document with latest document anyway.
                if (inProgressState != null &&
                    compilation != null &&
                    inProgressState.IntermediateProjects.All(t => IsTouchDocumentActionForDocument(t.action, id)))
                {
                    inProgressProject     = ProjectState;
                    inProgressCompilation = compilation;

                    SolutionLogger.UseExistingPartialProjectState();
                    return;
                }

                inProgressProject = inProgressState != null?inProgressState.IntermediateProjects.First().state : this.ProjectState;

                // if we already have a final compilation we are done.
                if (compilation != null && state is FinalState)
                {
                    inProgressCompilation = compilation;

                    SolutionLogger.UseExistingFullProjectState();
                    return;
                }

                // 1) if we have an in-progress compilation use it.
                // 2) If we don't, then create a simple empty compilation/project.
                // 3) then, make sure that all it's p2p refs and whatnot are correct.
                if (compilation == null)
                {
                    inProgressProject     = inProgressProject.RemoveAllDocuments();
                    inProgressCompilation = CreateEmptyCompilation();
                }
                else
                {
                    inProgressCompilation = compilation;
                }

                // first remove all project from the project and compilation.
                inProgressProject = inProgressProject.WithProjectReferences(ImmutableArray.Create <ProjectReference>());

                // Now add in back a consistent set of project references.  For project references
                // try to get either a CompilationReference or a SkeletonReference. This ensures
                // that the in-progress project only reports a reference to another project if it
                // could actually get a reference to that project's metadata.
                var metadataReferences   = new List <MetadataReference>();
                var newProjectReferences = new List <ProjectReference>();

                metadataReferences.AddRange(this.ProjectState.MetadataReferences);

                var metadataReferenceToProjectId = new Dictionary <MetadataReference, ProjectId>();

                foreach (var projectReference in this.ProjectState.ProjectReferences)
                {
                    var referencedProject = solution.GetProjectState(projectReference.ProjectId);
                    if (referencedProject != null)
                    {
                        if (referencedProject.IsSubmission)
                        {
                            var previousScriptCompilation = solution.GetCompilationAsync(projectReference.ProjectId, cancellationToken).WaitAndGetResult(cancellationToken);

                            // previous submission project must support compilation:
                            RoslynDebug.Assert(previousScriptCompilation != null);

                            inProgressCompilation = inProgressCompilation.WithScriptCompilationInfo(inProgressCompilation.ScriptCompilationInfo.WithPreviousScriptCompilation(previousScriptCompilation));
                        }
                        else
                        {
                            // get the latest metadata for the partial compilation of the referenced project.
                            var metadata = solution.GetPartialMetadataReference(projectReference, this.ProjectState);

                            if (metadata == null)
                            {
                                // if we failed to get the metadata, check to see if we previously had existing metadata and reuse it instead.
                                var inProgressCompilationNotRef = inProgressCompilation;
                                metadata = inProgressCompilationNotRef.ExternalReferences.FirstOrDefault(
                                    r => solution.GetProjectState(inProgressCompilationNotRef.GetAssemblyOrModuleSymbol(r) as IAssemblySymbol)?.Id == projectReference.ProjectId);
                            }

                            if (metadata != null)
                            {
                                newProjectReferences.Add(projectReference);
                                metadataReferences.Add(metadata);
                                metadataReferenceToProjectId.Add(metadata, projectReference.ProjectId);
                            }
                        }
                    }
                }

                inProgressProject     = inProgressProject.AddProjectReferences(newProjectReferences);
                inProgressCompilation = UpdateCompilationWithNewReferencesAndRecordAssemblySymbols(inProgressCompilation, metadataReferences, metadataReferenceToProjectId);

                SolutionLogger.CreatePartialProjectState();
            }
Esempio n. 2
0
 internal override GreenNode SetAnnotations(SyntaxAnnotation[]?annotations)
 {
     RoslynDebug.Assert(GetType() == typeof(SyntaxToken));
     return(new SyntaxToken(Kind, FullWidth, GetDiagnostics(), annotations));
 }
Esempio n. 3
0
 public EventSymbol(Symbols.EventSymbol underlying)
 {
     RoslynDebug.Assert(underlying is object);
     _underlying = underlying;
 }
            protected override void AnalyzeDiagnosticAnalyzer(SymbolAnalysisContext symbolContext)
            {
                var namedType = (INamedTypeSymbol)symbolContext.Symbol;

                if (namedType.IsAbstract)
                {
                    return;
                }

                // 1) MissingDiagnosticAnalyzerAttributeRule: DiagnosticAnalyzer has no DiagnosticAnalyzerAttribute.
                // 2) AddLanguageSupportToAnalyzerRule: For analyzer supporting only one of C# or VB languages, detect if it can support the other language.

                var        hasAttribute    = false;
                SyntaxNode?attributeSyntax = null;
                bool       supportsCSharp  = false;
                bool       supportsVB      = false;

                var namedTypeAttributes = namedType.GetApplicableAttributes(_attributeUsageAttribute);

                foreach (AttributeData attribute in namedTypeAttributes)
                {
                    if (attribute.AttributeClass.DerivesFrom(DiagnosticAnalyzerAttribute))
                    {
                        // Bail out for the case where analyzer type derives from a sub-type in different assembly, and the sub-type has the diagnostic analyzer attribute.
                        if (attribute.ApplicationSyntaxReference == null)
                        {
                            return;
                        }

                        hasAttribute = true;

                        // The attribute constructor's signature is "(string, params string[])",
                        // so process both string arguments and string[] arguments.
                        foreach (TypedConstant arg in attribute.ConstructorArguments)
                        {
                            CheckLanguage(arg, ref supportsCSharp, ref supportsVB);

                            if (arg.Kind == TypedConstantKind.Array)
                            {
                                foreach (TypedConstant element in arg.Values)
                                {
                                    CheckLanguage(element, ref supportsCSharp, ref supportsVB);
                                }
                            }
                        }

                        attributeSyntax = attribute.ApplicationSyntaxReference.GetSyntax(symbolContext.CancellationToken);
                    }
                }

                if (!hasAttribute)
                {
                    Diagnostic diagnostic = namedType.CreateDiagnostic(MissingDiagnosticAnalyzerAttributeRule);
                    symbolContext.ReportDiagnostic(diagnostic);
                }
                else if (supportsCSharp ^ supportsVB)
                {
                    RoslynDebug.Assert(attributeSyntax != null);

                    // If the analyzer assembly doesn't reference either C# or VB CodeAnalysis assemblies,
                    // then the analyzer is pretty likely a language-agnostic analyzer.
                    Compilation      compilation = symbolContext.Compilation;
                    string           compilationTypeNameToCheck = supportsCSharp ? CSharpCompilationFullName : BasicCompilationFullName;
                    INamedTypeSymbol?compilationType            = compilation.GetOrCreateTypeByMetadataName(compilationTypeNameToCheck);
                    if (compilationType == null)
                    {
                        string     missingLanguage = supportsCSharp ? LanguageNames.VisualBasic : LanguageNames.CSharp;
                        Diagnostic diagnostic      = attributeSyntax.CreateDiagnostic(AddLanguageSupportToAnalyzerRule, namedType.Name, missingLanguage);
                        symbolContext.ReportDiagnostic(diagnostic);
                    }
                }
            }
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterCompilationStartAction(compilationContext =>
            {
                compilationContext.RegisterOperationBlockAction(operationBlockContext =>
                {
                    var owningSymbol = operationBlockContext.OwningSymbol;
                    if (owningSymbol.IsConfiguredToSkipAnalysis(operationBlockContext.Options,
                                                                AlwaysTrueFalseOrNullRule, operationBlockContext.Compilation, operationBlockContext.CancellationToken))
                    {
                        return;
                    }

                    var processedOperationRoots = new HashSet <IOperation>();

                    foreach (var operationRoot in operationBlockContext.OperationBlocks)
                    {
                        static bool ShouldAnalyze(IOperation op) =>
                        (op as IBinaryOperation)?.IsComparisonOperator() == true ||
                        (op as IInvocationOperation)?.TargetMethod.ReturnType.SpecialType == SpecialType.System_Boolean ||
                        op.Kind == OperationKind.Coalesce ||
                        op.Kind == OperationKind.ConditionalAccess ||
                        op.Kind == OperationKind.IsNull ||
                        op.Kind == OperationKind.IsPattern;

                        if (operationRoot.HasAnyOperationDescendant(ShouldAnalyze))
                        {
                            // Skip duplicate analysis from operation blocks for constructor initializer and body.
                            if (!processedOperationRoots.Add(operationRoot.GetRoot()))
                            {
                                // Already processed.
                                continue;
                            }

                            var cfg = operationBlockContext.GetControlFlowGraph(operationRoot);
                            var wellKnownTypeProvider      = WellKnownTypeProvider.GetOrCreate(operationBlockContext.Compilation);
                            var valueContentAnalysisResult = ValueContentAnalysis.TryGetOrComputeResult(cfg, owningSymbol, wellKnownTypeProvider,
                                                                                                        operationBlockContext.Options, AlwaysTrueFalseOrNullRule,
                                                                                                        PointsToAnalysisKind.Complete,
                                                                                                        operationBlockContext.CancellationToken,
                                                                                                        out var copyAnalysisResultOpt, out var pointsToAnalysisResult);
                            if (valueContentAnalysisResult == null ||
                                pointsToAnalysisResult == null)
                            {
                                continue;
                            }

                            foreach (var operation in cfg.DescendantOperations())
                            {
                                // Skip implicit operations.
                                // However, 'IsNull' operations are compiler generated operations corresponding to
                                // non-implicit conditional access operations, so we should not skip them.
                                if (operation.IsImplicit && operation.Kind != OperationKind.IsNull)
                                {
                                    continue;
                                }

                                switch (operation.Kind)
                                {
                                case OperationKind.BinaryOperator:
                                    var binaryOperation = (IBinaryOperation)operation;
                                    PredicateValueKind predicateKind = GetPredicateKind(binaryOperation);
                                    if (predicateKind != PredicateValueKind.Unknown &&
                                        (!(binaryOperation.LeftOperand is IBinaryOperation leftBinary) || GetPredicateKind(leftBinary) == PredicateValueKind.Unknown) &&
                                        (!(binaryOperation.RightOperand is IBinaryOperation rightBinary) || GetPredicateKind(rightBinary) == PredicateValueKind.Unknown))
                                    {
                                        ReportAlwaysTrueFalseOrNullDiagnostic(operation, predicateKind);
                                    }

                                    break;

                                case OperationKind.Invocation:
                                case OperationKind.IsPattern:
                                    predicateKind = GetPredicateKind(operation);
                                    if (predicateKind != PredicateValueKind.Unknown)
                                    {
                                        ReportAlwaysTrueFalseOrNullDiagnostic(operation, predicateKind);
                                    }

                                    break;

                                case OperationKind.IsNull:
                                    // '{0}' is always/never '{1}'. Remove or refactor the condition(s) to avoid dead code.
                                    predicateKind = GetPredicateKind(operation);
                                    DiagnosticDescriptor rule;
                                    switch (predicateKind)
                                    {
                                    case PredicateValueKind.AlwaysTrue:
                                        rule = AlwaysTrueFalseOrNullRule;
                                        break;

                                    case PredicateValueKind.AlwaysFalse:
                                        rule = NeverNullRule;
                                        break;

                                    default:
                                        continue;
                                    }

                                    var originalOperation = operationRoot.SemanticModel.GetOperation(operation.Syntax, operationBlockContext.CancellationToken);
                                    if (originalOperation is IAssignmentOperation ||
                                        originalOperation is IVariableDeclaratorOperation)
                                    {
                                        // Skip compiler generated IsNull operation for assignment/variable declaration within a using.
                                        continue;
                                    }

                                    var arg1       = operation.Syntax.ToString();
                                    var arg2       = operation.Language == LanguageNames.VisualBasic ? "Nothing" : "null";
                                    var diagnostic = operation.CreateDiagnostic(rule, arg1, arg2);
                                    operationBlockContext.ReportDiagnostic(diagnostic);
                                    break;
                                }
                            }

                            PredicateValueKind GetPredicateKind(IOperation operation)
                            {
                                Debug.Assert(operation.Kind == OperationKind.BinaryOperator ||
                                             operation.Kind == OperationKind.Invocation ||
                                             operation.Kind == OperationKind.IsNull ||
                                             operation.Kind == OperationKind.IsPattern);
                                RoslynDebug.Assert(pointsToAnalysisResult != null);
                                RoslynDebug.Assert(valueContentAnalysisResult != null);

                                if (operation is IBinaryOperation binaryOperation &&
                                    binaryOperation.IsComparisonOperator() ||
                                    operation.Type?.SpecialType == SpecialType.System_Boolean)
                                {
                                    PredicateValueKind predicateKind = pointsToAnalysisResult.GetPredicateKind(operation);
                                    if (predicateKind != PredicateValueKind.Unknown)
                                    {
                                        return(predicateKind);
                                    }

                                    if (copyAnalysisResultOpt != null)
                                    {
                                        predicateKind = copyAnalysisResultOpt.GetPredicateKind(operation);
                                        if (predicateKind != PredicateValueKind.Unknown)
                                        {
                                            return(predicateKind);
                                        }
                                    }

                                    predicateKind = valueContentAnalysisResult.GetPredicateKind(operation);
                                    if (predicateKind != PredicateValueKind.Unknown)
                                    {
                                        return(predicateKind);
                                    }
                                }

                                return(PredicateValueKind.Unknown);
                            }

                            void ReportAlwaysTrueFalseOrNullDiagnostic(IOperation operation, PredicateValueKind predicateKind)
                            {
                                Debug.Assert(predicateKind != PredicateValueKind.Unknown);

                                // '{0}' is always '{1}'. Remove or refactor the condition(s) to avoid dead code.
                                var arg1 = operation.Syntax.ToString();
                                var arg2 = predicateKind == PredicateValueKind.AlwaysTrue ?
                                           (operation.Language == LanguageNames.VisualBasic ? "True" : "true") :
                                           (operation.Language == LanguageNames.VisualBasic ? "False" : "false");
                                var diagnostic = operation.CreateDiagnostic(AlwaysTrueFalseOrNullRule, arg1, arg2);
                                operationBlockContext.ReportDiagnostic(diagnostic);
                            }
                        }
                    }
Esempio n. 6
0
        internal PEEventSymbol(
            PEModuleSymbol moduleSymbol,
            PENamedTypeSymbol containingType,
            EventDefinitionHandle handle,
            PEMethodSymbol addMethod,
            PEMethodSymbol removeMethod,
            MultiDictionary <string, PEFieldSymbol> privateFieldNameToSymbols
            )
        {
            RoslynDebug.Assert((object)moduleSymbol != null);
            RoslynDebug.Assert((object)containingType != null);
            Debug.Assert(!handle.IsNil);
            RoslynDebug.Assert((object)addMethod != null);
            RoslynDebug.Assert((object)removeMethod != null);

            _addMethod      = addMethod;
            _removeMethod   = removeMethod;
            _handle         = handle;
            _containingType = containingType;

            EventAttributes mdFlags   = 0;
            EntityHandle    eventType = default(EntityHandle);

            try
            {
                var module = moduleSymbol.Module;
                module.GetEventDefPropsOrThrow(handle, out _name, out mdFlags, out eventType);
            }
            catch (BadImageFormatException mrEx)
            {
                _name = _name ?? string.Empty;
                _lazyCachedUseSiteInfo.Initialize(
                    new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this)
                    );

                if (eventType.IsNil)
                {
                    _eventTypeWithAnnotations = TypeWithAnnotations.Create(
                        new UnsupportedMetadataTypeSymbol(mrEx)
                        );
                }
            }

            TypeSymbol originalEventType = _eventTypeWithAnnotations.Type;

            if (!_eventTypeWithAnnotations.HasType)
            {
                var metadataDecoder = new MetadataDecoder(moduleSymbol, containingType);
                originalEventType = metadataDecoder.GetTypeOfToken(eventType);

                const int targetSymbolCustomModifierCount = 0;
                var       typeSymbol = DynamicTypeDecoder.TransformType(
                    originalEventType,
                    targetSymbolCustomModifierCount,
                    handle,
                    moduleSymbol
                    );
                typeSymbol = NativeIntegerTypeDecoder.TransformType(
                    typeSymbol,
                    handle,
                    moduleSymbol
                    );

                // We start without annotation (they will be decoded below)
                var type = TypeWithAnnotations.Create(typeSymbol);

                // Decode nullable before tuple types to avoid converting between
                // NamedTypeSymbol and TupleTypeSymbol unnecessarily.

                // The containing type is passed to NullableTypeDecoder.TransformType to determine access
                // because the event does not have explicit accessibility in metadata.
                type = NullableTypeDecoder.TransformType(
                    type,
                    handle,
                    moduleSymbol,
                    accessSymbol: _containingType,
                    nullableContext: _containingType
                    );
                type = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, handle, moduleSymbol);
                _eventTypeWithAnnotations = type;
            }

            // IsWindowsRuntimeEvent checks the signatures, so we just have to check the accessors.
            bool isWindowsRuntimeEvent = IsWindowsRuntimeEvent;
            bool callMethodsDirectly   = isWindowsRuntimeEvent
                ? !DoModifiersMatch(_addMethod, _removeMethod)
                : !DoSignaturesMatch(moduleSymbol, originalEventType, _addMethod, _removeMethod);

            if (callMethodsDirectly)
            {
                _flags |= Flags.CallMethodsDirectly;
            }
            else
            {
                _addMethod.SetAssociatedEvent(this, MethodKind.EventAdd);
                _removeMethod.SetAssociatedEvent(this, MethodKind.EventRemove);

                PEFieldSymbol?associatedField = GetAssociatedField(
                    privateFieldNameToSymbols,
                    isWindowsRuntimeEvent
                    );
                if ((object?)associatedField != null)
                {
                    _associatedFieldOpt = associatedField;
                    associatedField.SetAssociatedEvent(this);
                }
            }

            if ((mdFlags & EventAttributes.SpecialName) != 0)
            {
                _flags |= Flags.IsSpecialName;
            }

            if ((mdFlags & EventAttributes.RTSpecialName) != 0)
            {
                _flags |= Flags.IsRuntimeSpecialName;
            }
        }
        public static void ReportNoLocationDiagnostic(
            this Compilation compilation,
            DiagnosticDescriptor rule,
            Action <Diagnostic> addDiagnostic,
            ImmutableDictionary <string, string?>?properties,
            params object[] args)
        {
            var effectiveSeverity = GetEffectiveSeverity();

            if (!effectiveSeverity.HasValue)
            {
                // Disabled rule
                return;
            }

            if (effectiveSeverity.Value != rule.DefaultSeverity)
            {
#pragma warning disable RS0030 // The symbol 'DiagnosticDescriptor.DiagnosticDescriptor.#ctor' is banned in this project: Use 'DiagnosticDescriptorHelper.Create' instead
                rule = new DiagnosticDescriptor(rule.Id, rule.Title, rule.MessageFormat, rule.Category,
                                                effectiveSeverity.Value, rule.IsEnabledByDefault, rule.Description, rule.HelpLinkUri, rule.CustomTags.ToArray());
#pragma warning restore RS0030
            }

            var diagnostic = Diagnostic.Create(rule, Location.None, properties, args);
            addDiagnostic(diagnostic);
            return;

            DiagnosticSeverity?GetEffectiveSeverity()
            {
                // Microsoft.CodeAnalysis version >= 3.7 exposes options through 'CompilationOptions.SyntaxTreeOptionsProvider.TryGetDiagnosticValue'
                // Microsoft.CodeAnalysis version 3.3 - 3.7 exposes options through 'SyntaxTree.DiagnosticOptions'. This API is deprecated in 3.7.

                var syntaxTreeOptionsProvider = s_compilationOptionsSyntaxTreeOptionsProviderProperty?.GetValue(compilation.Options);
                var syntaxTreeOptionsProviderTryGetDiagnosticValueMethod = syntaxTreeOptionsProvider?.GetType().GetRuntimeMethods().FirstOrDefault(m => m.Name == "TryGetDiagnosticValue");

                if (syntaxTreeOptionsProviderTryGetDiagnosticValueMethod == null && s_syntaxTreeDiagnosticOptionsProperty == null)
                {
                    return(rule.DefaultSeverity);
                }

                ReportDiagnostic?overriddenSeverity = null;

                foreach (var tree in compilation.SyntaxTrees)
                {
                    ReportDiagnostic?configuredValue = null;

                    // Prefer 'CompilationOptions.SyntaxTreeOptionsProvider', if available.
                    if (s_compilationOptionsSyntaxTreeOptionsProviderProperty != null)
                    {
                        if (syntaxTreeOptionsProviderTryGetDiagnosticValueMethod != null)
                        {
                            // public abstract bool TryGetDiagnosticValue(SyntaxTree tree, string diagnosticId, out ReportDiagnostic severity);
                            // public abstract bool TryGetDiagnosticValue(SyntaxTree tree, string diagnosticId, CancellationToken cancellationToken, out ReportDiagnostic severity);
                            object?[] parameters;
                            if (syntaxTreeOptionsProviderTryGetDiagnosticValueMethod.GetParameters().Length == 3)
                            {
                                parameters = new object?[] { tree, rule.Id, null };
                            }
                            else
                            {
                                parameters = new object?[] { tree, rule.Id, CancellationToken.None, null };
                            }

                            if (syntaxTreeOptionsProviderTryGetDiagnosticValueMethod.Invoke(syntaxTreeOptionsProvider, parameters) is true &&
                                parameters.Last() is ReportDiagnostic value)
                            {
                                configuredValue = value;
                            }
                        }
                    }
                    else
                    {
                        RoslynDebug.Assert(s_syntaxTreeDiagnosticOptionsProperty != null);
                        var options = (ImmutableDictionary <string, ReportDiagnostic>)s_syntaxTreeDiagnosticOptionsProperty.GetValue(tree) !;
                        if (options.TryGetValue(rule.Id, out var value))
                        {
                            configuredValue = value;
                        }
                    }

                    if (configuredValue == null)
                    {
                        continue;
                    }

                    if (configuredValue == ReportDiagnostic.Suppress)
                    {
                        // Any suppression entry always wins.
                        return(null);
                    }

                    if (overriddenSeverity == null)
                    {
                        overriddenSeverity = configuredValue;
                    }
                    else if (overriddenSeverity.Value.IsLessSevereThan(configuredValue.Value))
                    {
                        // Choose the most severe value for conflicts.
                        overriddenSeverity = configuredValue;
                    }
                }

                return(overriddenSeverity.HasValue ? overriddenSeverity.Value.ToDiagnosticSeverity() : rule.DefaultSeverity);
            }
        }
        public async Task <Document> AddImportsAsync(
            Document document,
            IEnumerable <TextSpan> spans,
            Strategy strategy,
            bool safe,
            OptionSet?options,
            CancellationToken cancellationToken)
        {
            options ??= await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);

            var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var addImportsService = document.GetRequiredLanguageService <IAddImportsService>();
            var generator         = document.GetRequiredLanguageService <SyntaxGenerator>();

            // Create a simple interval tree for simplification spans.
            var spansTree = new SimpleIntervalTree <TextSpan, TextSpanIntervalIntrospector>(new TextSpanIntervalIntrospector(), spans);

            var nodes = root.DescendantNodesAndSelf().Where(IsInSpan);

            var(importDirectivesToAdd, namespaceSymbols, context, model, newRoot) = strategy switch
            {
                Strategy.AddImportsFromSymbolAnnotations
                => await GetImportDirectivesFromAnnotatedNodesAsync(document, nodes, root, addImportsService, generator, cancellationToken).ConfigureAwait(false),
                Strategy.AddImportsFromSyntaxes
                => await GetImportDirectivesFromSyntaxesAsync(document, nodes, root, addImportsService, generator, cancellationToken).ConfigureAwait(false),
                _ => throw new InvalidEnumArgumentException(nameof(strategy), (int)strategy, typeof(Strategy)),
            };

            // If the previous call provided a new root, use it.
            root = newRoot ?? root;

            if (importDirectivesToAdd.Length == 0)
            {
                return(document.WithSyntaxRoot(root)); //keep any added simplifier annotations
            }

            if (safe)
            {
                // Mark the context with an annotation.
                // This will allow us to find it after we have called MakeSafeToAddNamespaces.
                var annotation = new SyntaxAnnotation();
                RoslynDebug.Assert(context is object);
                document = document.WithSyntaxRoot(root.ReplaceNode(context, context.WithAdditionalAnnotations(annotation)));
                root     = (await document.GetSyntaxRootAsync().ConfigureAwait(false)) !;

                model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                Contract.ThrowIfNull(model);

                // Make Safe to add namespaces
                document = document.WithSyntaxRoot(
                    MakeSafeToAddNamespaces(root, namespaceSymbols, model, document.Project.Solution.Workspace, cancellationToken));
                root = (await document.GetSyntaxRootAsync().ConfigureAwait(false)) !;

                model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                Contract.ThrowIfNull(model);

                // Find the context. It might be null if we have removed the context in the process of complexifying the tree.
                context = root.DescendantNodesAndSelf().FirstOrDefault(x => x.HasAnnotation(annotation)) ?? root;
            }

            model ??= await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var placeSystemNamespaceFirst = options.GetOption(GenerationOptions.PlaceSystemNamespaceFirst, document.Project.Language);

            root = addImportsService.AddImports(model.Compilation, root, context, importDirectivesToAdd, generator, placeSystemNamespaceFirst, cancellationToken);

            return(document.WithSyntaxRoot(root));

            bool IsInSpan(SyntaxNode node) =>
            spansTree.HasIntervalThatOverlapsWith(node.FullSpan.Start, node.FullSpan.Length);
        }
Esempio n. 9
0
        internal ImmutableArray <TypeParameterConstraintClause> BindTypeParameterConstraintClauses(
            Symbol containingSymbol,
            ImmutableArray <TypeParameterSymbol> typeParameters,
            TypeParameterListSyntax typeParameterList,
            SyntaxList <TypeParameterConstraintClauseSyntax> clauses,
            ref IReadOnlyDictionary <TypeParameterSymbol, bool> isValueTypeOverride,
            DiagnosticBag diagnostics,
            bool isForOverride = false)
        {
            Debug.Assert(this.Flags.Includes(BinderFlags.GenericConstraintsClause));
            RoslynDebug.Assert((object)containingSymbol != null);
            Debug.Assert((containingSymbol.Kind == SymbolKind.NamedType) || (containingSymbol.Kind == SymbolKind.Method));
            Debug.Assert(typeParameters.Length > 0);
            Debug.Assert(clauses.Count > 0);

            int n = typeParameters.Length;

            // Create a map from type parameter name to ordinal.
            // No need to report duplicate names since duplicates
            // are reported when the type parameters are bound.
            var names = new Dictionary <string, int>(n, StringOrdinalComparer.Instance);

            foreach (var typeParameter in typeParameters)
            {
                var name = typeParameter.Name;
                if (!names.ContainsKey(name))
                {
                    names.Add(name, names.Count);
                }
            }

            // An array of constraint clauses, one for each type parameter, indexed by ordinal.
            var results = ArrayBuilder <TypeParameterConstraintClause?> .GetInstance(n, fillWithValue : null);

            var syntaxNodes = ArrayBuilder <ArrayBuilder <TypeConstraintSyntax>?> .GetInstance(n, fillWithValue : null);

            // Bind each clause and add to the results.
            foreach (var clause in clauses)
            {
                var name = clause.Name.Identifier.ValueText;
                RoslynDebug.Assert(name is object);
                int ordinal;
                if (names.TryGetValue(name, out ordinal))
                {
                    Debug.Assert(ordinal >= 0);
                    Debug.Assert(ordinal < n);

                    (TypeParameterConstraintClause constraintClause, ArrayBuilder <TypeConstraintSyntax>?typeConstraintNodes) = this.BindTypeParameterConstraints(typeParameterList.Parameters[ordinal], clause, isForOverride, diagnostics);
                    if (results[ordinal] == null)
                    {
                        results[ordinal]     = constraintClause;
                        syntaxNodes[ordinal] = typeConstraintNodes;
                    }
                    else
                    {
                        // "A constraint clause has already been specified for type parameter '{0}'. ..."
                        diagnostics.Add(ErrorCode.ERR_DuplicateConstraintClause, clause.Name.Location, name);
                        typeConstraintNodes?.Free();
                    }
                }
                else
                {
                    // Unrecognized type parameter. Don't bother binding the constraints
                    // (the ": I<U>" in "where U : I<U>") since that will lead to additional
                    // errors ("type or namespace 'U' could not be found") if the type
                    // parameter is referenced in the constraints.

                    // "'{1}' does not define type parameter '{0}'"
                    diagnostics.Add(ErrorCode.ERR_TyVarNotFoundInConstraint, clause.Name.Location, name, containingSymbol.ConstructedFrom());
                }
            }

            // Add default values for type parameters without constraint clauses.
            for (int i = 0; i < n; i++)
            {
                if (results[i] == null)
                {
                    results[i] = GetDefaultTypeParameterConstraintClause(typeParameterList.Parameters[i], isForOverride);
                }
            }

            TypeParameterConstraintClause.AdjustConstraintTypes(containingSymbol, typeParameters, results, ref isValueTypeOverride);

            RemoveInvalidConstraints(typeParameters, results !, syntaxNodes, diagnostics);

            foreach (var typeConstraintsSyntaxes in syntaxNodes)
            {
                typeConstraintsSyntaxes?.Free();
            }

            syntaxNodes.Free();

            return(results.ToImmutableAndFree() !);
        }
Esempio n. 10
0
            /// <summary>
            /// Given a ISymbol, returns the renameable locations for a given symbol.
            /// </summary>
            public static async Task <ImmutableArray <RenameLocation> > GetRenamableDefinitionLocationsAsync(
                ISymbol referencedSymbol, ISymbol originalSymbol, Solution solution, CancellationToken cancellationToken)
            {
                var shouldIncludeSymbol = await ShouldIncludeSymbolAsync(referencedSymbol, originalSymbol, solution, false, cancellationToken).ConfigureAwait(false);

                if (!shouldIncludeSymbol)
                {
                    return(ImmutableArray <RenameLocation> .Empty);
                }

                // Namespaces are definitions and references all in one. Since every definition
                // location is also a reference, we'll ignore it's definitions.
                if (referencedSymbol.Kind == SymbolKind.Namespace)
                {
                    return(ImmutableArray <RenameLocation> .Empty);
                }

                var results = ArrayBuilder <RenameLocation> .GetInstance();

                // If the original symbol was an alias, then the definitions will just be the
                // location of the alias, always
                if (originalSymbol.Kind == SymbolKind.Alias)
                {
                    var location = originalSymbol.Locations.Single();
                    AddRenameLocationIfNotGenerated(location);
                    return(results.ToImmutableAndFree());
                }

                var isRenamableAccessor = await IsPropertyAccessorOrAnOverrideAsync(referencedSymbol, solution, cancellationToken).ConfigureAwait(false);

                foreach (var location in referencedSymbol.Locations)
                {
                    if (location.IsInSource)
                    {
                        AddRenameLocationIfNotGenerated(location, isRenamableAccessor);
                    }
                }

                // If we're renaming a named type, we'll also have to find constructors and
                // destructors declarations that match the name
                if (referencedSymbol.Kind == SymbolKind.NamedType && referencedSymbol.Locations.All(l => l.IsInSource))
                {
                    var firstLocation = referencedSymbol.Locations[0];
                    var syntaxFacts   = solution.GetRequiredDocument(firstLocation.SourceTree !)
                                        .GetRequiredLanguageService <ISyntaxFactsService>();

                    var namedType = (INamedTypeSymbol)referencedSymbol;
                    foreach (var method in namedType.GetMembers().OfType <IMethodSymbol>())
                    {
                        if (!method.IsImplicitlyDeclared && (method.MethodKind == MethodKind.Constructor ||
                                                             method.MethodKind == MethodKind.StaticConstructor ||
                                                             method.MethodKind == MethodKind.Destructor))
                        {
                            foreach (var location in method.Locations)
                            {
                                if (location.IsInSource)
                                {
                                    var token = location.FindToken(cancellationToken);
                                    if (!syntaxFacts.IsReservedOrContextualKeyword(token) &&
                                        token.ValueText == referencedSymbol.Name)
                                    {
                                        AddRenameLocationIfNotGenerated(location);
                                    }
                                }
                            }
                        }
                    }
                }

                return(results.ToImmutableAndFree());

                void AddRenameLocationIfNotGenerated(Location location, bool isRenamableAccessor = false)
                {
                    RoslynDebug.Assert(location.IsInSource);
                    var document = solution.GetRequiredDocument(location.SourceTree);

                    // If the location is in a source generated file, we won't rename it. Our assumption in this case is we
                    // have cascaded to this symbol from our original source symbol, and the generator will update this file
                    // based on the renamed symbol.
                    if (document is not SourceGeneratedDocument)
                    {
                        results.Add(new RenameLocation(location, document.Id, isRenamableAccessor: isRenamableAccessor));
                    }
                }
            }
        // Both hash computations below use the FNV-1a algorithm (http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function).

        internal static int GetHashCode(byte[] x)
        {
            RoslynDebug.Assert(x != null);
            return(Hash.GetFNVHashCode(x));
        }
Esempio n. 12
0
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.ReportDiagnostics);
            analysisContext.EnableConcurrentExecution();

            analysisContext.RegisterCompilationStartAction(
                (CompilationStartAnalysisContext compilationStartAnalysisContext) =>
            {
                if (!compilationStartAnalysisContext.Compilation.TryGetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.NewtonsoftJsonTypeNameHandling,
                        out INamedTypeSymbol? typeNameHandlingSymbol))
                {
                    return;
                }

                compilationStartAnalysisContext.RegisterOperationAction(
                    (OperationAnalysisContext operationAnalysisContext) =>
                {
                    IFieldReferenceOperation fieldReferenceOperation =
                        (IFieldReferenceOperation)operationAnalysisContext.Operation;
                    if (IsOtherThanNone(fieldReferenceOperation))
                    {
                        operationAnalysisContext.ReportDiagnostic(
                            fieldReferenceOperation.CreateDiagnostic(Rule));
                    }
                },
                    OperationKind.FieldReference);

                compilationStartAnalysisContext.RegisterOperationAction(
                    (OperationAnalysisContext operationAnalysisContext) =>
                {
                    IAssignmentOperation assignmentOperation = (IAssignmentOperation)operationAnalysisContext.Operation;
                    if (!typeNameHandlingSymbol.Equals(assignmentOperation.Target.Type))
                    {
                        return;
                    }

                    // Find the topmost operation with non-zero (not None), unless we find an operation that would've
                    // been flagged by the FieldReference callback above.
                    foreach (IOperation childOperation in assignmentOperation.Value.DescendantsAndSelf())
                    {
                        if (childOperation is IFieldReferenceOperation fieldReferenceOperation &&
                            IsOtherThanNone(fieldReferenceOperation))
                        {
                            return;
                        }

                        if (childOperation.ConstantValue.HasValue &&
                            childOperation.ConstantValue.Value is int integerValue &&
                            integerValue != 0)
                        {
                            operationAnalysisContext.ReportDiagnostic(childOperation.CreateDiagnostic(Rule));
                            return;
                        }
                    }
                },
                    OperationKind.SimpleAssignment,
                    OperationKind.CompoundAssignment);

                return;

                bool IsOtherThanNone(IFieldReferenceOperation fieldReferenceOperation)
                {
                    RoslynDebug.Assert(typeNameHandlingSymbol != null);
                    if (!typeNameHandlingSymbol.Equals(fieldReferenceOperation.Field.ContainingType))
                    {
                        return(false);
                    }

                    return(fieldReferenceOperation.Field.Name != "None");
                };
            });
        }
Esempio n. 13
0
        private void TrackBulkFileOperations()
        {
            RoslynDebug.AssertNotNull(_workspace);

            // we will pause whatever ambient work loads we have that are tied to IGlobalOperationNotificationService
            // such as solution crawler, pre-emptive remote host synchronization and etc. any background work users didn't
            // explicitly asked for.
            //
            // this should give all resources to BulkFileOperation. we do same for things like build,
            // debugging, wait dialog and etc. BulkFileOperation is used for things like git branch switching and etc.
            var globalNotificationService = _workspace.Services.GetRequiredService <IGlobalOperationNotificationService>();

            // BulkFileOperation can't have nested events. there will be ever only 1 events (Begin/End)
            // so we only need simple tracking.
            var gate = new object();
            GlobalOperationRegistration?localRegistration = null;

            BulkFileOperation.End += (s, a) =>
            {
                StopBulkFileOperationNotification();
            };

            BulkFileOperation.Begin += (s, a) =>
            {
                StartBulkFileOperationNotification();
            };

            void StartBulkFileOperationNotification()
            {
                RoslynDebug.Assert(gate != null);
                RoslynDebug.Assert(globalNotificationService != null);

                lock (gate)
                {
                    // this shouldn't happen, but we are using external component
                    // so guarding us from them
                    if (localRegistration != null)
                    {
                        FatalError.ReportWithoutCrash(new InvalidOperationException("BulkFileOperation already exist"));
                        return;
                    }

                    localRegistration = globalNotificationService.Start("BulkFileOperation");
                }
            }

            void StopBulkFileOperationNotification()
            {
                RoslynDebug.Assert(gate != null);

                lock (gate)
                {
                    // this can happen if BulkFileOperation was already in the middle
                    // of running. to make things simpler, decide to not use IsInProgress
                    // which we need to worry about race case.
                    if (localRegistration == null)
                    {
                        return;
                    }

                    localRegistration.Dispose();
                    localRegistration = null;
                }
            }
        }
Esempio n. 14
0
 internal CommandLineParser(CommonMessageProvider messageProvider, bool isScriptCommandLineParser)
 {
     RoslynDebug.Assert(messageProvider != null);
     _messageProvider          = messageProvider;
     IsScriptCommandLineParser = isScriptCommandLineParser;
 }
Esempio n. 15
0
        private static void AnalyzeSymbol(
            SymbolAnalysisContext context,
            INamedTypeSymbol?iCollectionType,
            INamedTypeSymbol?gCollectionType,
            INamedTypeSymbol?iEnumerableType,
            INamedTypeSymbol?gEnumerableType,
            INamedTypeSymbol?iListType,
            INamedTypeSymbol?gListType)
        {
            var namedTypeSymbol = (INamedTypeSymbol)context.Symbol;

            // FxCop compat: only fire on externally visible types by default.
            if (!namedTypeSymbol.MatchesConfiguredVisibility(context.Options, Rule, context.CancellationToken))
            {
                return;
            }

            var allInterfacesStatus = default(CollectionsInterfaceStatus);

            foreach (var @interface in namedTypeSymbol.AllInterfaces)
            {
                var originalDefinition = @interface.OriginalDefinition;
                if (originalDefinition.Equals(iCollectionType))
                {
                    allInterfacesStatus.ICollectionPresent = true;
                }
                else if (originalDefinition.Equals(iEnumerableType))
                {
                    allInterfacesStatus.IEnumerablePresent = true;
                }
                else if (originalDefinition.Equals(iListType))
                {
                    allInterfacesStatus.IListPresent = true;
                }
                else if (originalDefinition.Equals(gCollectionType))
                {
                    allInterfacesStatus.GenericICollectionPresent = true;
                }
                else if (originalDefinition.Equals(gEnumerableType))
                {
                    allInterfacesStatus.GenericIEnumerablePresent = true;
                }
                else if (originalDefinition.Equals(gListType))
                {
                    allInterfacesStatus.GenericIListPresent = true;
                }
            }

            INamedTypeSymbol?missingInterface;
            INamedTypeSymbol?implementedInterface;

            if (allInterfacesStatus.GenericIListPresent)
            {
                // Implemented IList<T>, meaning has all 3 generic interfaces. Nothing can be wrong.
                return;
            }
            else if (allInterfacesStatus.IListPresent)
            {
                // Implemented IList but not IList<T>.
                missingInterface     = gListType;
                implementedInterface = iListType;
            }
            else if (allInterfacesStatus.GenericICollectionPresent)
            {
                // Implemented ICollection<T>, and doesn't have an inherit of IList. Nothing can be wrong
                return;
            }
            else if (allInterfacesStatus.ICollectionPresent)
            {
                // Implemented ICollection but not ICollection<T>
                missingInterface     = gCollectionType;
                implementedInterface = iCollectionType;
            }
            else if (allInterfacesStatus.GenericIEnumerablePresent)
            {
                // Implemented IEnumerable<T>, and doesn't have an inherit of ICollection. Nothing can be wrong
                return;
            }
            else if (allInterfacesStatus.IEnumerablePresent)
            {
                // Implemented IEnumerable, but not IEnumerable<T>
                missingInterface     = gEnumerableType;
                implementedInterface = iEnumerableType;
            }
            else
            {
                // No collections implementation, nothing can be wrong.
                return;
            }

            RoslynDebug.Assert(missingInterface != null && implementedInterface != null);
            context.ReportDiagnostic(Diagnostic.Create(Rule,
                                                       namedTypeSymbol.Locations.First(),
                                                       namedTypeSymbol.Name,
                                                       implementedInterface.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                       missingInterface.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)));
        }
Esempio n. 16
0
        /// <summary>
        /// Zero or more named arguments that specify values for fields and properties of the attribute.
        /// </summary>
        public ImmutableArray <Cci.IMetadataNamedArgument> GetNamedArguments(EmitContext context)
        {
            // Perform fixup
            Cci.ITypeReference stringType = context.Module.GetPlatformType(
                Cci.PlatformType.SystemString,
                context
                );

#if DEBUG
            // Must have exactly 1 named argument.
            var namedArgs = _sourceAttribute.GetNamedArguments(context);
            Debug.Assert(namedArgs.Length == 1);

            // Named argument must be 'File' property of string type
            var fileArg = namedArgs.First();
            Debug.Assert(fileArg.ArgumentName == FilePropertyName);
            Debug.Assert(
                context.Module.IsPlatformType(fileArg.Type, Cci.PlatformType.SystemString)
                );

            // Named argument value must be a non-empty string
            Debug.Assert(fileArg.ArgumentValue is MetadataConstant);
            var fileName = (string?)((MetadataConstant)fileArg.ArgumentValue).Value;
            Debug.Assert(!String.IsNullOrEmpty(fileName));

            // PermissionSetAttribute type must have a writable public string type property member 'Hex'
            ISymbol iSymbol = _sourceAttribute.GetType(context).GetInternalSymbol() !.GetISymbol();
            Debug.Assert(
                ((INamedTypeSymbol)iSymbol)
                .GetMembers(HexPropertyName)
                .Any(
                    member =>
                    member.Kind == SymbolKind.Property &&
                    ((IPropertySymbol)member).Type.SpecialType
                    == SpecialType.System_String
                    )
                );
#endif

            string hexFileContent;

            // Read the file contents at the resolved file path into a byte array.
            // May throw PermissionSetFileReadException, which is handled in Compilation.Emit.
            var resolver = context.Module.CommonCompilation.Options.XmlReferenceResolver;

            // If the resolver isn't available we won't get here since we had to use it to resolve the path.
            RoslynDebug.Assert(resolver != null);

            try
            {
                using (Stream stream = resolver.OpenReadChecked(_resolvedPermissionSetFilePath))
                {
                    // Convert the byte array contents into a string in hexadecimal format.
                    hexFileContent = ConvertToHex(stream);
                }
            }
            catch (IOException e)
            {
                throw new PermissionSetFileReadException(e.Message, _resolvedPermissionSetFilePath);
            }

            // Synthesize a named attribute argument "Hex = hexFileContent".
            return(ImmutableArray.Create <Cci.IMetadataNamedArgument>(
                       new HexPropertyMetadataNamedArgument(
                           stringType,
                           new MetadataConstant(stringType, hexFileContent)
                           )
                       ));
        }
        private static bool TryGetReleaseTrackingData(
            ImmutableArray <AdditionalText> additionalTexts,
            CancellationToken cancellationToken,
            [NotNullWhen(returnValue: true)] out ReleaseTrackingData?shippedData,
            [NotNullWhen(returnValue: true)] out ReleaseTrackingData?unshippedData,
            out List <Diagnostic>?invalidFileDiagnostics)
        {
            if (!TryGetReleaseTrackingFiles(additionalTexts, cancellationToken, out var shippedText, out var unshippedText))
            {
                // TODO: Report a diagnostic that both must be specified if either shippedText or unshippedText is non-null.
                shippedData            = shippedText != null ? ReleaseTrackingData.Default : null;
                unshippedData          = unshippedText != null ? ReleaseTrackingData.Default : null;
                invalidFileDiagnostics = null;
                return(false);
            }

            var diagnostics = new List <Diagnostic>();

            using var reportedInvalidLines = PooledHashSet <TextLine> .GetInstance();

            shippedData   = ReadReleaseTrackingData(shippedText.Path, shippedText.GetText(cancellationToken), OnDuplicateEntryInRelease, OnInvalidEntry, isShippedFile: true);
            unshippedData = ReadReleaseTrackingData(unshippedText.Path, unshippedText.GetText(cancellationToken), OnDuplicateEntryInRelease, OnInvalidEntry, isShippedFile: false);

            invalidFileDiagnostics = diagnostics;
            return(invalidFileDiagnostics.Count == 0);

            // Local functions.
            void OnDuplicateEntryInRelease(string ruleId, Version currentVersion, string path, SourceText sourceText, TextLine line)
            {
                if (!reportedInvalidLines.Add(line))
                {
                    // Already reported.
                    return;
                }

                RoslynDebug.Assert(diagnostics != null);

                // Rule '{0}' has more then one entry for release '{1}' in analyzer release file '{2}'.
                string           arg1             = ruleId;
                string           arg2             = currentVersion == UnshippedVersion ? "unshipped" : currentVersion.ToString();
                string           arg3             = Path.GetFileName(path);
                LinePositionSpan linePositionSpan = sourceText.Lines.GetLinePositionSpan(line.Span);
                Location         location         = Location.Create(path, line.Span, linePositionSpan);
                var diagnostic = Diagnostic.Create(RemoveDuplicateEntriesForAnalyzerReleaseRule, location, arg1, arg2, arg3);

                diagnostics.Add(diagnostic);
            }

            void OnInvalidEntry(TextLine line, InvalidEntryKind invalidEntryKind, string path, SourceText sourceText)
            {
                RoslynDebug.Assert(diagnostics != null);
                RoslynDebug.Assert(reportedInvalidLines != null);

                if (!reportedInvalidLines.Add(line))
                {
                    // Already reported.
                    return;
                }

                var rule = invalidEntryKind switch
                {
                    // Analyzer release file '{0}' has a missing or invalid release header '{1}'.
                    InvalidEntryKind.Header => InvalidHeaderInAnalyzerReleasesFileRule,

                    // Analyzer release file '{0}' has an entry with one or more 'Undetected' fields that need to be manually filled in '{1}'.
                    InvalidEntryKind.UndetectedField => InvalidUndetectedEntryInAnalyzerReleasesFileRule,

                    // Analyzer release file '{0}' has an invalid entry '{1}'.
                    InvalidEntryKind.Other => InvalidEntryInAnalyzerReleasesFileRule,
                    _ => throw new NotImplementedException(),
                };

                string           arg1             = Path.GetFileName(path);
                string           arg2             = line.ToString();
                LinePositionSpan linePositionSpan = sourceText.Lines.GetLinePositionSpan(line.Span);
                Location         location         = Location.Create(path, line.Span, linePositionSpan);
                var diagnostic = Diagnostic.Create(rule, location, arg1, arg2);

                diagnostics.Add(diagnostic);
            }
        }
Esempio n. 18
0
 protected void AdjustFlagsAndWidth(GreenNode node)
 {
     RoslynDebug.Assert(node != null, "PERF: caller must ensure that node!=null, we do not want to re-check that here.");
     this.flags |= (node.flags & NodeFlags.InheritMask);
     _fullWidth += node._fullWidth;
 }
Esempio n. 19
0
 private FloatingValueSet(IValueSet <TFloating> numbers, bool hasNaN)
 {
     RoslynDebug.Assert(numbers is NumericValueSet <TFloating, TFloatingTC>);
     (_numbers, _hasNaN) = (numbers, hasNaN);
 }
 public WrappedEventSymbol(EventSymbol underlyingEvent)
 {
     RoslynDebug.Assert((object)underlyingEvent != null);
     _underlyingEvent = underlyingEvent;
 }
Esempio n. 21
0
        public bool TryCreateForTupleElements(ITupleOperation tupleOperation, [NotNullWhen(returnValue: true)] out ImmutableArray <AnalysisEntity> elementEntities)
        {
            if (_tupleElementEntitiesMap.TryGetValue(tupleOperation, out elementEntities))
            {
                return(!elementEntities.IsDefault);
            }

            try
            {
                elementEntities = default;
                if (tupleOperation.Type?.IsTupleType != true ||
                    _getPointsToAbstractValueOpt == null)
                {
                    return(false);
                }

                var tupleType = (INamedTypeSymbol)tupleOperation.Type;
                if (tupleType.TupleElements.IsDefault)
                {
                    return(false);
                }

                PointsToAbstractValue instanceLocation  = _getPointsToAbstractValueOpt(tupleOperation);
                var            underlyingValueTupleType = tupleType.GetUnderlyingValueTupleTypeOrThis();
                AnalysisEntity?parentEntity             = null;
                if (tupleOperation.TryGetParentTupleOperation(out var parentTupleOperationOpt, out var elementOfParentTupleContainingTuple) &&
                    TryCreateForTupleElements(parentTupleOperationOpt, out var parentTupleElementEntities))
                {
                    Debug.Assert(parentTupleOperationOpt.Elements.Length == parentTupleElementEntities.Length);
                    for (int i = 0; i < parentTupleOperationOpt.Elements.Length; i++)
                    {
                        if (parentTupleOperationOpt.Elements[i] == elementOfParentTupleContainingTuple)
                        {
                            parentEntity     = parentTupleElementEntities[i];
                            instanceLocation = parentEntity.InstanceLocation;
                            break;
                        }
                    }

                    RoslynDebug.Assert(parentEntity != null);
                }
                else
                {
                    parentEntity = AnalysisEntity.Create(underlyingValueTupleType, ImmutableArray <AbstractIndex> .Empty,
                                                         underlyingValueTupleType, instanceLocation, parentOpt: null);
                }

                Debug.Assert(parentEntity.InstanceLocation == instanceLocation);

                var builder = ArrayBuilder <AnalysisEntity> .GetInstance(tupleType.TupleElements.Length);

                foreach (var field in tupleType.TupleElements)
                {
                    var tupleFieldName        = field.CorrespondingTupleField.Name;
                    var mappedValueTupleField = underlyingValueTupleType.GetMembers(tupleFieldName).OfType <IFieldSymbol>().FirstOrDefault();
                    if (mappedValueTupleField == null)
                    {
                        builder.Free();
                        return(false);
                    }

                    builder.Add(AnalysisEntity.Create(mappedValueTupleField, indices: ImmutableArray <AbstractIndex> .Empty,
                                                      type: mappedValueTupleField.Type, instanceLocation, parentEntity));
                }

                elementEntities = builder.ToImmutableAndFree();
                return(true);
            }
        private static void UpdateLocation(
            SemanticModel semanticModel, INamedTypeSymbol interfaceType,
            SyntaxEditor editor, ISyntaxFactsService syntaxFacts,
            Location location, CancellationToken cancellationToken)
        {
            var identifierName = location.FindNode(getInnermostNodeForTie: true, cancellationToken);

            if (identifierName == null || !syntaxFacts.IsIdentifierName(identifierName))
            {
                return;
            }

            var node = syntaxFacts.IsNameOfMemberAccessExpression(identifierName) || syntaxFacts.IsMemberBindingExpression(identifierName.Parent)
                ? identifierName.Parent
                : identifierName;

            RoslynDebug.Assert(node is object);
            if (syntaxFacts.IsInvocationExpression(node.Parent))
            {
                node = node.Parent;
            }

            var operation = semanticModel.GetOperation(node, cancellationToken);
            var instance  = operation switch
            {
                IMemberReferenceOperation memberReference => memberReference.Instance,
                IInvocationOperation invocation => invocation.Instance,
                _ => null,
            };

            if (instance == null)
            {
                return;
            }

            if (instance.IsImplicit)
            {
                if (instance is IInstanceReferenceOperation instanceReference &&
                    instanceReference.ReferenceKind != InstanceReferenceKind.ContainingTypeInstance)
                {
                    return;
                }

                // Accessing the member not off of <dot>.  i.e just plain `Goo()`.  Replace with
                // ((IGoo)this).Goo();
                var generator = editor.Generator;
                editor.ReplaceNode(
                    identifierName,
                    generator.MemberAccessExpression(
                        generator.AddParentheses(generator.CastExpression(interfaceType, generator.ThisExpression())),
                        identifierName.WithoutTrivia()).WithTriviaFrom(identifierName));
            }
            else
            {
                // Accessing the member like `x.Goo()`.  Replace with `((IGoo)x).Goo()`
                editor.ReplaceNode(
                    instance.Syntax, (current, g) =>
                    g.AddParentheses(
                        g.CastExpression(interfaceType, current.WithoutTrivia())).WithTriviaFrom(current));
            }
        }
 protected virtual bool FileExists(string fullPath)
 {
     RoslynDebug.Assert(fullPath != null);
     RoslynDebug.Assert(PathUtilities.IsAbsolute(fullPath));
     return(File.Exists(fullPath));
 }
Esempio n. 24
0
 internal ValidTargetsStringLocalizableErrorArgument(string[] targetResourceIds)
 {
     RoslynDebug.Assert(targetResourceIds != null);
     _targetResourceIds = targetResourceIds;
 }
Esempio n. 25
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();

            // Security analyzer - analyze and report diagnostics on generated code.
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

            context.RegisterCompilationStartAction(
                (CompilationStartAnalysisContext compilationStartAnalysisContext) =>
            {
                if (!compilationStartAnalysisContext.Compilation.TryGetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemSecurityAuthenticationSslProtocols,
                        out INamedTypeSymbol? sslProtocolsSymbol))
                {
                    return;
                }

                compilationStartAnalysisContext.RegisterOperationAction(
                    (OperationAnalysisContext operationAnalysisContext) =>
                {
                    IFieldReferenceOperation fieldReferenceOperation = (IFieldReferenceOperation)operationAnalysisContext.Operation;
                    if (IsReferencingSslProtocols(
                            fieldReferenceOperation,
                            out bool isDeprecatedProtocol,
                            out bool isHardcodedOkayProtocol))
                    {
                        if (isDeprecatedProtocol)
                        {
                            operationAnalysisContext.ReportDiagnostic(
                                fieldReferenceOperation.CreateDiagnostic(
                                    DeprecatedRule,
                                    fieldReferenceOperation.Field.Name));
                        }
                        else if (isHardcodedOkayProtocol)
                        {
                            operationAnalysisContext.ReportDiagnostic(
                                fieldReferenceOperation.CreateDiagnostic(
                                    HardcodedRule,
                                    fieldReferenceOperation.Field.Name));
                        }
                    }
                },
                    OperationKind.FieldReference);

                compilationStartAnalysisContext.RegisterOperationAction(
                    (OperationAnalysisContext operationAnalysisContext) =>
                {
                    IOperation?valueOperation;
                    switch (operationAnalysisContext.Operation)
                    {
                    case IAssignmentOperation assignmentOperation:
                        // Make sure this is an assignment operation for a SslProtocols value.
                        if (!sslProtocolsSymbol.Equals(assignmentOperation.Target.Type))
                        {
                            return;
                        }

                        valueOperation = assignmentOperation.Value;
                        break;

                    case IArgumentOperation argumentOperation:
                        if (!sslProtocolsSymbol.Equals(argumentOperation.Type))
                        {
                            return;
                        }

                        valueOperation = argumentOperation.Value;
                        break;

                    case IReturnOperation returnOperation:
                        if (returnOperation.ReturnedValue == null ||
                            !sslProtocolsSymbol.Equals(returnOperation.ReturnedValue.Type))
                        {
                            return;
                        }

                        valueOperation = returnOperation.ReturnedValue;
                        break;

                    case IVariableInitializerOperation variableInitializerOperation:
                        if (variableInitializerOperation.Value == null ||
                            !sslProtocolsSymbol.Equals(variableInitializerOperation.Value.Type))
                        {
                            return;
                        }

                        valueOperation = variableInitializerOperation.Value;
                        break;

                    default:
                        Debug.Fail("Unhandled IOperation " + operationAnalysisContext.Operation.Kind);
                        return;
                    }

                    // Find the topmost operation with a bad bit set, unless we find an operation that would've been
                    // flagged by the FieldReference callback above.
                    IOperation?foundDeprecatedOperation = null;
                    bool foundDeprecatedReference       = false;
                    IOperation?foundHardcodedOperation  = null;
                    bool foundHardcodedReference        = false;
                    foreach (IOperation childOperation in valueOperation.DescendantsAndSelf())
                    {
                        if (childOperation is IFieldReferenceOperation fieldReferenceOperation &&
                            IsReferencingSslProtocols(
                                fieldReferenceOperation,
                                out var isDeprecatedProtocol,
                                out var isHardcodedOkayProtocol))
                        {
                            if (isDeprecatedProtocol)
                            {
                                foundDeprecatedReference = true;
                            }
                            else if (isHardcodedOkayProtocol)
                            {
                                foundHardcodedReference = true;
                            }

                            if (foundDeprecatedReference && foundHardcodedReference)
                            {
                                return;
                            }
                        }

                        if (childOperation.ConstantValue.HasValue &&
                            childOperation.ConstantValue.Value is int integerValue)
                        {
                            if (foundDeprecatedOperation == null &&         // Only want the first.
                                (integerValue & UnsafeBits) != 0)
                            {
                                foundDeprecatedOperation = childOperation;
                            }

                            if (foundHardcodedOperation == null &&         // Only want the first.
                                (integerValue & HardcodedBits) != 0)
                            {
                                foundHardcodedOperation = childOperation;
                            }
                        }
                    }

                    if (foundDeprecatedOperation != null && !foundDeprecatedReference)
                    {
                        operationAnalysisContext.ReportDiagnostic(
                            foundDeprecatedOperation.CreateDiagnostic(
                                DeprecatedRule,
                                foundDeprecatedOperation.ConstantValue));
                    }

                    if (foundHardcodedOperation != null && !foundHardcodedReference)
                    {
                        operationAnalysisContext.ReportDiagnostic(
                            foundHardcodedOperation.CreateDiagnostic(
                                HardcodedRule,
                                foundHardcodedOperation.ConstantValue));
                    }
                },
                    OperationKind.SimpleAssignment,
                    OperationKind.CompoundAssignment,
                    OperationKind.Argument,
                    OperationKind.Return,
                    OperationKind.VariableInitializer);

                return;

                // Local function(s).
                bool IsReferencingSslProtocols(
                    IFieldReferenceOperation fieldReferenceOperation,
                    out bool isDeprecatedProtocol,
                    out bool isHardcodedOkayProtocol)
                {
                    RoslynDebug.Assert(sslProtocolsSymbol != null);

                    if (sslProtocolsSymbol.Equals(fieldReferenceOperation.Field.ContainingType))
                    {
                        if (HardcodedSslProtocolsMetadataNames.Contains(fieldReferenceOperation.Field.Name))
                        {
                            isHardcodedOkayProtocol = true;
                            isDeprecatedProtocol    = false;
                        }
                        else if (fieldReferenceOperation.Field.Name == "None")
                        {
                            isHardcodedOkayProtocol = false;
                            isDeprecatedProtocol    = false;
                        }
                        else
                        {
                            isDeprecatedProtocol    = true;
                            isHardcodedOkayProtocol = false;
                        }

                        return(true);
                    }
                    else
                    {
                        isHardcodedOkayProtocol = false;
                        isDeprecatedProtocol    = false;
                        return(false);
                    }
                }
            });
        }
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();

            // Security analyzer - analyze and report diagnostics on generated code.
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

            context.RegisterCompilationStartAction(
                (CompilationStartAnalysisContext compilationStartAnalysisContext) =>
            {
                var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilationStartAnalysisContext.Compilation);
                if (!wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemNetSecurityProtocolType,
                        out var securityProtocolTypeTypeSymbol) ||
                    !wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemNetServicePointManager,
                        out var servicePointManagerTypeSymbol))
                {
                    return;
                }

                compilationStartAnalysisContext.RegisterOperationAction(
                    (OperationAnalysisContext operationAnalysisContext) =>
                {
                    var fieldReferenceOperation = (IFieldReferenceOperation)operationAnalysisContext.Operation;

                    // Make sure we're not inside an &= assignment like:
                    //   ServicePointManager.SecurityProtocol &= ~(SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11)
                    // cuz &= is at worst, disabling protocol versions.
                    if (IsReferencingSecurityProtocolType(
                            fieldReferenceOperation,
                            out var isDeprecatedProtocol,
                            out var isHardCodedOkayProtocol) &&
                        null == fieldReferenceOperation.GetAncestor <ICompoundAssignmentOperation>(
                            OperationKind.CompoundAssignment,
                            IsAndEqualsServicePointManagerAssignment))
                    {
                        if (isDeprecatedProtocol)
                        {
                            operationAnalysisContext.ReportDiagnostic(
                                fieldReferenceOperation.CreateDiagnostic(
                                    DeprecatedRule,
                                    fieldReferenceOperation.Field.Name));
                        }
                        else if (isHardCodedOkayProtocol)
                        {
                            operationAnalysisContext.ReportDiagnostic(
                                fieldReferenceOperation.CreateDiagnostic(
                                    HardCodedRule,
                                    fieldReferenceOperation.Field.Name));
                        }
                    }
                }, OperationKind.FieldReference);

                compilationStartAnalysisContext.RegisterOperationAction(
                    (OperationAnalysisContext operationAnalysisContext) =>
                {
                    var assignmentOperation = (IAssignmentOperation)operationAnalysisContext.Operation;

                    // Make sure this is an assignment operation for a SecurityProtocolType, and not
                    // an assignment like:
                    //   ServicePointManager.SecurityProtocol &= ~(SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11)
                    // cuz &= is at worst, disabling protocol versions.
                    if (!securityProtocolTypeTypeSymbol.Equals(assignmentOperation.Target.Type) ||
                        (assignmentOperation is ICompoundAssignmentOperation compoundAssignmentOperation &&
                         IsAndEqualsServicePointManagerAssignment(compoundAssignmentOperation)))
                    {
                        return;
                    }

                    // Find the topmost operation with a bad bit set, unless we find an operation that would've been
                    // flagged by the FieldReference callback above.
                    IOperation?foundDeprecatedOperation = null;
                    bool foundDeprecatedReference       = false;
                    IOperation?foundHardCodedOperation  = null;
                    bool foundHardCodedReference        = false;
                    foreach (IOperation childOperation in assignmentOperation.Value.DescendantsAndSelf())
                    {
                        if (childOperation is IFieldReferenceOperation fieldReferenceOperation &&
                            IsReferencingSecurityProtocolType(
                                fieldReferenceOperation,
                                out var isDeprecatedProtocol,
                                out var isHardCodedOkayProtocol))
                        {
                            if (isDeprecatedProtocol)
                            {
                                foundDeprecatedReference = true;
                            }
                            else if (isHardCodedOkayProtocol)
                            {
                                foundHardCodedReference = true;
                            }

                            if (foundDeprecatedReference && foundHardCodedReference)
                            {
                                return;
                            }
                        }

                        if (childOperation.ConstantValue.HasValue &&
                            childOperation.ConstantValue.Value is int integerValue)
                        {
                            if (foundDeprecatedOperation == null &&         // Only want the first.
                                (integerValue & UnsafeBits) != 0)
                            {
                                foundDeprecatedOperation = childOperation;
                            }

                            if (foundHardCodedOperation == null &&         // Only want the first.
                                (integerValue & HardCodedBits) != 0)
                            {
                                foundHardCodedOperation = childOperation;
                            }
                        }
                    }

                    if (foundDeprecatedOperation != null && !foundDeprecatedReference)
                    {
                        operationAnalysisContext.ReportDiagnostic(
                            foundDeprecatedOperation.CreateDiagnostic(
                                DeprecatedRule,
                                foundDeprecatedOperation.ConstantValue));
                    }

                    if (foundHardCodedOperation != null && !foundHardCodedReference)
                    {
                        operationAnalysisContext.ReportDiagnostic(
                            foundHardCodedOperation.CreateDiagnostic(
                                HardCodedRule,
                                foundHardCodedOperation.ConstantValue));
                    }
                },
                    OperationKind.SimpleAssignment,
                    OperationKind.CompoundAssignment);

                return;

                // Local function(s).
                bool IsReferencingSecurityProtocolType(
                    IFieldReferenceOperation fieldReferenceOperation,
                    out bool isDeprecatedProtocol,
                    out bool isHardCodedOkayProtocol)
                {
                    RoslynDebug.Assert(securityProtocolTypeTypeSymbol != null);

                    if (securityProtocolTypeTypeSymbol.Equals(fieldReferenceOperation.Field.ContainingType))
                    {
                        if (HardCodedSafeProtocolMetadataNames.Contains(fieldReferenceOperation.Field.Name))
                        {
                            isHardCodedOkayProtocol = true;
                            isDeprecatedProtocol    = false;
                        }
                        else if (fieldReferenceOperation.Field.Name == SystemDefaultName)
                        {
                            isHardCodedOkayProtocol = false;
                            isDeprecatedProtocol    = false;
                        }
                        else
                        {
                            isDeprecatedProtocol    = true;
                            isHardCodedOkayProtocol = false;
                        }

                        return(true);
                    }
                    else
                    {
                        isHardCodedOkayProtocol = false;
                        isDeprecatedProtocol    = false;
                        return(false);
                    }
                }

                bool IsAndEqualsServicePointManagerAssignment(ICompoundAssignmentOperation compoundAssignmentOperation)
                {
                    RoslynDebug.Assert(servicePointManagerTypeSymbol != null);

                    return(compoundAssignmentOperation.OperatorKind == BinaryOperatorKind.And &&
                           compoundAssignmentOperation.Target is IPropertyReferenceOperation targetPropertyReference &&
                           targetPropertyReference.Instance == null &&
                           servicePointManagerTypeSymbol.Equals(targetPropertyReference.Property.ContainingType) &&
                           targetPropertyReference.Property.MetadataName == "SecurityProtocol");
                }
            });
        }
 internal MetadataLocation(IModuleSymbolInternal module)
 {
     RoslynDebug.Assert(module != null);
     _module = module;
 }
Esempio n. 28
0
 internal CodeAnalysisResourcesLocalizableErrorArgument(string targetResourceId)
 {
     RoslynDebug.Assert(targetResourceId != null);
     _targetResourceId = targetResourceId;
 }
Esempio n. 29
0
 public ArrayTypeSymbol(Symbols.ArrayTypeSymbol underlying, CodeAnalysis.NullableAnnotation nullableAnnotation)
     : base(nullableAnnotation)
 {
     RoslynDebug.Assert(underlying is object);
     _underlying = underlying;
 }
Esempio n. 30
0
 /// <summary>
 /// Get local functions declared immediately in scope designated by the node.
 /// </summary>
 internal virtual ImmutableArray <LocalFunctionSymbol> GetDeclaredLocalFunctionsForScope(CSharpSyntaxNode scopeDesignator)
 {
     RoslynDebug.Assert(Next is object);
     return(this.Next.GetDeclaredLocalFunctionsForScope(scopeDesignator));
 }