private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
        {
            SyntaxNode root = context.Node;

            if (!(root is AttributeSyntax))
            {
                return;
            }

            AttributeSyntax attributeSyntax = (AttributeSyntax)context.Node;

            ISymbol attributeUsage = context.SemanticModel.GetSymbolInfo(context.Node).Symbol;

            if (attributeUsage?.ContainingType?.ToString() == "Foundation.Api.ApiControllers.ParameterAttribute")
            {
                LiteralExpressionSyntax expression = (LiteralExpressionSyntax)(attributeSyntax.DescendantNodes().OfType <AttributeArgumentSyntax>().First()).Expression;

                string parameterNameValue = expression.Token.ValueText;

                if (!char.IsLower(parameterNameValue[0]))
                {
                    Diagnostic diagn = Diagnostic.Create(Rule, root.GetLocation(), Message);

                    context.ReportDiagnostic(diagn);
                }
            }
        }
예제 #2
0
        private async Task <Document> AddDefaultValuesAsync(Document document, AttributeSyntax attribute, MethodDeclarationSyntax method, InlineDataMustMatchTheoryParameters.ParameterArrayStyleType arrayStyle, CancellationToken cancellationToken)
        {
            var editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);

            InitializerExpressionSyntax arrayInitializer = null;

            if (arrayStyle == InlineDataMustMatchTheoryParameters.ParameterArrayStyleType.Initializer)
            {
                arrayInitializer = (InitializerExpressionSyntax)attribute.DescendantNodes().First(n => n.IsKind(SyntaxKind.ArrayInitializerExpression));
            }

            var originalInitializer = arrayInitializer;
            int i = originalInitializer?.Expressions.Count ?? attribute.ArgumentList?.Arguments.Count ?? 0;

            for (; i < method.ParameterList.Parameters.Count; i++)
            {
                var defaultExpression = (ExpressionSyntax)CreateDefaultValueSyntax(editor, method.ParameterList.Parameters[i].Type);
                if (arrayInitializer != null)
                {
                    arrayInitializer = arrayInitializer.AddExpressions(defaultExpression);
                }
                else
                {
                    editor.AddAttributeArgument(attribute, defaultExpression);
                }
            }
            if (arrayInitializer != null)
            {
                editor.ReplaceNode(originalInitializer, arrayInitializer);
            }

            return(editor.GetChangedDocument());
        }
예제 #3
0
        public static string GetNamedArgumentValue([NotNull] this AttributeSyntax node, string argumentName)
        {
            AttributeArgumentSyntax namedArgument =
                node.DescendantNodes()
                .OfType <AttributeArgumentSyntax>()
                .FirstOrDefault(aas => aas.DescendantNodes()
                                .OfType <IdentifierNameSyntax>()
                                .Any(ins => ins.Identifier.Text == argumentName));

            SyntaxToken?valueToken = namedArgument.DescendantNodes().OfType <LiteralExpressionSyntax>().FirstOrDefault()?.Token;

            return(valueToken?.Text.Trim('"'));
        }
예제 #4
0
            private static string GetAttributeTypeArgument(AttributeSyntax attribute)
            {
                var @typeof = attribute.DescendantNodes().FirstOrDefault(node => node is TypeOfExpressionSyntax) as TypeOfExpressionSyntax;

                return(@typeof.Type.GetText().ToString().Split('.').Last());
            }
예제 #5
0
#pragma warning disable CS3002 // Return type is not CLS-compliant
#pragma warning disable CS3001 // Argument type is not CLS-compliant
        public static IEnumerable <AttributeArgumentSyntax> GetAttributeArguments(this AttributeSyntax node)
#pragma warning restore CS3001 // Argument type is not CLS-compliant
#pragma warning restore CS3002 // Return type is not CLS-compliant
        {
            return(node.DescendantNodes().OfType <AttributeArgumentSyntax>());
        }
예제 #6
0
 public static IEnumerable <AttributeArgumentSyntax> GetAttributeArguments([NotNull] this AttributeSyntax node)
 {
     return(node.DescendantNodes().OfType <AttributeArgumentSyntax>());
 }
예제 #7
0
        /// <summary>
        /// Generates source code to optimize serialization and deserialization with JsonSerializer.
        /// </summary>
        /// <param name="executionContext"></param>
        public void Execute(GeneratorExecutionContext executionContext)
        {
            Compilation compilation = executionContext.Compilation;

            const string     JsonSerializableAttributeName = "System.Text.Json.Serialization.JsonSerializableAttribute";
            INamedTypeSymbol jsonSerializableAttribute     = compilation.GetTypeByMetadataName(JsonSerializableAttributeName);

            if (jsonSerializableAttribute == null)
            {
                return;
            }

            JsonSerializableSyntaxReceiver receiver            = (JsonSerializableSyntaxReceiver)executionContext.SyntaxReceiver;
            MetadataLoadContextInternal    metadataLoadContext = new(compilation);

            TypeExtensions.NullableOfTType = metadataLoadContext.Resolve(typeof(Nullable <>));

            JsonSourceGeneratorHelper helper = new(executionContext, metadataLoadContext);

            _helper = helper;

            // Discover serializable types indicated by JsonSerializableAttribute.
            foreach (CompilationUnitSyntax compilationUnit in receiver.CompilationUnits)
            {
                SemanticModel compilationSemanticModel = executionContext.Compilation.GetSemanticModel(compilationUnit.SyntaxTree);

                foreach (AttributeListSyntax attributeListSyntax in compilationUnit.AttributeLists)
                {
                    AttributeSyntax attributeSyntax = attributeListSyntax.Attributes.First();
                    IMethodSymbol   attributeSymbol = compilationSemanticModel.GetSymbolInfo(attributeSyntax).Symbol as IMethodSymbol;

                    if (attributeSymbol == null || !jsonSerializableAttribute.Equals(attributeSymbol.ContainingType, SymbolEqualityComparer.Default))
                    {
                        // Not the right attribute.
                        continue;
                    }

                    // Get JsonSerializableAttribute arguments.
                    IEnumerable <SyntaxNode> attributeArguments = attributeSyntax.DescendantNodes().Where(node => node is AttributeArgumentSyntax);

                    ITypeSymbol?typeSymbol           = null;
                    string?     typeInfoPropertyName = null;

                    int i = 0;
                    foreach (AttributeArgumentSyntax node in attributeArguments)
                    {
                        if (i == 0)
                        {
                            TypeOfExpressionSyntax?typeNode = node.ChildNodes().Single() as TypeOfExpressionSyntax;
                            if (typeNode != null)
                            {
                                ExpressionSyntax typeNameSyntax = (ExpressionSyntax)typeNode.ChildNodes().Single();
                                typeSymbol = compilationSemanticModel.GetTypeInfo(typeNameSyntax).ConvertedType;
                            }
                        }
                        else if (i == 1)
                        {
                            // Obtain the optional TypeInfoPropertyName string property on the attribute, if present.
                            SyntaxNode?typeInfoPropertyNameNode = node.ChildNodes().ElementAtOrDefault(1);
                            if (typeInfoPropertyNameNode != null)
                            {
                                typeInfoPropertyName = typeInfoPropertyNameNode.GetFirstToken().ValueText;
                            }
                        }

                        i++;
                    }

                    if (typeSymbol == null)
                    {
                        continue;
                    }


                    Type type = new TypeWrapper(typeSymbol, metadataLoadContext);
                    if (type.Namespace == "<global namespace>")
                    {
                        // typeof() reference where the type's name isn't fully qualified.
                        // The compilation is not valid and the user needs to fix their code.
                        // The compiler will notify the user so we don't have to.
                        return;
                    }

                    helper.RegisterRootSerializableType(type, typeInfoPropertyName);
                }
            }

            helper.GenerateSerializationMetadata();
        }