Beispiel #1
0
        private static ReferenceInfo?BuildReference(
            ProjectAssetsFile projectAssets,
            string referenceName,
            bool treatAsUsed,
            ImmutableDictionary <string, ImmutableDictionary <string, string> > targetLibraryKeys,
            Dictionary <string, ReferenceInfo?> builtReferences)
        {
            var dependencyNames       = new HashSet <string>();
            var compilationAssemblies = ImmutableArray.CreateBuilder <string>();
            var referenceType         = ReferenceType.Unknown;
            var itemSpecification     = referenceName;

            var packagesPath = projectAssets.Project?.Restore?.PackagesPath ?? string.Empty;

            RoslynDebug.AssertNotNull(projectAssets.Targets);
            RoslynDebug.AssertNotNull(projectAssets.Libraries);

            foreach (var(targetName, libraryKeys) in targetLibraryKeys)
            {
                if (!libraryKeys.TryGetValue(referenceName, out var key) ||
                    !projectAssets.Libraries.TryGetValue(key, out var library))
                {
                    continue;
                }

                var target        = projectAssets.Targets[targetName];
                var targetLibrary = target[key];

                referenceType = targetLibrary.Type switch
                {
                    "package" => ReferenceType.Package,
                    "project" => ReferenceType.Project,
                    _ => ReferenceType.Assembly
                };

                if (referenceType == ReferenceType.Project &&
                    library.Path is not null)
                {
                    // Project references are keyed by their filename but the
                    // item specification should be the path to the project file
                    // with Windows-style directory separators.
                    itemSpecification = library.Path.Replace('/', '\\');
                }

                if (targetLibrary.Dependencies != null)
                {
                    dependencyNames.AddRange(targetLibrary.Dependencies.Keys);
                }

                if (targetLibrary.Compile != null)
                {
                    foreach (var assemblyPath in targetLibrary.Compile.Keys)
                    {
                        if (!assemblyPath.EndsWith(NuGetEmptyFileName))
                        {
                            compilationAssemblies.Add(Path.GetFullPath(Path.Combine(packagesPath, library.Path ?? "", assemblyPath)));
                        }
                    }
                }
            }

            if (referenceType == ReferenceType.Unknown)
            {
                return(null);
            }

            if (referenceType == ReferenceType.Package && itemSpecification == ".NETStandard.Library")
            {
                // Referencing .NETStandard.Library brings along references to a number of common .NET libraries
                // for which the .NET SDK already brings into the compilation. This makes it very easy for
                // the parent reference to be considered transitively used.
                return(null);
            }

            if (builtReferences.TryGetValue(itemSpecification, out var builtReference))
            {
                return(builtReference);
            }

            var dependencies = dependencyNames
                               .Select(dependency => BuildReference(projectAssets, dependency, treatAsUsed: false, targetLibraryKeys, builtReferences))
                               .WhereNotNull()
                               .ToImmutableArray();

            var reference = new ReferenceInfo(referenceType, itemSpecification, treatAsUsed, compilationAssemblies.ToImmutable(), dependencies);

            builtReferences.Add(reference.ItemSpecification, reference);

            return(reference);
        }
    }
Beispiel #2
0
 internal static UsedNamespaceOrType CreateType(ITypeReference type, string?aliasOpt = null)
 {
     RoslynDebug.Assert(type != null);
     return(new UsedNamespaceOrType(alias: aliasOpt, targetType: type));
 }
Beispiel #3
0
 internal static UsedNamespaceOrType CreateExternAlias(string alias)
 {
     RoslynDebug.Assert(alias != null);
     return(new UsedNamespaceOrType(alias: alias));
 }
 internal MetadataLocation(IModuleSymbolInternal module)
 {
     RoslynDebug.Assert(module != null);
     _module = module;
 }
Beispiel #5
0
 public ArrayTypeSymbol(Symbols.ArrayTypeSymbol underlying, CodeAnalysis.NullableAnnotation nullableAnnotation)
     : base(nullableAnnotation)
 {
     RoslynDebug.Assert(underlying is object);
     _underlying = underlying;
 }
 protected virtual bool FileExists(string fullPath)
 {
     RoslynDebug.Assert(fullPath != null);
     RoslynDebug.Assert(PathUtilities.IsAbsolute(fullPath));
     return(File.Exists(fullPath));
 }
Beispiel #7
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");
                }
            });
        }
Beispiel #9
0
 internal CodeAnalysisResourcesLocalizableErrorArgument(string targetResourceId)
 {
     RoslynDebug.Assert(targetResourceId != null);
     _targetResourceId = targetResourceId;
 }
        private void AnalyzeNode(SyntaxNodeAnalysisContext context)
        {
            var cancellationToken = context.CancellationToken;
            var node = (TMemberAccessExpressionSyntax)context.Node;

            var syntaxFacts = GetSyntaxFacts();
            var expr        = syntaxFacts.GetExpressionOfMemberAccessExpression(node);

            if (!(expr is TThisExpressionSyntax))
            {
                return;
            }

            var analyzerOptions = context.Options;

            var syntaxTree = node.SyntaxTree;
            var optionSet  = analyzerOptions.GetAnalyzerOptionSet(syntaxTree, cancellationToken);

            var model = context.SemanticModel;

            if (!CanSimplifyTypeNameExpression(
                    model, node, optionSet, out var issueSpan, cancellationToken))
            {
                return;
            }

            if (model.SyntaxTree.OverlapsHiddenPosition(issueSpan, cancellationToken))
            {
                return;
            }

            var symbolInfo = model.GetSymbolInfo(node, cancellationToken);

            if (symbolInfo.Symbol == null)
            {
                return;
            }

            var applicableOption = QualifyMembersHelpers.GetApplicableOptionFromSymbolKind(symbolInfo.Symbol.Kind);
            var optionValue      = optionSet.GetOption(applicableOption, GetLanguageName());

            if (optionValue == null)
            {
                return;
            }

            var severity = optionValue.Notification.Severity;

            RoslynDebug.AssertNotNull(DescriptorId);
            var descriptor = CreateUnnecessaryDescriptor(DescriptorId);
            var tree       = model.SyntaxTree;
            var builder    = ImmutableDictionary.CreateBuilder <string, string>();

            // used so we can provide a link in the preview to the options page. This value is
            // hard-coded there to be the one that will go to the code-style page.
            builder["OptionName"]     = nameof(CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration);
            builder["OptionLanguage"] = model.Language;

            var diagnostic = DiagnosticHelper.Create(
                descriptor, tree.GetLocation(issueSpan), severity,
                ImmutableArray.Create(node.GetLocation()), builder.ToImmutable());

            context.ReportDiagnostic(diagnostic);
        }
Beispiel #11
0
 internal ValidTargetsStringLocalizableErrorArgument(string[] targetResourceIds)
 {
     RoslynDebug.Assert(targetResourceIds != null);
     _targetResourceIds = targetResourceIds;
 }
        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));
            }
        }
 public WrappedEventSymbol(EventSymbol underlyingEvent)
 {
     RoslynDebug.Assert((object)underlyingEvent != null);
     _underlyingEvent = underlyingEvent;
 }
Beispiel #14
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 async Task <ImmutableDictionary <Document, ImmutableArray <Diagnostic> > > GetDocumentDiagnosticsToFixAsync(IEnumerable <DiagnosticData> diagnosticsToFix, Func <Project, bool> shouldFixInProject, bool filterStaleDiagnostics, CancellationToken cancellationToken)
        {
            var builder = ImmutableDictionary.CreateBuilder <DocumentId, List <DiagnosticData> >();

            foreach (var diagnosticData in diagnosticsToFix.Where(IsDocumentDiagnostic))
            {
                RoslynDebug.AssertNotNull(diagnosticData.DocumentId);

                if (!builder.TryGetValue(diagnosticData.DocumentId, out var diagnosticsPerDocument))
                {
                    diagnosticsPerDocument             = new List <DiagnosticData>();
                    builder[diagnosticData.DocumentId] = diagnosticsPerDocument;
                }

                diagnosticsPerDocument.Add(diagnosticData);
            }

            if (builder.Count == 0)
            {
                return(ImmutableDictionary <Document, ImmutableArray <Diagnostic> > .Empty);
            }

            var finalBuilder = ImmutableDictionary.CreateBuilder <Document, ImmutableArray <Diagnostic> >();
            var latestDocumentDiagnosticsMap = filterStaleDiagnostics ? new Dictionary <DocumentId, ImmutableHashSet <DiagnosticData> >() : null;

            foreach (var group in builder.GroupBy(kvp => kvp.Key.ProjectId))
            {
                var projectId = group.Key;
                var project   = _workspace.CurrentSolution.GetProject(projectId);
                if (project == null || !shouldFixInProject(project))
                {
                    continue;
                }

                if (filterStaleDiagnostics)
                {
                    RoslynDebug.AssertNotNull(latestDocumentDiagnosticsMap);

                    var uniqueDiagnosticIds      = group.SelectMany(kvp => kvp.Value.Select(d => d.Id)).ToImmutableHashSet();
                    var latestProjectDiagnostics = (await _diagnosticService.GetDiagnosticsForIdsAsync(project.Solution, project.Id, diagnosticIds: uniqueDiagnosticIds, includeSuppressedDiagnostics: true, cancellationToken: cancellationToken)
                                                    .ConfigureAwait(false)).Where(IsDocumentDiagnostic);

                    latestDocumentDiagnosticsMap.Clear();
                    foreach (var kvp in latestProjectDiagnostics.Where(d => d.DocumentId != null).GroupBy(d => d.DocumentId !))
                    {
                        latestDocumentDiagnosticsMap.Add(kvp.Key, kvp.ToImmutableHashSet());
                    }
                }

                foreach (var documentDiagnostics in group)
                {
                    var document = project.GetDocument(documentDiagnostics.Key);
                    if (document == null)
                    {
                        continue;
                    }

                    IEnumerable <DiagnosticData> documentDiagnosticsToFix;
                    if (filterStaleDiagnostics)
                    {
                        RoslynDebug.AssertNotNull(latestDocumentDiagnosticsMap);

                        if (!latestDocumentDiagnosticsMap.TryGetValue(document.Id, out var latestDocumentDiagnostics))
                        {
                            // Ignore stale diagnostics in error list.
                            latestDocumentDiagnostics = ImmutableHashSet <DiagnosticData> .Empty;
                        }

                        // Filter out stale diagnostics in error list.
                        documentDiagnosticsToFix = documentDiagnostics.Value.Where(d => latestDocumentDiagnostics.Contains(d) || SuppressionHelpers.IsSynthesizedExternalSourceDiagnostic(d));
                    }
                    else
                    {
                        documentDiagnosticsToFix = documentDiagnostics.Value;
                    }

                    if (documentDiagnosticsToFix.Any())
                    {
                        var diagnostics = await documentDiagnosticsToFix.ToDiagnosticsAsync(project, cancellationToken).ConfigureAwait(false);

                        finalBuilder.Add(document, diagnostics);
                    }
                }
            }

            return(finalBuilder.ToImmutableDictionary());
Beispiel #16
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)));
        }
            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);
                    }
                }
            }
        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);
            }
        }
        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);
                            }
                        }
                    }
Beispiel #20
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;
            }
        }
Beispiel #21
0
 internal override GreenNode SetAnnotations(SyntaxAnnotation[]?annotations)
 {
     RoslynDebug.Assert(GetType() == typeof(SyntaxToken));
     return(new SyntaxToken(Kind, FullWidth, GetDiagnostics(), annotations));
 }
Beispiel #22
0
 private FloatingValueSet(IValueSet <TFloating> numbers, bool hasNaN)
 {
     RoslynDebug.Assert(numbers is NumericValueSet <TFloating, TFloatingTC>);
     (_numbers, _hasNaN) = (numbers, hasNaN);
 }
Beispiel #23
0
 public EventSymbol(Symbols.EventSymbol underlying)
 {
     RoslynDebug.Assert(underlying is object);
     _underlying = underlying;
 }
        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);
            }
        }
Beispiel #25
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;
 }
Beispiel #26
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);
            }
Beispiel #27
0
 internal static UsedNamespaceOrType CreateNamespace(INamespace @namespace, IAssemblyReference?assemblyOpt = null, string?aliasOpt = null)
 {
     RoslynDebug.Assert(@namespace != null);
     return(new UsedNamespaceOrType(alias: aliasOpt, targetAssembly: assemblyOpt, targetNamespace: @namespace));
 }
Beispiel #28
0
        int IVBFileCodeModelEvents.EndEdit()
        {
            try
            {
                if (_editCount == 1)
                {
                    RoslynDebug.AssertNotNull(_batchElements);
                    RoslynDebug.AssertNotNull(_invisibleEditor);

                    List <ValueTuple <AbstractKeyedCodeElement, SyntaxPath> >?elementAndPaths = null;
                    if (_batchElements.Count > 0)
                    {
                        foreach (var element in _batchElements)
                        {
                            var node = element.LookupNode();
                            if (node != null)
                            {
                                elementAndPaths ??= new List <ValueTuple <AbstractKeyedCodeElement, SyntaxPath> >();
                                elementAndPaths.Add(ValueTuple.Create(element, new SyntaxPath(node)));
                            }
                        }
                    }

                    if (_batchDocument != null)
                    {
                        // perform expensive operations at once
                        var newDocument = State.ThreadingContext.JoinableTaskFactory.Run(async() =>
                        {
                            var simplifierOptions = await _batchDocument.GetSimplifierOptionsAsync(GlobalOptions, CancellationToken.None).ConfigureAwait(false);
                            return(await Simplifier.ReduceAsync(_batchDocument, Simplifier.Annotation, simplifierOptions, CancellationToken.None).ConfigureAwait(false));
                        });

                        _batchDocument.Project.Solution.Workspace.TryApplyChanges(newDocument.Project.Solution);

                        // done using batch document
                        _batchDocument = null;
                    }

                    // Ensure the file is prettylisted, even if we didn't make any edits
                    CodeModelService.EnsureBufferFormatted(_invisibleEditor.TextBuffer);

                    if (elementAndPaths != null)
                    {
                        foreach (var elementAndPath in elementAndPaths)
                        {
                            // make sure the element is there.
                            if (_codeElementTable.TryGetValue(elementAndPath.Item1.NodeKey, out var existingElement))
                            {
                                elementAndPath.Item1.ReacquireNodeKey(elementAndPath.Item2, CancellationToken.None);
                            }

                            // make sure existing element doesn't go away (weak reference) in the middle of
                            // updating the node key
                            GC.KeepAlive(existingElement);
                        }
                    }

                    _batchMode     = false;
                    _batchElements = null;
                }

                return(VSConstants.S_OK);
            }
            catch (Exception ex)
            {
                return(Marshal.GetHRForException(ex));
            }
            finally
            {
                ReleaseEditor();
            }
        }
Beispiel #29
0
 internal static UsedNamespaceOrType CreateXmlNamespace(string prefix, string xmlNamespace)
 {
     RoslynDebug.Assert(xmlNamespace != null);
     RoslynDebug.Assert(prefix != null);
     return(new UsedNamespaceOrType(alias: prefix, targetXmlNamespace: xmlNamespace));
 }
Beispiel #30
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() !);
        }