拆分与罗斯林的表达式语句 [英] Splitting the Expression statements with Roslyn
问题描述
我在开发rephrases CSHARP
代码的应用程序工作。我与罗斯林
这样做。我现在面临一个问题,分裂表达
。
Sample类
类节目
{
静态无效的主要(字串[] args)
{
浮动floatVariable = 20;
的Int16了IntVariable = 10;
字符串str =学校;
Console.Write(STR + floatVariable.ToString()+ intVariable.ToString()); //这个说法
}
}
示例代码,我面临的问题使用
串码=新的StreamReader(CLASSPATH).ReadToEnd();
VAR syntaxTree = CSharpSyntaxTree.ParseText(代码);
VAR syntaxRoot = syntaxTree.GetRoot();
//这会得到一个方法,并且该方法
变种MyMethods = syntaxRoot.DescendantNodes内声明()OfType&所述局部变量。MethodDeclarationSyntax>();
的foreach(在MyMethods MethodDeclarationSyntax MDS)
{
syntaxTree = CSharpSyntaxTree.ParseText(mds.ToFullString());
IEnumerable的< SyntaxNode> 。节点= syntaxTree.GetRoot()DescendantNodes();
IEnumerable的< VariableDeclarationSyntax> variableDeclarations = nodes.OfType< VariableDeclarationSyntax>();
的foreach(在variableDeclarations VariableDeclarationSyntax变量)
{
//我会收集变量的细节,如数据类型,变量名和初始值这里
}
的foreach(在mds.Body.Statements StatementSyntax语句)
{
如果(statement.CSharpKind()== SyntaxKind.ExpressionStatement)
{
//我想分裂表达式Console.Write(STR + floatVariable.ToString()+ intVariable.ToString());如下
// 1。 intVariable.ToString()
// 2。 floatVariable.ToString()
// 3。 STR
//然后,我必须找到从上述3解决结果整个数据类型=>这里串
}
}
}
任何帮助将是。感谢
编辑:的我有分裂参数化的表达式语句的麻烦
。我试图做到这一点,
如果(statement.CSharpKind()== SyntaxKind.ExpressionStatement)
{
ExpressionStatementSyntax表达=语句ExpressionStatementSyntax;
变种表达式= expression.Expression.DescendantNodes();
}
但这种分割每个令牌作为一个单独的元素。我只是想分裂的 Console.Write(STR + floatVariable.ToString()+ intVariable.ToString())
到
- Console.Write()
- STR
- intVariable.ToString( )
- floatVariable.ToString()
这很难说究竟做你想做的事,因为你指定什么代码应该做的只是在一个特定的情况下,不是一般的。
我理解它的方式是:
- 对于调用表达式,返回的被调用,也陷入它的参数,如果有的话表达
- 对于二元运算符,陷入两个孩子。
- 对于所有其他表达式,直接返回表达式。
通过本规范,并使用 CSharpSyntaxVisitor
,代码看起来是这样的:
公共静态的IEnumerable< ExpressionSyntax>斯普利特(ExpressionSyntax表达式)
{
返回新SplitVisitor()访问(表达)。
}
类SplitVisitor:CSharpSyntaxVisitor<&IEnumerable的LT; ExpressionSyntax>>
{
公共覆盖的IEnumerable< ExpressionSyntax> VisitInvocationExpression(
InvocationExpressionSyntax节点)
{
收益率的回报node.Expression;
VAR argumentExpressions = node.ArgumentList.Arguments
.SelectMany(A =>参观(a.Expression));
的foreach(在argumentExpressions VAR表达式)
收益率的回报表现;
}
公共覆盖的IEnumerable< ExpressionSyntax> VisitBinaryExpression(
BinaryExpressionSyntax节点)
{
的foreach
收益率的回报一个表达式(var在访问(node.Left)的表达);
的foreach(在访问(node.Right VAR表达式))
收益率的回报表现;
}
公共覆盖的IEnumerable< ExpressionSyntax> DefaultVisit(SyntaxNode节点)
{
VAR表达式=节点ExpressionSyntax;
如果(表达式!= NULL)
收益率的回报表现;
}
}
I am working in developing an application that rephrases CSharp
code. I am doing this with Roslyn
. I am facing a problem with splitting expressions
.
Sample class
class Program
{
static void Main(string[] args)
{
float floatVariable = 20;
Int16 intVariable = 10;
string str = "School";
Console.Write(str + floatVariable.ToString() + intVariable.ToString()); // Facing problem with this statement
}
}
Sample code I am using
string code = new StreamReader(classPath).ReadToEnd();
var syntaxTree = CSharpSyntaxTree.ParseText(code);
var syntaxRoot = syntaxTree.GetRoot();
//This will get the method and local variables declared inside the method
var MyMethods = syntaxRoot.DescendantNodes().OfType<MethodDeclarationSyntax>();
foreach (MethodDeclarationSyntax mds in MyMethods)
{
syntaxTree = CSharpSyntaxTree.ParseText(mds.ToFullString());
IEnumerable<SyntaxNode> nodes = syntaxTree.GetRoot().DescendantNodes();
IEnumerable<VariableDeclarationSyntax> variableDeclarations = nodes.OfType<VariableDeclarationSyntax>();
foreach (VariableDeclarationSyntax variable in variableDeclarations)
{
// I will collect the variable details like Datatype, variable names and initialized values here
}
foreach (StatementSyntax statement in mds.Body.Statements)
{
if (statement.CSharpKind() == SyntaxKind.ExpressionStatement)
{
//I want to split the expressions "Console.Write(str + floatVariable.ToString() + intVariable.ToString());" as below
//1. intVariable.ToString()
//2. floatVariable.ToString()
//3. str
//Then I have to find the whole data type from the resolved result of above 3 => string here
}
}
}
Any help will be appreciated.
Edit: I am having trouble in splitting the parameterized expression statements. I am trying to do this by,
if (statement.CSharpKind() == SyntaxKind.ExpressionStatement)
{
ExpressionStatementSyntax expression = statement as ExpressionStatementSyntax;
var expressions = expression.Expression.DescendantNodes();
}
But this splits each and every token as a seperate elements. I just want to split the Console.Write(str + floatVariable.ToString() + intVariable.ToString())
into,
- Console.Write()
- str
- intVariable.ToString()
- floatVariable.ToString()
It's hard to tell what exactly do you want to do, because you specified what the code should do only in one specific case, not in general.
The way I interpret it is:
- For invocation expression, return the expression that's being invoked and also descend into its arguments, if any.
- For binary operators, descend into both children.
- For all other expressions, return the expression directly.
With this specification and using CSharpSyntaxVisitor
, the code could look like this:
public static IEnumerable<ExpressionSyntax> Split(ExpressionSyntax expression)
{
return new SplitVisitor().Visit(expression);
}
class SplitVisitor : CSharpSyntaxVisitor<IEnumerable<ExpressionSyntax>>
{
public override IEnumerable<ExpressionSyntax> VisitInvocationExpression(
InvocationExpressionSyntax node)
{
yield return node.Expression;
var argumentExpressions = node.ArgumentList.Arguments
.SelectMany(a => Visit(a.Expression));
foreach (var expression in argumentExpressions)
yield return expression;
}
public override IEnumerable<ExpressionSyntax> VisitBinaryExpression(
BinaryExpressionSyntax node)
{
foreach (var expression in Visit(node.Left))
yield return expression;
foreach (var expression in Visit(node.Right))
yield return expression;
}
public override IEnumerable<ExpressionSyntax> DefaultVisit(SyntaxNode node)
{
var expression = node as ExpressionSyntax;
if (expression != null)
yield return expression;
}
}
这篇关于拆分与罗斯林的表达式语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!