/// <summary>
            /// Fully analyzes the specified <paramref name="symbol"/>.
            /// </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="compilation">Current <see cref="DefaultParamCompilationData"/>.</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 valid, otherwise <see langword="false"/>.
            /// </returns>
            public static bool Analyze(
                IDiagnosticReceiver diagnosticReceiver,
                INamedTypeSymbol symbol,
                DefaultParamCompilationData compilation,
                CancellationToken cancellationToken = default
                )
            {
                TypeParameterContainer typeParameters = TypeParameterContainer.CreateFrom(symbol, compilation, cancellationToken);

                if (!typeParameters.HasDefaultParams)
                {
                    return(false);
                }

                bool isValid = AnalyzeAgainstProhibitedAttributes(diagnosticReceiver, symbol, compilation, out AttributeData[]? attributes);

                isValid &= AnalyzeContainingTypes(diagnosticReceiver, symbol, compilation, out INamedTypeSymbol[]? containingTypes, cancellationToken);
                isValid &= AnalyzeTypeParameters(diagnosticReceiver, symbol, in typeParameters);

                if (isValid)
                {
                    string targetNamespace = GetTargetNamespace(symbol, compilation, attributes !, containingTypes !);

                    return(AnalyzeCollidingMembers(diagnosticReceiver, symbol, in typeParameters, compilation, targetNamespace, out _, attributes !, containingTypes !, cancellationToken));
                }

                return(false);
            }
            /// <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);
            }
Ejemplo n.º 3
0
        /// <summary>
        /// Reports <see cref="Diagnostic"/> s for a single <see cref="LocalFunctionStatementSyntax"/>.
        /// </summary>
        /// <param name="diagnosticReceiver">
        /// <see cref="IDiagnosticReceiver"/> that is used to report <see cref="Diagnostic"/> s.
        /// </param>
        /// <param name="compilation">Current <see cref="DefaultParamCompilationData"/>.</param>
        /// <param name="localFunction">
        /// <see cref="LocalFunctionStatementSyntax"/> to report <see cref="Diagnostic"/> for.
        /// </param>
        /// <param name="cancellationToken">
        /// <see cref="CancellationToken"/> that specifies if the operation should be canceled.
        /// </param>
        public static void ReportDiagnosticsForLocalFunction(
            IDiagnosticReceiver diagnosticReceiver,
            DefaultParamCompilationData compilation,
            LocalFunctionStatementSyntax localFunction,
            CancellationToken cancellationToken = default
            )
        {
            if (localFunction is null)
            {
                return;
            }

            SemanticModel semanticModel = compilation.Compilation.GetSemanticModel(localFunction.SyntaxTree);

            if (HasDefaultParamAttribute(localFunction, semanticModel, compilation.DefaultParamAttribute !))
            {
                ISymbol?symbol = semanticModel.GetDeclaredSymbol(localFunction, cancellationToken);

                if (symbol is not IMethodSymbol s)
                {
                    return;
                }

                DefaultParamMethodAnalyzer.WithDiagnostics.ReportDiagnosticForInvalidMethodType(diagnosticReceiver, s);
            }
        }
            /// <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);
            }
Ejemplo n.º 5
0
            /// <inheritdoc cref="DefaultParamDelegateAnalyzer.WithDiagnostics.Analyze(IDiagnosticReceiver, INamedTypeSymbol, DefaultParamCompilationData, CancellationToken)"/>
            public static bool Analyze(
                IDiagnosticReceiver diagnosticReceiver,
                INamedTypeSymbol symbol,
                DefaultParamCompilationData compilation,
                CancellationToken cancellationToken = default
                )
            {
                TypeParameterContainer typeParameters = TypeParameterContainer.CreateFrom(symbol, compilation, cancellationToken);

                if (!typeParameters.HasDefaultParams)
                {
                    return(false);
                }

                ImmutableArray <AttributeData> attributes = symbol.GetAttributes();

                INamedTypeSymbol[] containingTypes = symbol.GetContainingTypeSymbols().ToArray();

                bool isValid = AnalyzeAgainstProhibitedAttributes(diagnosticReceiver, symbol, compilation, attributes);

                isValid &= AnalyzeContainingTypes(diagnosticReceiver, symbol, compilation, containingTypes, cancellationToken);
                isValid &= AnalyzeAgainstPartial(diagnosticReceiver, symbol, cancellationToken);
                isValid &= AnalyzeTypeParameters(diagnosticReceiver, symbol, in typeParameters);

                if (isValid)
                {
                    string targetNamespace = GetTargetNamespace(symbol, compilation, attributes, containingTypes);

                    isValid &= AnalyzeCollidingMembers(diagnosticReceiver, symbol, in typeParameters, compilation, targetNamespace, out _, attributes, containingTypes, cancellationToken);
                }

                ShouldInheritInsteadOfCopying(diagnosticReceiver, symbol, compilation, attributes, containingTypes);

                return(isValid);
            }
Ejemplo n.º 6
0
            /// <summary>
            /// Analyzes if the <paramref name="symbol"/> is of an invalid type.
            /// </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>
            /// <returns><see langword="true"/> if the <paramref name="symbol"/> is valid, otherwise <see langword="false"/>.</returns>
            public static bool AnalyzeAgainstInvalidMethodType(IDiagnosticReceiver diagnosticReceiver, IMethodSymbol symbol)
            {
                if (symbol.MethodKind != MethodKind.Ordinary || (symbol.ContainingType is INamedTypeSymbol t && t.TypeKind == TypeKind.Interface))
                {
                    ReportDiagnosticForInvalidMethodType(diagnosticReceiver, symbol);
                    return(false);
                }

                return(true);
            }
Ejemplo n.º 7
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="cancellationToken"><see cref="CancellationToken"/> that specifies if the operation should be canceled.</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,
                CancellationToken cancellationToken = default
                )
            {
                if (symbol?.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax(cancellationToken) is not MethodDeclarationSyntax declaration)
                {
                    return(false);
                }

                return(AnalyzeAgainstPartialOrExtern(diagnosticReceiver, symbol, declaration));
            }
            /// <summary>
            /// Analyzes if the <paramref name="symbol"/> has <see cref="DurianGeneratedAttribute"/> or <see cref="GeneratedCodeAttribute"/> and reports <see cref="Diagnostic"/>s if the <paramref name="symbol"/> is not valid. If the <paramref name="symbol"/> is valid, returns an array of <paramref name="attributes"/> of that <paramref name="symbol"/>.
            /// </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="attributes">An array of <see cref="AttributeData"/>s of the <paramref name="symbol"/>. Returned if the method itself returns <see langword="true"/>.</param>
            /// <returns><see langword="true"/> if the <paramref name="symbol"/> is valid (does not have the prohibited attributes), otherwise <see langword="false"/>.</returns>
            public static bool AnalyzeAgainstProhibitedAttributes(
                IDiagnosticReceiver diagnosticReceiver,
                ISymbol symbol,
                DefaultParamCompilationData compilation,
                out AttributeData[]?attributes
                )
            {
                AttributeData[] attrs   = symbol.GetAttributes().ToArray();
                bool            isValid = AnalyzeAgainstProhibitedAttributes(diagnosticReceiver, symbol, compilation, attrs);

                attributes = isValid ? attrs : null;
                return(isValid);
            }
Ejemplo n.º 9
0
 /// <inheritdoc cref="DefaultParamAnalyzer.WithDiagnostics.AnalyzeAgainstProhibitedAttributes(IDiagnosticReceiver, ISymbol, DefaultParamCompilationData, IEnumerable{AttributeData}?)"/>
 public static bool AnalyzeAgainstProhibitedAttributes(
     IDiagnosticReceiver diagnosticReceiver,
     ISymbol symbol,
     DefaultParamCompilationData compilation,
     IEnumerable <AttributeData>?attributes = null
     )
 {
     return(DefaultParamAnalyzer.WithDiagnostics.AnalyzeAgainstProhibitedAttributes(
                diagnosticReceiver,
                symbol,
                compilation,
                attributes
                ));
 }
            /// <summary>
            /// Enumerates through all the <see cref="DelegateDeclarationSyntax"/>es collected by the <paramref name="syntaxReceiver"/> and returns an array of <see cref="DefaultParamDelegateData"/>s created from the valid ones.
            /// </summary>
            /// <param name="diagnosticReceiver"><see cref="IDiagnosticReceiver"/> that is used to report <see cref="Diagnostic"/>s.</param>
            /// <param name="compilation">Current <see cref="DefaultParamCompilationData"/>.</param>
            /// <param name="syntaxReceiver"><see cref="DefaultParamSyntaxReceiver"/> that collected the <see cref="DelegateDeclarationSyntax"/>es.</param>
            /// <param name="cancellationToken"><see cref="CancellationToken"/> that specifies if the operation should be canceled.</param>
            public static DefaultParamDelegateData[] GetValidDelegates(
                IDiagnosticReceiver diagnosticReceiver,
                DefaultParamCompilationData compilation,
                DefaultParamSyntaxReceiver syntaxReceiver,
                CancellationToken cancellationToken = default
                )
            {
                if (compilation is null || diagnosticReceiver is null || syntaxReceiver is null || syntaxReceiver.CandidateDelegates.Count == 0)
                {
                    return(Array.Empty <DefaultParamDelegateData>());
                }

                return(GetValidDelegates_Internal(diagnosticReceiver, compilation, syntaxReceiver.CandidateDelegates.ToArray(), cancellationToken));
            }
Ejemplo n.º 11
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);
            }
Ejemplo n.º 12
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);
     }
 }
            /// <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,
                [NotNullWhen(true)] out INamedTypeSymbol[]?containingTypes,
                CancellationToken cancellationToken = default
                )
            {
                INamedTypeSymbol[] types = symbol.GetContainingTypeSymbols().ToArray();
                bool isValid             = AnalyzeContainingTypes(diagnosticReceiver, symbol, compilation, types, cancellationToken);

                containingTypes = isValid ? types : null;
                return(isValid);
            }
Ejemplo n.º 14
0
 /// <inheritdoc cref="DefaultParamAnalyzer.WithDiagnostics.AnalyzeAgainstProhibitedAttributes(IDiagnosticReceiver, ISymbol, DefaultParamCompilationData, out AttributeData[])"/>
 public static bool AnalyzeAgainstProhibitedAttributes(
     IDiagnosticReceiver diagnosticReceiver,
     INamedTypeSymbol symbol,
     DefaultParamCompilationData compilation,
     [NotNullWhen(true)] out AttributeData[]?attributes
     )
 {
     return(DefaultParamAnalyzer.WithDiagnostics.AnalyzeAgainstProhibitedAttributes(
                diagnosticReceiver,
                symbol,
                compilation,
                out attributes
                ));
 }
Ejemplo n.º 15
0
            /// <summary>
            /// Fully analyzes the specified <paramref name="symbol"/>.
            /// </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="compilation">Current <see cref="DefaultParamCompilationData"/>.</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 valid, otherwise <see langword="false"/>.</returns>
            public static bool Analyze(
                IDiagnosticReceiver diagnosticReceiver,
                IMethodSymbol symbol,
                DefaultParamCompilationData compilation,
                CancellationToken cancellationToken = default
                )
            {
                TypeParameterContainer typeParameters = TypeParameterContainer.CreateFrom(symbol, compilation, cancellationToken);

                if (!typeParameters.HasDefaultParams && !symbol.IsOverride)
                {
                    return(false);
                }

                return(AnalyzeCore(diagnosticReceiver, symbol, compilation, ref typeParameters, cancellationToken));
            }
            /// <inheritdoc/>
            protected override bool Analyze(
                DefaultParamCompilationData compilation,
                SyntaxNodeAnalysisContext context,
                [NotNullWhen(true)] out DefaultParamDelegateData?data
                )
            {
                if (context.Node is not TypeParameterListSyntax || context.Node.Parent is not DelegateDeclarationSyntax declaration)
                {
                    data = null;
                    return(false);
                }

                IDiagnosticReceiver diagnosticReceiver = DiagnosticReceiverFactory.SyntaxNode(context);

                return(WithDiagnostics.ValidateAndCreate(diagnosticReceiver, compilation, declaration, out data, context.CancellationToken));
            }
Ejemplo n.º 17
0
        /// <summary>
        /// Reports <see cref="Diagnostic"/> s for <see cref="LocalFunctionStatementSyntax"/> es
        /// returned by the <see cref="GetCandidateLocalFunctions()"/> method.
        /// </summary>
        /// <param name="diagnosticReceiver">
        /// <see cref="IDiagnosticReceiver"/> that is used to report <see cref="Diagnostic"/> s.
        /// </param>
        /// <param name="compilation">Current <see cref="DefaultParamCompilationData"/>.</param>
        /// <param name="syntaxReceiver">
        /// <see cref="DefaultParamSyntaxReceiver"/> that collected the <see
        /// cref="LocalFunctionStatementSyntax"/> to report <see cref="Diagnostic"/> for.
        /// </param>
        /// <param name="cancellationToken">
        /// <see cref="CancellationToken"/> that specifies if the operation should be canceled.
        /// </param>
        public static void ReportDiagnosticsForLocalFunctions(
            IDiagnosticReceiver diagnosticReceiver,
            DefaultParamCompilationData compilation,
            DefaultParamSyntaxReceiver syntaxReceiver,
            CancellationToken cancellationToken = default
            )
        {
            if (diagnosticReceiver is null || compilation is null || syntaxReceiver is null || syntaxReceiver.CandidateLocalFunctions is null || syntaxReceiver.CandidateLocalFunctions.Count == 0)
            {
                return;
            }

            foreach (LocalFunctionStatementSyntax fn in syntaxReceiver.CandidateLocalFunctions)
            {
                ReportDiagnosticsForLocalFunction(diagnosticReceiver, compilation, fn, cancellationToken);
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Reports <see cref="Diagnostic"/> s for <see cref="LocalFunctionStatementSyntax"/> es
        /// returned by the <see cref="GetCandidateLocalFunctions()"/> method.
        /// </summary>
        /// <param name="diagnosticReceiver">
        /// <see cref="IDiagnosticReceiver"/> that is used to report <see cref="Diagnostic"/> s.
        /// </param>
        /// <param name="compilation">Current <see cref="DefaultParamCompilationData"/>.</param>
        /// <param name="collectedLocalFunctions">
        /// A collection of <see cref="LocalFunctionStatementSyntax"/> to report the <see
        /// cref="Diagnostic"/> s for.
        /// </param>
        /// <param name="cancellationToken">
        /// <see cref="CancellationToken"/> that specifies if the operation should be canceled.
        /// </param>
        public static void ReportDiagnosticsForLocalFunctions(
            IDiagnosticReceiver diagnosticReceiver,
            DefaultParamCompilationData compilation,
            IEnumerable <LocalFunctionStatementSyntax> collectedLocalFunctions,
            CancellationToken cancellationToken = default
            )
        {
            if (collectedLocalFunctions is null || compilation is null || diagnosticReceiver is null)
            {
                return;
            }

            foreach (LocalFunctionStatementSyntax fn in collectedLocalFunctions)
            {
                ReportDiagnosticsForLocalFunction(diagnosticReceiver, compilation, fn, cancellationToken);
            }
        }
            /// <inheritdoc/>
            protected override bool Analyze(
                DefaultParamCompilationData compilation,
                SyntaxNodeAnalysisContext context,
                [NotNullWhen(true)] out IDefaultParamTarget?data
                )
            {
                data = null;

                if (context.Node is not TypeParameterListSyntax || context.Node.Parent is not LocalFunctionStatementSyntax declaration)
                {
                    return(false);
                }

                IDiagnosticReceiver diagnosticReceiver = DiagnosticReceiverFactory.SyntaxNode(context);

                ReportDiagnosticsForLocalFunction(diagnosticReceiver, compilation, declaration, context.CancellationToken);
                return(false);
            }
Ejemplo n.º 20
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);
            }
            /// <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);
            }
Ejemplo n.º 22
0
 public static void ReceiveDiagnostic(this IDiagnosticReceiver receiver, DiagnosticCode code, FileLocation?location, bool isError) =>
 receiver.ReceiveDiagnostic(new DiagnosticInfo(code, location), isError);
 /// <inheritdoc/>
 protected override FriendClassCompilationData CreateCompilation(CSharpCompilation compilation, IDiagnosticReceiver diagnosticReceiver)
 {
     return(new FriendClassCompilationData(compilation));
 }
 /// <summary>
 /// Checks, if the specified <paramref name="typeParameters"/> are valid and reports <see cref="Diagnostic"/> if they are not.
 /// </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 the type parameters of.</param>
 /// <param name="typeParameters"><see cref="TypeParameterContainer"/> to analyze.</param>
 /// <returns><see langword="true"/> if the type parameters contained within the <see cref="TypeParameterContainer"/> are valid, otherwise <see langword="false"/>.</returns>
 public static bool AnalyzeTypeParameters(
     IDiagnosticReceiver diagnosticReceiver,
     ISymbol symbol,
     in TypeParameterContainer typeParameters
Ejemplo n.º 25
0
        public CallExpression BindOverload(IExpression callee, IReadOnlyList <IExpression> parameters, IDiagnosticReceiver diagnosticReceiver, FileLocation location)
        {
            if (Parameters.Count != parameters.Count)
            {
                diagnosticReceiver.ReceiveDiagnostic(DiagnosticCode.InvalidParamCount, location, true);
                return(new CallExpression(null !, null !, PrimitiveType.Unknown));
            }

            for (int i = 0; i < parameters.Count; i++)
            {
                if (Parameters[i].ReturnType == parameters[i].ReturnType)
                {
                    continue;
                }

                diagnosticReceiver.ReceiveDiagnostic(DiagnosticCode.InvalidParamType, location, true);
            }

            return(new CallExpression(callee, parameters, ReturnType));
        }
Ejemplo n.º 26
0
 /// <summary>
 /// Analyzes if the <paramref name="symbol"/> has valid <paramref name="typeParameters"/> when compared to the <paramref name="symbol"/>'s base method.
 /// </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="typeParameters"><see cref="TypeParameterContainer"/> that contains type parameters to be analyzed.</param>
 /// <param name="combinedTypeParameters">Combined <see cref="TypeParameterContainer"/>s of the <paramref name="symbol"/>'s base methods.</param>
 /// <returns><see langword="true"/> if the <paramref name="symbol"/> is valid, otherwise <see langword="false"/>.</returns>
 public static bool AnalyzeBaseMethodAndTypeParameters(
     IDiagnosticReceiver diagnosticReceiver,
     IMethodSymbol symbol,
     ref TypeParameterContainer typeParameters,
     in TypeParameterContainer combinedTypeParameters
 /// <summary>
 /// Enumerates through all the <see cref="DelegateDeclarationSyntax"/>es collected by the <paramref name="syntaxReceiver"/> and returns an array of <see cref="DefaultParamDelegateData"/>s created from the valid ones. If the target <see cref="DefaultParamDelegateData"/> already exists in the specified <paramref name="cache"/>, includes it instead.
 /// </summary>
 /// <param name="diagnosticReceiver"><see cref="IDiagnosticReceiver"/> that is used to report <see cref="Diagnostic"/>s.</param>
 /// <param name="compilation">Current <see cref="DefaultParamCompilationData"/>.</param>
 /// <param name="syntaxReceiver"><see cref="DefaultParamSyntaxReceiver"/> that collected the <see cref="DelegateDeclarationSyntax"/>es.</param>
 /// <param name="cache">Container of cached <see cref="DefaultParamDelegateData"/>s.</param>
 /// <param name="cancellationToken"><see cref="CancellationToken"/> that specifies if the operation should be canceled.</param>
 public static DefaultParamDelegateData[] GetValidDelegates(
     IDiagnosticReceiver diagnosticReceiver,
     DefaultParamCompilationData compilation,
     DefaultParamSyntaxReceiver syntaxReceiver,
     in CachedData <DefaultParamDelegateData> cache,
Ejemplo n.º 28
0
 /// <inheritdoc/>
 protected override DefaultParamCompilationData CreateCompilation(CSharpCompilation compilation, IDiagnosticReceiver diagnosticReceiver)
 {
     return(new DefaultParamCompilationData(compilation));
 }
Ejemplo n.º 29
0
		/// <inheritdoc/>
		protected override EnumServicesCompilationData CreateCompilation(CSharpCompilation compilation, IDiagnosticReceiver diagnosticReceiver)
		{
			return new EnumServicesCompilationData(compilation);
		}
Ejemplo n.º 30
0
 /// <inheritdoc cref="DefaultParamDelegateAnalyzer.WithDiagnostics.AnalyzeCollidingMembers(IDiagnosticReceiver, INamedTypeSymbol, in TypeParameterContainer, DefaultParamCompilationData, string, out HashSet{int}?, IEnumerable{AttributeData}?, INamedTypeSymbol[], CancellationToken)"/>
 public static bool AnalyzeCollidingMembers(
     IDiagnosticReceiver diagnosticReceiver,
     INamedTypeSymbol symbol,
     in TypeParameterContainer typeParameters,