📄 codedomvisitor.cs
字号:
{
_expression = null;
node.Target.Accept(this);
if (_expression == null)
return;
if (_expression is CodeMethodReferenceExpression) {
_expression = new CodeObjectCreateExpression(ConvTypeRef(node.Type), _expression);
} else {
_expression = new CodeCastExpression(ConvTypeRef(node.Type), _expression);
}
}
public override void OnBlock(Block node)
{
foreach (Statement n in node.Statements)
n.Accept(this);
}
public override void OnExpressionStatement(ExpressionStatement node)
{
_expression = null;
node.Expression.Accept(this);
if (_expression != null)
_statements.Add(new CodeExpressionStatement(_expression));
}
public override void OnGotoStatement(GotoStatement node)
{
_statements.Add(new CodeGotoStatement(node.Label.Name));
}
public override void OnNullLiteralExpression(NullLiteralExpression node)
{
_expression = new CodePrimitiveExpression(null);
}
public override void OnBoolLiteralExpression(BoolLiteralExpression node)
{
_expression = new CodePrimitiveExpression(node.Value);
}
public override void OnStringLiteralExpression(StringLiteralExpression node)
{
_expression = new CodePrimitiveExpression(node.Value);
}
public override void OnCharLiteralExpression(CharLiteralExpression node)
{
_expression = new CodePrimitiveExpression(node.Value);
}
public override void OnIntegerLiteralExpression(IntegerLiteralExpression node)
{
_expression = new CodePrimitiveExpression(node.Value);
}
public override void OnDoubleLiteralExpression(DoubleLiteralExpression node)
{
_expression = new CodePrimitiveExpression(node.Value);
}
public override void OnMemberReferenceExpression(MemberReferenceExpression node)
{
_expression = null;
node.Target.Accept(this);
if (_expression != null) {
if (_expression is CodeTypeReferenceExpression) {
string baseName = ((CodeTypeReferenceExpression)_expression).Type.BaseType;
_expression = CreateMemberExpression(_expression, baseName, node.Name, true);
} else {
_expression = CreateMemberExpression(_expression, node.Name);
}
}
}
public override void OnDeclarationStatement(DeclarationStatement node)
{
CodeVariableDeclarationStatement var = new CodeVariableDeclarationStatement(ConvTypeRef(node.Declaration.Type),
node.Declaration.Name);
if (node.Initializer != null) {
_expression = null;
node.Initializer.Accept(this);
var.InitExpression = _expression;
}
_statements.Add(var);
}
CodeVariableDeclarationStatement GetLocalVariable(string name)
{
foreach (CodeStatement stmt in _statements) {
CodeVariableDeclarationStatement var = stmt as CodeVariableDeclarationStatement;
if (var != null && var.Name == name) {
return var;
}
}
return null;
}
public override void OnReferenceExpression(ReferenceExpression node)
{
if (pc.GetClass(node.Name) != null) {
_expression = new CodeTypeReferenceExpression(node.Name);
} else if (pc.NamespaceExists(node.Name)) {
_expression = new CodeTypeReferenceExpression(node.Name);
} else if (GetLocalVariable(node.Name) != null) {
_expression = new CodeVariableReferenceExpression(node.Name);
} else {
_expression = CreateMemberExpression(new CodeThisReferenceExpression(), node.Name);
}
}
CodeExpression CreateMemberExpression(CodeExpression expr, string name)
{
if (expr is CodeTypeReferenceExpression) {
string typeRef = ((CodeTypeReferenceExpression)_expression).Type.BaseType;
return CreateMemberExpression(expr, typeRef, name, true);
} else if (expr is CodeThisReferenceExpression) {
string typeRef = _namespace.Name + "." + _class.Name;
return CreateMemberExpression(expr, typeRef, name, false);
} else if (expr is CodeFieldReferenceExpression || expr is CodePropertyReferenceExpression) {
if (_fieldReferenceType == null)
return new CodePropertyReferenceExpression(expr, name);
return CreateMemberExpression(expr, _fieldReferenceType.FullyQualifiedName, name, false);
} else if (expr is CodeVariableReferenceExpression) {
string varName = ((CodeVariableReferenceExpression)expr).VariableName;
CodeVariableDeclarationStatement varDecl = GetLocalVariable(varName);
return CreateMemberExpression(expr, varDecl.Type.BaseType, name, false);
} else {
_fieldReferenceType = null;
return new CodePropertyReferenceExpression(expr, name);
}
}
IReturnType _fieldReferenceType;
CodeExpression CreateMemberExpression(CodeExpression target, string parentName, string name, bool isStatic)
{
_fieldReferenceType = null;
string combinedName = parentName + "." + name;
if (pc.GetClass(combinedName) != null)
return new CodeTypeReferenceExpression(combinedName);
else if (pc.NamespaceExists(combinedName))
return new CodeTypeReferenceExpression(combinedName);
GetClassReturnType rt = new GetClassReturnType(pc, parentName, 0);
foreach (IProperty prop in rt.GetProperties()) {
if (prop.IsStatic == isStatic && prop.Name == name) {
_fieldReferenceType = prop.ReturnType;
return new CodePropertyReferenceExpression(target, name);
}
}
foreach (IEvent ev in rt.GetEvents()) {
if (ev.IsStatic == isStatic && ev.Name == name) {
_fieldReferenceType = ev.ReturnType;
return new CodeEventReferenceExpression(target, name);
}
}
foreach (IMethod me in rt.GetMethods()) {
if (me.IsStatic == isStatic && me.Name == name) {
_fieldReferenceType = me.ReturnType;
CodeMethodReferenceExpression cmre = new CodeMethodReferenceExpression(target, name);
cmre.UserData["method"] = me;
return cmre;
}
}
foreach (IField field in rt.GetFields()) {
if (field.IsStatic == isStatic && field.Name == name) {
_fieldReferenceType = field.ReturnType;
return new CodeFieldReferenceExpression(target, name);
}
}
// unknown member, guess:
if (char.IsUpper(name, 0))
return new CodePropertyReferenceExpression(target, name);
else
return new CodeFieldReferenceExpression(target, name);
}
public override void OnAstLiteralExpression(AstLiteralExpression node)
{
_expression = new CodeObjectCreateExpression(node.Node.GetType());
}
public override void OnMethodInvocationExpression(MethodInvocationExpression node)
{
_expression = null;
node.Target.Accept(this);
if (_expression != null) {
CodeMethodInvokeExpression cmie;
CodeObjectCreateExpression coce;
if (_expression is CodeTypeReferenceExpression) {
coce = new CodeObjectCreateExpression(((CodeTypeReferenceExpression)_expression).Type);
ConvertExpressions(coce.Parameters, node.Arguments);
_expression = coce;
} else if (_expression is CodeMethodReferenceExpression) {
cmie = new CodeMethodInvokeExpression((CodeMethodReferenceExpression)_expression);
ConvertExpressions(cmie.Parameters, node.Arguments);
FixArrayArguments(cmie);
_expression = cmie;
} else if (_expression is CodeFieldReferenceExpression) {
// when a type is unknown, a MemberReferenceExpression is translated into a CodeFieldReferenceExpression
CodeFieldReferenceExpression cfre = (CodeFieldReferenceExpression)_expression;
cmie = new CodeMethodInvokeExpression(cfre.TargetObject, cfre.FieldName);
ConvertExpressions(cmie.Parameters, node.Arguments);
FixArrayArguments(cmie);
_expression = cmie;
} else {
_expression = null;
}
}
}
/// <summary>
/// Fixes the type of array literals used as arguments to the method.
/// </summary>
void FixArrayArguments(CodeMethodInvokeExpression cmie)
{
IMethod m = cmie.Method.UserData["method"] as IMethod;
if (m != null) {
int count = Math.Min(m.Parameters.Count, cmie.Parameters.Count);
for (int i = 0; i < count; i++) {
CodeArrayCreateExpression cace = cmie.Parameters[i] as CodeArrayCreateExpression;
if (cace != null && (bool)cace.UserData["unknownType"]
&& m.Parameters[i].ReturnType.ArrayDimensions > 0)
{
cace.CreateType = new CodeTypeReference(m.Parameters[i].ReturnType.FullyQualifiedName);
}
}
}
}
/// <summary>Converts a list of expressions to CodeDom expressions.</summary>
void ConvertExpressions(CodeExpressionCollection args, ExpressionCollection expressions)
{
foreach (Expression e in expressions) {
_expression = null;
e.Accept(this);
args.Add(_expression);
}
}
public override void OnReturnStatement(ReturnStatement node)
{
_expression = null;
if (node.Expression != null)
node.Expression.Accept(this);
_statements.Add(new CodeMethodReturnStatement(_expression));
}
public override void OnSelfLiteralExpression(SelfLiteralExpression node)
{
_expression = new CodeThisReferenceExpression();
}
public override void OnSuperLiteralExpression(SuperLiteralExpression node)
{
_expression = new CodeBaseReferenceExpression();
}
public override void OnTypeofExpression(TypeofExpression node)
{
_expression = new CodeTypeOfExpression(ConvTypeRef(node.Type));
}
public override void OnArrayLiteralExpression(ArrayLiteralExpression node)
{
BooResolver resolver = new BooResolver();
IReturnType createType = resolver.GetTypeOfExpression(node, null);
if (createType == null)
createType = ReflectionReturnType.Object;
CodeExpression[] initializers = new CodeExpression[node.Items.Count];
for (int i = 0; i < initializers.Length; i++) {
_expression = null;
node.Items[i].Accept(this);
initializers[i] = _expression;
}
_expression = new CodeArrayCreateExpression(createType.FullyQualifiedName, initializers);
_expression.UserData["unknownType"] = node.Type != null;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -