public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node) { NamespaceDeclarationSyntax namespaceDeclaration = node.Ancestors().OfType <NamespaceDeclarationSyntax>().FirstOrDefault(); node = (ClassDeclarationSyntax)base.VisitClassDeclaration(node); var classTemplates = new List <AopTemplate>(); var globalTemplates = _templateService.GetGlobalTemplates(_filePath, namespaceDeclaration?.Name?.ToString(), node.Identifier.ToString()); classTemplates.AddRange(globalTemplates.Where(w => w.Action == Action)); classTemplates.ForEach(s => s.AppliedTo = AopTemplateApplied.Class); string className = node.Identifier.ToString(); Console.Out.WriteLine("Class: " + className); if (BuilderSettings.Verbosity > 2) { Console.Out.WriteLine("Old code:"); Console.Out.WriteLine(node.ToFullString()); } AopRewriter.AddTemplatesFromAttributes(classTemplates, Action, node.AttributeLists, AopTemplateAction.Methods); ClassDeclarationSyntax result = AopRewriter.ProcessTemplates <ClassDeclarationSyntax>(_templateService, classTemplates, node, node); return(result); }
protected override string InternalProcessFile(string sourcePath, string sourceCode) { // step 1. process comments string newSourceCode = ProcessAspectComments(sourceCode); SyntaxTree tree = CSharpSyntaxTree.ParseText(newSourceCode); AopWalker walker = GetClassTemplates(tree); // step 2. rewrite source code for classes { var classRewriter = new AopClassRewriter(sourcePath, this); SyntaxNode newNode = classRewriter.Visit(tree.GetRoot()); newSourceCode = newNode.ToFullString(); tree = CSharpSyntaxTree.ParseText(newSourceCode); } // step 3. rewrite source code for methods and properties { var rewriter = new AopRewriter(sourcePath, this, walker.ClassTemplates); SyntaxNode newNode = tree.GetRoot(); var methodNames = newNode.DescendantNodes().OfType <MethodDeclarationSyntax>().Select(s => s.Identifier.ValueText); foreach (string methodName in methodNames) { MethodDeclarationSyntax method = newNode.DescendantNodes().OfType <MethodDeclarationSyntax>().FirstOrDefault(w => w.Identifier.ValueText == methodName); if (method == null) { continue; } foreach (AopTemplate template in rewriter.GetMethodTemplates(method)) { method = newNode.DescendantNodes().OfType <MethodDeclarationSyntax>().FirstOrDefault(w => w.Identifier.ValueText == methodName); if (method == null) { continue; } template.AppliedTo = AopTemplateApplied.Method; SyntaxNode[] result = rewriter.VisitMethodDeclaration(method, template); newNode = newNode.ReplaceNode(method, result); } } var propertyNames = newNode.DescendantNodes().OfType <PropertyDeclarationSyntax>().Select(s => s.Identifier.ValueText); foreach (string propertyName in propertyNames) { PropertyDeclarationSyntax property = newNode.DescendantNodes().OfType <PropertyDeclarationSyntax>().FirstOrDefault(w => w.Identifier.ValueText == propertyName); if (property == null) { continue; } foreach (AopTemplate template in rewriter.GetPropertyTemplates(property)) { property = newNode.DescendantNodes().OfType <PropertyDeclarationSyntax>().FirstOrDefault(w => w.Identifier.ValueText == propertyName); if (property == null) { continue; } template.AppliedTo = AopTemplateApplied.Property; SyntaxNode[] result = rewriter.VisitPropertyDeclaration(property, template); newNode = newNode.ReplaceNode(property, result); } } newSourceCode = newNode.ToFullString(); tree = CSharpSyntaxTree.ParseText(newSourceCode); } // step 4. rewrite source code for using blocks { var rewriter = new AopUsingRewriter(); SyntaxNode newNode = rewriter.Visit(tree.GetRoot()); newSourceCode = newNode.ToFullString(); tree = CSharpSyntaxTree.ParseText(newSourceCode); } // step 5. rewrite source code for postprocessing classes templates { var classRewriter = new AopClassRewriter(sourcePath, this) { Action = AopTemplateAction.PostProcessingClasses }; SyntaxNode newNode = classRewriter.Visit(tree.GetRoot()); newSourceCode = newNode.ToFullString(); } // step 6: cleanup AopTemplate attributes and using { tree = CSharpSyntaxTree.ParseText(newSourceCode); SyntaxNode node = tree.GetRoot(); { AttributeListSyntax oldNode; while ((oldNode = node.DescendantNodes().OfType <AttributeListSyntax>().FirstOrDefault(w => w.Attributes.Any(a => a.Name.ToFullString() == "AopTemplate"))) != null) { node = node.RemoveNode(oldNode, SyntaxRemoveOptions.KeepLeadingTrivia); } } { UsingDirectiveSyntax oldNode; while ((oldNode = node.DescendantNodes().OfType <UsingDirectiveSyntax>().FirstOrDefault(w => w.Name.ToFullString() == "AOP.Common")) != null) { node = node.RemoveNode(oldNode, SyntaxRemoveOptions.KeepLeadingTrivia); } } // make sure the class has all required usings if (_requiredUsings.Count > 0) { for (int i = 0; i < _requiredUsings.Count; i++) { _requiredUsings[i] = _requiredUsings[i].Trim(';'); } foreach (UsingDirectiveSyntax usingNode in node.DescendantNodes().OfType <UsingDirectiveSyntax>()) { string usingName = usingNode.Name.ToFullString(); if (_requiredUsings.Contains(usingName)) { _requiredUsings.Remove(usingName); } } SyntaxNode insertNode = node.ChildNodes().LastOrDefault(w => w.Kind() == SyntaxKind.UsingDirective); bool insertAfter = true; if (insertNode == null) { insertNode = node.ChildNodes().First(); insertAfter = false; } foreach (string requiredUsing in _requiredUsings) { var usingNode = new List <SyntaxNode>() { SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(requiredUsing)) }; if (insertAfter) { node = node.InsertNodesAfter(insertNode, usingNode); } else { node = node.InsertNodesBefore(insertNode, usingNode); } } } newSourceCode = node.NormalizeWhitespace().ToFullString(); } return(newSourceCode); }