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); })); }
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))); }
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)); }
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); }
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()); }
public static bool IsInPartialType(this MethodDeclarationSyntax method) => method.Ancestors().OfType <TypeDeclarationSyntax>().FirstOrDefault()?.Modifiers.Includes(SyntaxKind.PartialKeyword) ?? false;