コード例 #1
0
            /// <summary>
            /// Analyzes if the containing types of the <paramref name="symbol"/> are valid and reports appropriate <see cref="Diagnostic"/>s. If the <paramref name="symbol"/> is valid, returns an array of <see cref="ITypeData"/>s of its containing types.
            /// </summary>
            /// <param name="diagnosticReceiver"><see cref="IDiagnosticReceiver"/> that is used to report <see cref="Diagnostic"/>s.</param>
            /// <param name="symbol"><see cref="ISymbol"/> to analyze.</param>
            /// <param name="compilation">Current <see cref="DefaultParamCompilationData"/>.</param>
            /// <param name="containingTypes">An array of the <paramref name="symbol"/>'s containing types' <see cref="ITypeData"/>s. Returned if the method itself returns <see langword="true"/>.</param>
            /// <returns><see langword="true"/> if the containing types of the <paramref name="symbol"/> are valid, otherwise <see langword="false"/>.</returns>
            public static bool AnalyzeContainingTypes(
                IDiagnosticReceiver diagnosticReceiver,
                ISymbol symbol,
                DefaultParamCompilationData compilation,
                [NotNullWhen(true)] out ITypeData[]?containingTypes
                )
            {
                ITypeData[] types   = symbol.GetContainingTypes(compilation).ToArray();
                bool        isValid = true;

                if (types.Length > 0)
                {
                    foreach (ITypeData parent in types)
                    {
                        if (!parent.Modifiers.Any(m => m.IsKind(SyntaxKind.PartialKeyword)))
                        {
                            diagnosticReceiver.ReportDiagnostic(DefaultParamDiagnostics.DUR0101_ContainingTypeMustBePartial, parent.Symbol);
                            isValid = false;
                        }

                        ImmutableArray <ITypeParameterSymbol> typeParameters = parent.Symbol.TypeParameters;

                        if (typeParameters.Length > 0 && typeParameters.SelectMany(t => t.GetAttributes()).Any(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, compilation.DefaultParamAttribute)))
                        {
                            diagnosticReceiver.ReportDiagnostic(DefaultParamDiagnostics.DUR0126_DefaultParamMembersCannotBeNested, symbol);
                            isValid = false;
                        }
                    }
                }

                containingTypes = isValid ? types : null;

                return(isValid);
            }
コード例 #2
0
            /// <summary>
            /// Analyzes if the containing types of the <paramref name="symbol"/> are valid and reports appropriate <see cref="Diagnostic"/>s.
            /// </summary>
            /// <param name="diagnosticReceiver"><see cref="IDiagnosticReceiver"/> that is used to report <see cref="Diagnostic"/>s.</param>
            /// <param name="symbol"><see cref="ISymbol"/> to analyze.</param>
            /// <param name="compilation">Current <see cref="DefaultParamCompilationData"/>.</param>
            /// <param name="containingTypes">An array of the <paramref name="symbol"/>'s containing types' <see cref="INamedTypeSymbol"/>s. Returned if the method itself returns <see langword="true"/>.</param>
            /// <param name="cancellationToken"><see cref="CancellationToken"/> that specifies if the operation should be canceled.</param>
            /// <returns><see langword="true"/> if the containing types of the <paramref name="symbol"/> are valid, otherwise <see langword="false"/>.</returns>
            public static bool AnalyzeContainingTypes(
                IDiagnosticReceiver diagnosticReceiver,
                ISymbol symbol,
                DefaultParamCompilationData compilation,
                INamedTypeSymbol[]?containingTypes  = null,
                CancellationToken cancellationToken = default
                )
            {
                InitializeContainingTypes(ref containingTypes, symbol);

                bool isValid = true;

                if (containingTypes.Length > 0)
                {
                    foreach (INamedTypeSymbol parent in containingTypes)
                    {
                        if (!HasPartialKeyword(parent, cancellationToken))
                        {
                            diagnosticReceiver.ReportDiagnostic(DefaultParamDiagnostics.DUR0101_ContainingTypeMustBePartial, parent);
                            isValid = false;
                        }

                        ImmutableArray <ITypeParameterSymbol> typeParameters = parent.TypeParameters;

                        if (typeParameters.Length > 0 && typeParameters.SelectMany(t => t.GetAttributes()).Any(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, compilation.DefaultParamAttribute)))
                        {
                            diagnosticReceiver.ReportDiagnostic(DefaultParamDiagnostics.DUR0126_DefaultParamMembersCannotBeNested, symbol);
                            isValid = false;
                        }
                    }
                }

                return(isValid);
            }
コード例 #3
0
            /// <summary>
            /// Analyzes if the <paramref name="symbol"/> or either <see langword="partial"/> or <see langword="extern"/>.
            /// </summary>
            /// <param name="diagnosticReceiver"><see cref="IDiagnosticReceiver"/> that is used to report <see cref="Diagnostic"/>s.</param>
            /// <param name="symbol"><see cref="IMethodSymbol"/> to analyze.</param>
            /// <param name="declaration">Main <see cref="MethodDeclarationSyntax"/> of the <paramref name="symbol"/>.</param>
            /// <returns><see langword="true"/> if the <paramref name="symbol"/> is valid (is not <see langword="partial"/> or <see langword="extern"/>), otherwise <see langword="false"/>.</returns>
            public static bool AnalyzeAgainstPartialOrExtern(
                IDiagnosticReceiver diagnosticReceiver,
                IMethodSymbol symbol,
                MethodDeclarationSyntax declaration
                )
            {
                if (symbol.IsExtern || symbol.IsPartial(declaration))
                {
                    diagnosticReceiver.ReportDiagnostic(DefaultParamDiagnostics.DUR0102_MethodCannotBePartialOrExtern, symbol);
                    return(false);
                }

                return(true);
            }
コード例 #4
0
 public static bool AnalyzeConfiguration(
     IDiagnosticReceiver diagnosticReceiver,
     IAssemblySymbol assembly,
     EnumServicesConfiguration configuration,
     AttributeSyntax syntax)
 {
     if (!IsValidServicesValue(configuration.EnumServices))
     {
         diagnosticReceiver.ReportDiagnostic(
             DUR0201_InvalidEnumValue,
             syntax.GetArgumentLocation(nameof(EnumServicesAttribute.Services)),
             assembly);
     }
 }
コード例 #5
0
            /// <summary>
            /// Analyzes if the specified <paramref name="symbol"/> is partial.
            /// </summary>
            /// <param name="diagnosticReceiver"><see cref="IDiagnosticReceiver"/> that is used to report <see cref="Diagnostic"/>s.</param>
            /// <param name="symbol"><see cref="INamedTypeSymbol"/> to analyze.</param>
            /// <param name="cancellationToken"><see cref="CancellationToken"/> that specifies if the operation should be canceled.</param>
            /// <returns><see langword="true"/> if the <paramref name="symbol"/> is not partial, <see langword="false"/> otherwise.</returns>
            public static bool AnalyzeAgainstPartial(
                IDiagnosticReceiver diagnosticReceiver,
                INamedTypeSymbol symbol,
                CancellationToken cancellationToken = default
                )
            {
                TypeDeclarationSyntax[] syntaxes = symbol.DeclaringSyntaxReferences
                                                   .Select(r => r.GetSyntax(cancellationToken))
                                                   .OfType <TypeDeclarationSyntax>()
                                                   .ToArray();

                if (syntaxes.Length > 1 || syntaxes[0].Modifiers.Any(m => m.IsKind(SyntaxKind.PartialKeyword)))
                {
                    diagnosticReceiver.ReportDiagnostic(DefaultParamDiagnostics.DUR0122_DoNotUseDefaultParamOnPartialType, symbol);
                    return(false);
                }

                return(true);
            }
コード例 #6
0
            /// <summary>
            /// Analyzes if the provided collection of <see cref="AttributeData"/>s contains <see cref="DurianGeneratedAttribute"/> or <see cref="GeneratedCodeAttribute"/> and reports appropriate <see cref="Diagnostic"/>s.
            /// </summary>
            /// <param name="diagnosticReceiver"><see cref="IDiagnosticReceiver"/> that is used to report <see cref="Diagnostic"/>s.</param>
            /// <param name="symbol"><see cref="ISymbol"/> that owns the <paramref name="attributes"/>.</param>
            /// <param name="compilation">Current <see cref="DefaultParamCompilationData"/>.</param>
            /// <param name="attributes">A collection of <see cref="AttributeData"/> to analyze.</param>
            /// <returns><see langword="true"/> if all the <paramref name="attributes"/> are valid (neither of them is prohibited), otherwise <see langword="false"/>.</returns>
            public static bool AnalyzeAgainstProhibitedAttributes(
                IDiagnosticReceiver diagnosticReceiver,
                ISymbol symbol,
                DefaultParamCompilationData compilation,
                IEnumerable <AttributeData>?attributes = null
                )
            {
                InitializeAttributes(ref attributes, symbol);

                foreach (AttributeData attr in attributes)
                {
                    if (SymbolEqualityComparer.Default.Equals(attr.AttributeClass, compilation.GeneratedCodeAttribute) ||
                        SymbolEqualityComparer.Default.Equals(attr.AttributeClass, compilation.DurianGeneratedAttribute))
                    {
                        diagnosticReceiver.ReportDiagnostic(DefaultParamDiagnostics.DUR0104_DefaultParamCannotBeAppliedWhenGenerationAttributesArePresent, symbol);

                        return(false);
                    }
                }

                return(true);
            }