Exemple #1
0
        protected override IEnumerable <CodeAction> GetActions(Document document, SemanticModel semanticModel, SyntaxNode root, TextSpan span, SyntaxNode node, CancellationToken cancellationToken)
        {
            MethodDeclarationSyntax methodDeclaration = node as MethodDeclarationSyntax;

            if (methodDeclaration == null)
            {
                yield break;
            }

            TypeDeclarationSyntax enclosingTypeDeclaration = methodDeclaration.Ancestors().OfType <TypeDeclarationSyntax>().FirstOrDefault();

            if (enclosingTypeDeclaration == null)
            {
                yield break;
            }
            if (methodDeclaration.Modifiers.Any(SyntaxKind.StaticKeyword))
            {
                yield break;
            }

            var declaringTypeSymbol = semanticModel.GetDeclaredSymbol(enclosingTypeDeclaration);
            var methodSymbol        = semanticModel.GetDeclaredSymbol(methodDeclaration);

            yield return(CodeActionFactory.Create(span, DiagnosticSeverity.Info, GettextCatalog.GetString("Convert to static method"), t2 =>
            {
                return PerformAction(document, semanticModel, root, enclosingTypeDeclaration, declaringTypeSymbol, methodDeclaration, methodSymbol, cancellationToken);
            }));
        }
Exemple #2
0
    public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node)
    {
        var newNode   = (MethodDeclarationSyntax)base.VisitMethodDeclaration(node);
        var modifiers = newNode.Modifiers;

        if (modifiers.All(mod => mod.Kind() != SyntaxKind.StaticKeyword))
        {
            modifiers = modifiers.Add(Token(SyntaxKind.StaticKeyword).WithTrailingTrivia(Whitespace(" ")));
        }
        var  parentClass       = node.Ancestors().OfType <ClassDeclarationSyntax>().First();
        var  className         = parentClass.Identifier.ValueText;
        bool?hasTypeParameters = parentClass.TypeParameterList?.Parameters.Any();

        if (hasTypeParameters != null && (bool)hasTypeParameters)
        {
            className += parentClass.TypeParameterList.ToString();
        }

        // I pass the 'this' parameter in anyway.
        var parameterSyntax =
            Parameter(SyntaxFactory.Identifier(" " + ThisFieldName)).
            WithType(ParseTypeName(className));

        if (newNode.ParameterList?.Parameters.Count > 0)
        {
            parameterSyntax = parameterSyntax.WithLeadingTrivia(SyntaxTrivia(SyntaxKind.WhitespaceTrivia, " "));
        }

        var separatedSyntaxList = new SeparatedSyntaxList <ParameterSyntax>();

        separatedSyntaxList = separatedSyntaxList.Add(parameterSyntax);
        var parameterList    = ParameterList(separatedSyntaxList);
        var newParameterList = newNode.ParameterList == null
                                    ? parameterList
                                    : newNode.ParameterList.AddParameters(parameterSyntax);

        return(newNode.ReplaceNode(newNode,
                                   newNode.Update(newNode.AttributeLists, modifiers, newNode.ReturnType, newNode.ExplicitInterfaceSpecifier,
                                                  newNode.Identifier, newNode.TypeParameterList, newParameterList, newNode.ConstraintClauses, newNode.Body,
                                                  newNode.ExpressionBody, newNode.SemicolonToken)));
    }
Exemple #3
0
        public IEnumerable <AopTemplate> GetMethodTemplates(MethodDeclarationSyntax node)
        {
            ClassDeclarationSyntax     classDeclaration     = node.Ancestors().OfType <ClassDeclarationSyntax>().FirstOrDefault();
            NamespaceDeclarationSyntax namespaceDeclaration = classDeclaration.Ancestors().OfType <NamespaceDeclarationSyntax>().FirstOrDefault();

            var methodTemplates = new List <AopTemplate>();

            var globalTemplates = _templateService.GetGlobalTemplates(_filePath, namespaceDeclaration?.Name?.ToString(), classDeclaration?.Identifier.ToString(), methodName: node.Identifier.ToString());

            methodTemplates.AddRange(globalTemplates.Where(w => w.Action == AopTemplateAction.All || w.Action == AopTemplateAction.Methods));

            AddTemplatesFromClass(methodTemplates, AopTemplateAction.Methods, classDeclaration, node.Identifier.ToString(), node.Modifiers);

            AddTemplatesFromAttributes(methodTemplates, AopTemplateAction.Methods, node.AttributeLists, AopTemplateAction.Methods);

            if (!String.IsNullOrEmpty(BuilderSettings.OnlyTemplate))
            {
                return(methodTemplates.Where(w => w.TemplateName == BuilderSettings.OnlyTemplate));
            }

            return(methodTemplates.OrderBy(o => o.AdvicePriority));
        }
Exemple #4
0
        public SyntaxNode[] VisitMethodDeclaration(MethodDeclarationSyntax node, AopTemplate template)
        {
            var result = new List <SyntaxNode>();

            ClassDeclarationSyntax classDeclaration = node.Ancestors().OfType <ClassDeclarationSyntax>().FirstOrDefault();

            string methodName = node.Identifier.ToString();

            Console.Out.WriteLine("Method:  " + methodName);

            if (BuilderSettings.Verbosity > 2)
            {
                Console.Out.WriteLine(node.ToFullString());
            }

            IEnumerable <SyntaxNode> resultNodes = ProcessTemplate(_templateService, template, node, classDeclaration);

            if (resultNodes != null)
            {
                result.AddRange(resultNodes);
            }

            return(result.Count > 0 ? result.ToArray() : null);
        }
Exemple #5
0
            public override void VisitMethodDeclaration(MethodDeclarationSyntax node)
            {
                if (!node.AttributeLists.Any())
                {
                    base.VisitMethodDeclaration(node);
                    return;
                }

                var attribute = node.AttributeLists
                                .SelectMany(al => al.Attributes)
                                .SingleOrDefault(attr => attr.Name.ToString() == "JsonParseMethod");

                if (attribute is null)
                {
                    base.VisitMethodDeclaration(node);
                    return;
                }

                var semanticModel = Compilation.GetSemanticModel(node.SyntaxTree);

                var type       = node.Ancestors().OfType <TypeDeclarationSyntax>().First();
                var typeName   = type.ToTypeName(semanticModel);
                var typeSymbol = semanticModel.GetDeclaredSymbol(type);

                if (node.ReturnType.ToTypeName(semanticModel) != typeName)
                {
                    throw new InvalidOperationException($"Parse method {typeName}.{node.Identifier} must have a signature returning the containing type.");
                }

                if (node.ParameterList.Parameters.Count != 1)
                {
                    throw new InvalidOperationException($"Parse method {typeName}.{node.Identifier} must have a single parameter");
                }

                if (node.Modifiers.Any(m => m.ToString() == "private" || m.ToString() == "internal"))
                {
                    throw new InvalidOperationException($"Parse method {typeName}.{node.Identifier} must have be public or internal");
                }

                if (!node.Modifiers.Any(m => m.ToString() == "static"))
                {
                    throw new InvalidOperationException($"Parse method {typeName}.{node.Identifier} must have be static");
                }

                var parseType = node.ParameterList.Parameters.Single().Type !.ToTypeName(semanticModel);

                var writeMemberName = attribute.ArgumentList?.Arguments.SingleOrDefault();
                Func <ImmutableDictionary <TypeName, JsonType>, string, string>?writeStatement = null;
                MemberDeclarationSyntax?outputMember = null;

                if (writeMemberName is not null)
                {
                    if (writeMemberName.Expression is null)
                    {
                        throw new InvalidOperationException("JsonParseMethod declarations must have zero arguments or a single unnamed nameof parameter naming the write member");
                    }

                    if (writeMemberName.Expression is not InvocationExpressionSyntax invocation || invocation.Expression.ToString() != "nameof")
                    {
                        throw new InvalidOperationException("JsonParseMethod declarations that specify a write member must use nameof to reference the member");
                    }

                    if (invocation.ArgumentList.Arguments.Count != 1 || invocation.ArgumentList.Arguments.Single().Expression is null)
                    {
                        throw new InvalidOperationException("Invalid nameof operator");
                    }

                    var symbolInfo = semanticModel.GetSymbolInfo(invocation.ArgumentList.Arguments.Single().Expression);
                    var symbol     = symbolInfo.Symbol ?? symbolInfo.CandidateSymbols.OfType <IMethodSymbol>().SingleOrDefault(m => m.Parameters.Length == 0 && !m.ReturnsVoid && !m.IsStatic && SymbolEqualityComparer.Default.Equals(m.ContainingType, typeSymbol));

                    if (symbol is IMethodSymbol method)
                    {
                        var writeOutputType = method.ReturnType.ToTypeName();
                        writeStatement = (jsonTypes, valueExpr) => jsonTypes.TryGetValue(writeOutputType, out var parseTypeJsonType) && parseTypeJsonType.CanDirectWrite(jsonTypes) ? parseTypeJsonType.DirectWriteStatement !(jsonTypes, $"({valueExpr}).{method.Name}()") : null;
                        outputMember   = method.DeclaringSyntaxReferences.First().GetSyntax() as MemberDeclarationSyntax;
                    }
                    else if (symbol is IPropertySymbol property)
                    {
                        var writeOutputType = property.Type.ToTypeName();
                        writeStatement = (jsonTypes, valueExpr) => jsonTypes.TryGetValue(writeOutputType, out var parseTypeJsonType) && parseTypeJsonType.CanDirectWrite(jsonTypes) ? parseTypeJsonType.DirectWriteStatement !(jsonTypes, $"({valueExpr}).{property.Name}") : null;
                        outputMember   = property.DeclaringSyntaxReferences.First().GetSyntax() as MemberDeclarationSyntax;
                    }
                    else
                    {
                        throw new InvalidOperationException($"The member {invocation.ArgumentList.Arguments.Single().Expression} is not an instance property or method with no parameters and a return value on the same type as the parse method.");
                    }
                }

                                #pragma warning disable CS8603 // Possible null reference return.
                JsonTypes.Add(typeName, new JsonType(
                                  type: typeName,
                                  directReadExpression: jsonTypes => jsonTypes.TryGetValue(parseType, out var parseTypeJsonType) && parseTypeJsonType.CanDirectRead(jsonTypes) ? $"{typeName}.{node.Identifier}({parseTypeJsonType.DirectReadExpression!(jsonTypes)})" : null,
                                  directWriteStatement: writeStatement,
                                  converterName: $"{typeName.ShortName}MethodConverter",
                                  constructionMember: node,
                                  outputMember: outputMember,
                                  tinyType: null
                                  ));
                                #pragma warning restore CS8603 // Possible null reference return.
            }
 // returns the class in which a given method is contained in
 public ClassDeclarationSyntax GetClass(MethodDeclarationSyntax method)
 {
     return(method.Ancestors().OfType <ClassDeclarationSyntax>().First());
 }
Exemple #7
0
 public static bool IsInPartialType(this MethodDeclarationSyntax method) =>
 method.Ancestors().OfType <TypeDeclarationSyntax>().FirstOrDefault()?.Modifiers.Includes(SyntaxKind.PartialKeyword) ?? false;