- RoslynCTPSamples.zip
- CodeGenerator
- bin
- Debug
- Release
- CodeGenerator.csproj
- CodeGenerator.csproj.user
- obj
- x86
- Debug
- DesignTimeResolveAssemblyReferences.cache
- DesignTimeResolveAssemblyReferencesInput.cache
- TempPE
- Program.cs
- Properties
- CodeGeneratorTest
- EventImplementer
- RefactoringConsole
- RefactoringExtension
- RoslynCTPLibrary
- RoslynCTPSamples.sln
- RoslynCTPSamples.suo
- RoslynCTPSamples.vsmdi
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Roslyn.Compilers.CSharp;
using RoslynCTPLibrary.Extensions;
namespace RoslynCTPLibrary.Refactoring {
public static class DeclarationExtractor {
public static string ProcessCode(string code, SemanticModel sm) {
return SyntaxTree.Create("t", (CompilationUnitSyntax)sm.SyntaxTree.Root.ReplaceNodes(sm.SyntaxTree.Root.DescendentNodes(
(BaseMethodDeclarationSyntax method) => method.BodyOpt != null && method.BodyOpt.Statements.Count > 0), oldMethod => ProcessMethod(oldMethod, sm)).Format()).ToString().Replace("#region", "#region ").Replace("#endregion", "#endregion ");
}
public static BaseMethodDeclarationSyntax ProcessMethod(BaseMethodDeclarationSyntax oldMethod, SemanticModel semanticModel) {
var tree = semanticModel.SyntaxTree;
var declarations = new List<LocalDeclarationStatementSyntax>();
var tabooIds = oldMethod.BodyOpt.DescendentNodes().OfType<LocalDeclarationStatementSyntax>().SelectMany(d => d.Declaration.Variables).GroupBy(v => v.Identifier.ValueText).Where(g => g.Count() > 1).ToLookup(g => g.Key);
Func<BlockSyntax, BlockSyntax> processBlock = null; processBlock = oldBlock => oldBlock.Update(oldBlock.OpenBraceToken, Syntax.List(oldBlock.Statements.Aggregate(new List<StatementSyntax>(), (statements, statement) => {
var declaration = statement as LocalDeclarationStatementSyntax; TypeSymbol type;
if (declaration != null && (type = semanticModel.GetSemanticInfo(declaration.Declaration.Type).Type).Kind != SymbolKind.ErrorType
&& !declaration.Declaration.Variables.Any(var => tabooIds.Contains(var.Identifier.ValueText) || (var.InitializerOpt != null && var.InitializerOpt.Value is InitializerExpressionSyntax))) {
var newDeclaration = declaration.ReplaceNodes(declaration.Declaration.Variables, oldVarDecl => oldVarDecl.ReplaceNode(oldVarDecl.InitializerOpt, null));
declarations.Add(newDeclaration.ReplaceNode(newDeclaration.Declaration.Type, Syntax.ParseTypeName(type.ToMinimalDisplayString(tree.GetLocation(declaration), semanticModel)).WithLeadingTrivia(newDeclaration.GetLeadingTrivia())));
statements.AddRange(declaration.Declaration.Variables.Where(var => var.InitializerOpt != null).Select(var => Syntax.ExpressionStatement(Syntax.BinaryExpression(SyntaxKind.AssignExpression, Syntax.IdentifierName(var.Identifier),
right: var.InitializerOpt.Value.ReplaceNodes(statement.DescendentNodes((BlockSyntax block) => block.Statements.Count > 0), processBlock)))));
} else
statements.Add(statement.ReplaceNodes(statement.DescendentNodes((BlockSyntax block) => block.Statements.Count > 0), processBlock));
return statements;
}).AsEnumerable()), oldBlock.CloseBraceToken);
var newBlock = processBlock(oldMethod.BodyOpt);
return oldMethod.ReplaceNode(oldMethod.BodyOpt, newBlock.Update(newBlock.OpenBraceToken,
Syntax.List(declarations.Concat(newBlock.ReplaceNode(newBlock.Statements.First(), newBlock.Statements.First().WithLeadingTrivia(Syntax.Comment("//End of declarations" + Environment.NewLine))).Statements)), newBlock.CloseBraceToken)).Format();
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.