📄 codedomoutputvisitor.cs
字号:
// using (new expr) { stmts; }
//
// emulate with
// object _dispose;
// try
// {
// _dispose = new expr;
//
// stmts;
// }
// finally
// {
// if (((_dispose != null)
// && (typeof(System.IDisposable).IsInstanceOfType(_dispose) == true)))
// {
// ((System.IDisposable)(_dispose)).Dispose();
// }
// }
//
usingId++; // in case nested using() statements
string name = "_dispose" + usingId.ToString();
CodeVariableDeclarationStatement disposable = new CodeVariableDeclarationStatement("System.Object", name, new CodePrimitiveExpression(null));
AddStmt(disposable);
CodeTryCatchFinallyStatement tryStmt = new CodeTryCatchFinallyStatement();
CodeVariableReferenceExpression left1 = new CodeVariableReferenceExpression(name);
codeStack.Push(NullStmtCollection); // send statements to nul Statement collection
CodeExpression right1 = (CodeExpression)usingStatement.ResourceAcquisition.AcceptVisitor(this, data);
codeStack.Pop();
CodeAssignStatement assign1 = new CodeAssignStatement(left1, right1);
tryStmt.TryStatements.Add(assign1);
tryStmt.TryStatements.Add(new CodeSnippetStatement());
codeStack.Push(tryStmt.TryStatements);
usingStatement.EmbeddedStatement.AcceptChildren(this, data);
codeStack.Pop();
CodeMethodInvokeExpression isInstanceOfType = new CodeMethodInvokeExpression(new CodeTypeOfExpression(typeof(IDisposable)), "IsInstanceOfType", new CodeExpression[] { left1 });
CodeConditionStatement if1 = new CodeConditionStatement();
if1.Condition = new CodeBinaryOperatorExpression(new CodeBinaryOperatorExpression(left1, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)),
CodeBinaryOperatorType.BooleanAnd,
new CodeBinaryOperatorExpression(isInstanceOfType, CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(true)));
if1.TrueStatements.Add(new CodeMethodInvokeExpression(new CodeCastExpression(typeof(IDisposable),left1), "Dispose", new CodeExpression[] { }));
tryStmt.FinallyStatements.Add(if1);
// Add Statement to Current Statement Collection
AddStmt(tryStmt);
return null;
}
public override object VisitTypeOfExpression(TypeOfExpression typeOfExpression, object data)
{
return new CodeTypeOfExpression(ConvType(typeOfExpression.TypeReference));
}
public override object VisitCastExpression(CastExpression castExpression, object data)
{
CodeTypeReference typeRef = ConvType(castExpression.CastTo);
return new CodeCastExpression(typeRef, (CodeExpression)castExpression.Expression.AcceptVisitor(this, data));
}
public override object VisitIndexerExpression(IndexerExpression indexerExpression, object data)
{
return new CodeIndexerExpression((CodeExpression)indexerExpression.TargetObject.AcceptVisitor(this, data), GetExpressionList(indexerExpression.Indexes));
}
public override object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data)
{
return new CodeThisReferenceExpression();
}
public override object VisitBaseReferenceExpression(BaseReferenceExpression baseReferenceExpression, object data)
{
return new CodeBaseReferenceExpression();
}
public override object VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression, object data)
{
if (arrayCreateExpression.ArrayInitializer == null) {
return new CodeArrayCreateExpression(ConvType(arrayCreateExpression.CreateType),
arrayCreateExpression.Arguments[0].AcceptVisitor(this, data) as CodeExpression);
}
return new CodeArrayCreateExpression(ConvType(arrayCreateExpression.CreateType),
GetExpressionList(arrayCreateExpression.ArrayInitializer.CreateExpressions));
}
public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
{
return new CodeObjectCreateExpression(ConvType(objectCreateExpression.CreateType),
objectCreateExpression.Parameters == null ? null : GetExpressionList(objectCreateExpression.Parameters));
}
public override object VisitParameterDeclarationExpression(ParameterDeclarationExpression parameterDeclarationExpression, object data)
{
CodeParameterDeclarationExpression parameter = new CodeParameterDeclarationExpression(ConvType(parameterDeclarationExpression.TypeReference), parameterDeclarationExpression.ParameterName);
parameters.Add(parameter);
return parameter;
}
public override object VisitBreakStatement(BreakStatement breakStatement, object data)
{
// RG:
// break;
//
// emulate with:
// goto break1;
//
Breakable breakable = breakableStack.Peek();
breakable.IsBreak = true;
CodeGotoStatement breakStmt = new CodeGotoStatement("break" + breakable.Id);
AddStmt(breakStmt);
return breakStmt;
}
public override object VisitContinueStatement(ContinueStatement continueStatement, object data)
{
// RG:
// continue;
//
// emulate with:
// goto continue1;
//
Breakable breakable = breakableStack.Peek();
// Is continuable?
if (!breakable.AllowContinue)
{
// walk stack to find first continuable item
Breakable[] stack = breakableStack.ToArray();
foreach (Breakable b in stack)
{
if (b.AllowContinue)
{
breakable = b;
break;
}
}
}
breakable.IsContinue = true;
CodeGotoStatement continueStmt = new CodeGotoStatement("continue" + breakable.Id);
AddStmt(continueStmt);
return continueStmt;
}
bool IsField(string type, string fieldName)
{
bool isField = environmentInformationProvider.HasField(type, fieldName);
if (!isField) {
int idx = type.LastIndexOf('.');
if (idx >= 0) {
type = type.Substring(0, idx) + "+" + type.Substring(idx + 1);
isField = IsField(type, fieldName);
}
}
return isField;
}
bool IsFieldReferenceExpression(FieldReferenceExpression fieldReferenceExpression)
{
if (fieldReferenceExpression.TargetObject is ThisReferenceExpression
|| fieldReferenceExpression.TargetObject is BaseReferenceExpression)
{
//field detection for fields\props inherited from base classes
return IsField(fieldReferenceExpression.FieldName);
}
return false;
}
public override object VisitFieldReferenceExpression(FieldReferenceExpression fieldReferenceExpression, object data)
{
if (methodReference) {
methodReference = false;
return new CodeMethodReferenceExpression((CodeExpression)fieldReferenceExpression.TargetObject.AcceptVisitor(this, data), fieldReferenceExpression.FieldName);
}
if (IsFieldReferenceExpression(fieldReferenceExpression)) {
return new CodeFieldReferenceExpression((CodeExpression)fieldReferenceExpression.TargetObject.AcceptVisitor(this, data),
fieldReferenceExpression.FieldName);
} else {
if (fieldReferenceExpression.TargetObject is FieldReferenceExpression) {
if (IsPossibleTypeReference((FieldReferenceExpression)fieldReferenceExpression.TargetObject)) {
CodeTypeReferenceExpression typeRef = ConvertToTypeReference((FieldReferenceExpression)fieldReferenceExpression.TargetObject);
if (IsField(typeRef.Type.BaseType, fieldReferenceExpression.FieldName)) {
return new CodeFieldReferenceExpression(typeRef,
fieldReferenceExpression.FieldName);
} else {
return new CodePropertyReferenceExpression(typeRef,
fieldReferenceExpression.FieldName);
}
}
}
CodeExpression codeExpression = (CodeExpression)fieldReferenceExpression.TargetObject.AcceptVisitor(this, data);
return new CodePropertyReferenceExpression(codeExpression,
fieldReferenceExpression.FieldName);
}
}
#endregion
#endregion
bool IsPossibleTypeReference(FieldReferenceExpression fieldReferenceExpression)
{
while (fieldReferenceExpression.TargetObject is FieldReferenceExpression) {
fieldReferenceExpression = (FieldReferenceExpression)fieldReferenceExpression.TargetObject;
}
IdentifierExpression identifier = fieldReferenceExpression.TargetObject as IdentifierExpression;
if (identifier != null)
return !IsField(identifier.Identifier) && !IsLocalVariable(identifier.Identifier);
TypeReferenceExpression tre = fieldReferenceExpression.TargetObject as TypeReferenceExpression;
if (tre != null)
return true;
return false;
}
bool IsLocalVariable(string identifier)
{
foreach (CodeVariableDeclarationStatement variable in variables) {
if (variable.Name == identifier)
return true;
}
foreach (CodeParameterDeclarationExpression parameter in parameters)
{
if (parameter.Name == identifier)
return true;
}
return false;
}
bool IsField(string identifier)
{
if (currentTypeDeclaration == null) // e.g. in unit tests
return false;
foreach (INode node in currentTypeDeclaration.Children) {
if (node is FieldDeclaration) {
FieldDeclaration fd = (FieldDeclaration)node;
if (fd.GetVariableDeclaration(identifier) != null) {
return true;
}
}
}
//field detection for fields\props inherited from base classes
if (currentTypeDeclaration.BaseTypes.Count > 0) {
return IsField(currentTypeDeclaration.BaseTypes[0].ToString(), identifier);
}
return false;
}
static CodeTypeReferenceExpression ConvertToTypeReference(FieldReferenceExpression fieldReferenceExpression)
{
StringBuilder type = new StringBuilder("");
while (fieldReferenceExpression.TargetObject is FieldReferenceExpression) {
type.Insert(0,'.');
type.Insert(1,fieldReferenceExpression.FieldName.ToCharArray());
fieldReferenceExpression = (FieldReferenceExpression)fieldReferenceExpression.TargetObject;
}
type.Insert(0,'.');
type.Insert(1,fieldReferenceExpression.FieldName.ToCharArray());
if (fieldReferenceExpression.TargetObject is IdentifierExpression) {
type.Insert(0, ((IdentifierExpression)fieldReferenceExpression.TargetObject).Identifier.ToCharArray());
string oldType = type.ToString();
int idx = oldType.LastIndexOf('.');
while (idx > 0) {
if (Type.GetType(type.ToString()) != null) {
break;
}
string stype = type.ToString().Substring(idx + 1);
type = new StringBuilder(type.ToString().Substring(0, idx));
type.Append("+");
type.Append(stype);
idx = type.ToString().LastIndexOf('.');
}
if (Type.GetType(type.ToString()) == null) {
type = new StringBuilder(oldType);
}
return new CodeTypeReferenceExpression(type.ToString());
} else if (fieldReferenceExpression.TargetObject is TypeReferenceExpression) {
type.Insert(0, ((TypeReferenceExpression)fieldReferenceExpression.TargetObject).TypeReference.SystemType);
return new CodeTypeReferenceExpression(type.ToString());
} else {
return null;
}
}
CodeExpression[] GetExpressionList(IList expressionList)
{
if (expressionList == null) {
return new CodeExpression[0];
}
CodeExpression[] list = new CodeExpression[expressionList.Count];
for (int i = 0; i < expressionList.Count; ++i) {
list[i] = (CodeExpression)((Expression)expressionList[i]).AcceptVisitor(this, null);
if (list[i] == null) {
list[i] = new CodePrimitiveExpression(0);
}
}
return list;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -