📄 convertvisitorstatements.cs
字号:
ArrayCreateExpression ace = new ArrayCreateExpression(r);
foreach (Expression boundExpr in o.Arguments) {
ace.Arguments.Add(Expression.AddInteger((Expression)boundExpr, 1));
}
ace.StartLocation = o.StartLocation;
B.Expression expr = new B.ReferenceExpression(GetLexicalInfo(identifier), identifier.Identifier);
expr = new B.BinaryExpression(GetLexicalInfo(reDimStatement), B.BinaryOperatorType.Assign, expr, ConvertExpression(ace));
list.Add(new B.ExpressionStatement(expr));
}
}
}
return list;
}
public object Visit(StatementExpression statementExpression, object data)
{
B.ExpressionStatement st = new B.ExpressionStatement(GetLexicalInfo(statementExpression));
st.Expression = ConvertExpression(statementExpression.Expression);
return st;
}
public object Visit(LocalVariableDeclaration lvd, object data)
{
ArrayList list = new ArrayList();
for (int i = 0; i < lvd.Variables.Count; i++) {
B.DeclarationStatement varDecl = new B.DeclarationStatement(GetLexicalInfo(lvd));
varDecl.Declaration = new B.Declaration(GetLexicalInfo(lvd.Variables[i]), lvd.Variables[i].Name, ConvertTypeReference(lvd.GetTypeForVariable(i)));
varDecl.Initializer = ConvertExpression(lvd.Variables[i].Initializer);
list.Add(varDecl);
}
return list;
}
public object Visit(EmptyStatement emptyStatement, object data)
{
return null;
}
public object Visit(ReturnStatement returnStatement, object data)
{
return new B.ReturnStatement(GetLexicalInfo(returnStatement), ConvertExpression(returnStatement.Expression), null);
}
public object Visit(YieldStatement yieldStatement, object data)
{
ReturnStatement rs = yieldStatement.Statement as ReturnStatement;
if (rs == null)
return new B.ReturnStatement(GetLexicalInfo(yieldStatement));
return new B.YieldStatement(GetLexicalInfo(yieldStatement), ConvertExpression(rs.Expression));
}
public object Visit(ThrowStatement throwStatement, object data)
{
return new B.RaiseStatement(GetLexicalInfo(throwStatement), ConvertExpression(throwStatement.Expression), null);
}
public object Visit(IfElseStatement ifElseStatement, object data)
{
B.IfStatement ifs = new B.IfStatement(GetLexicalInfo(ifElseStatement));
B.IfStatement outerIf = ifs;
ifs.EndSourceLocation = GetLocation(ifElseStatement.EndLocation);
ifs.Condition = ConvertExpression(ifElseStatement.Condition);
ifs.TrueBlock = ConvertBlock(ifElseStatement.TrueStatement);
if (ifElseStatement.HasElseIfSections) {
foreach (ElseIfSection sec in ifElseStatement.ElseIfSections) {
B.IfStatement elif = new B.IfStatement(GetLexicalInfo(sec));
elif.EndSourceLocation = GetLocation(sec.EndLocation);
elif.Condition = ConvertExpression(sec.Condition);
elif.TrueBlock = ConvertBlock(sec.EmbeddedStatement);
ifs.FalseBlock = new B.Block();
ifs.FalseBlock.Add(elif);
ifs = elif;
}
}
if (ifElseStatement.HasElseStatements) {
ifs.FalseBlock = ConvertBlock(ifElseStatement.FalseStatement);
}
return outerIf;
}
public object Visit(ElseIfSection elseIfSection, object data)
{
throw new ApplicationException("ElseIfSection visited");
}
B.LabelStatement MakeLabel(string name)
{
return new B.LabelStatement(lastLexicalInfo, name);
}
public object Visit(LabelStatement labelStatement, object data)
{
return new B.LabelStatement(GetLexicalInfo(labelStatement), labelStatement.Label);
}
public object Visit(GotoStatement gotoStatement, object data)
{
return new B.GotoStatement(GetLexicalInfo(gotoStatement), new B.ReferenceExpression(gotoStatement.Label));
}
public object Visit(StopStatement stopStatement, object data)
{
return new B.ExpressionStatement(MakeMethodCall("System.Diagnostics.Debugger.Break"));
}
public object Visit(EndStatement endStatement, object data)
{
return new B.ExpressionStatement(MakeMethodCall("System.Environment.Exit", new B.IntegerLiteralExpression(0)));
}
public object Visit(BreakStatement breakStatement, object data)
{
return new B.BreakStatement(GetLexicalInfo(breakStatement));
}
public object Visit(ContinueStatement continueStatement, object data)
{
return new B.ContinueStatement(GetLexicalInfo(continueStatement));
}
public object Visit(LockStatement lockStatement, object data)
{
return CreateMacro(lockStatement, "lock", lockStatement.EmbeddedStatement, lockStatement.LockExpression);
}
public object Visit(UsingStatement usingStatement, object data)
{
LocalVariableDeclaration varDecl = usingStatement.ResourceAcquisition as LocalVariableDeclaration;
Expression expr;
if (varDecl != null) {
if (varDecl.Variables.Count != 1) {
AddError(usingStatement, "Only one variable can be used with the using statement.");
return null;
}
expr = new AssignmentExpression(new IdentifierExpression(varDecl.Variables[0].Name),
AssignmentOperatorType.Assign,
varDecl.Variables[0].Initializer);
} else {
StatementExpression se = usingStatement.ResourceAcquisition as StatementExpression;
if (se == null) {
AddError(usingStatement, "Expected: VariableDeclaration or StatementExpression");
return null;
}
expr = se.Expression;
}
return CreateMacro(usingStatement, "using", usingStatement.EmbeddedStatement, expr);
}
public object Visit(WithStatement withStatement, object data)
{
return CreateMacro(withStatement, "with", withStatement.Body, withStatement.Expression);
}
public object Visit(OnErrorStatement onErrorStatement, object data)
{
AddError(onErrorStatement, "old VB-style exception handling is not supported.");
return null;
}
public object Visit(ErrorStatement errorStatement, object data)
{
AddError(errorStatement, "old VB-style exception handling is not supported.");
return null;
}
public object Visit(ResumeStatement resumeStatement, object data)
{
AddError(resumeStatement, "old VB-style exception handling is not supported.");
return null;
}
public object Visit(TryCatchStatement tryCatchStatement, object data)
{
B.TryStatement t = new B.TryStatement(GetLexicalInfo(tryCatchStatement));
t.EndSourceLocation = GetLocation(tryCatchStatement.EndLocation);
t.ProtectedBlock = ConvertBlock(tryCatchStatement.StatementBlock);
t.EnsureBlock = ConvertBlock(tryCatchStatement.FinallyBlock);
foreach (CatchClause clause in tryCatchStatement.CatchClauses) {
B.ExceptionHandler handler = new B.ExceptionHandler(GetLexicalInfo(clause));
handler.Block = ConvertBlock(clause.StatementBlock);
B.TypeReference typeRef = ConvertTypeReference(clause.TypeReference);
string name = clause.VariableName;
if (typeRef != null) {
if (name == null || name.Length == 0)
name = GenerateName();
handler.Declaration = new B.Declaration(name, typeRef);
} else {
if (name != null && name.Length > 0)
handler.Declaration = new B.Declaration(name, null);
}
t.ExceptionHandlers.Add(handler);
}
return t;
}
public object Visit(CatchClause catchClause, object data)
{
throw new ApplicationException("CatchClause visited.");
}
B.Statement GetLastStatement(B.Block block)
{
if (block == null || block.Statements.Count == 0)
return null;
return block.Statements[block.Statements.Count - 1];
}
string currentSwitchTempName;
public object Visit(SwitchStatement switchStatement, object data)
{
// We have a problem: given is still not implemented in boo.
// So here's the if / else workaround:
string oldSwitchTempName = currentSwitchTempName;
currentSwitchTempName = GenerateName();
ArrayList l = new ArrayList(3);
B.BinaryExpression init = new B.BinaryExpression(B.BinaryOperatorType.Assign,
new B.ReferenceExpression(currentSwitchTempName),
ConvertExpression(switchStatement.SwitchExpression));
l.Add(new B.ExpressionStatement(init));
B.IfStatement dummyStatement = new B.IfStatement(GetLexicalInfo(switchStatement));
B.IfStatement first = null;
B.IfStatement current = dummyStatement;
B.BreakStatement bs;
for (int i = 0; i < switchStatement.SwitchSections.Count; i++) {
current = (B.IfStatement)((INode)switchStatement.SwitchSections[i]).AcceptVisitor(this, current);
if (i == 0) {
first = current;
}
bs = GetLastStatement(current.TrueBlock) as B.BreakStatement;
if (bs != null)
bs.ReplaceBy(null);
}
bs = GetLastStatement(current.FalseBlock) as B.BreakStatement;
if (bs != null)
bs.ReplaceBy(null);
string endSwitchName = currentSwitchTempName + "_end";
first.Accept(new ReplaceBreakStatementsVisitor(endSwitchName));
FindUnneededLabelsVisitor fulv = new FindUnneededLabelsVisitor(currentSwitchTempName + "_", nameComparer);
first.Accept(fulv);
bool needsEndLabel = fulv.NeededLabels.Contains(endSwitchName);
fulv.RemoveLabels(); // remove "goto case" labels that aren't needed
currentSwitchTempName = oldSwitchTempName;
if (first == dummyStatement) {
l.AddRange(dummyStatement.FalseBlock.Statements);
} else {
l.Add(first);
}
if (needsEndLabel)
l.Add(MakeLabel(endSwitchName));
return l;
}
public object Visit(SwitchSection switchSection, object data)
{
B.IfStatement surroundingIf = (B.IfStatement)data;
bool isDefault = false;
ArrayList conditions = new ArrayList();
ArrayList labels = new ArrayList();
foreach (CaseLabel caseLabel in switchSection.SwitchLabels) {
if (caseLabel.IsDefault) {
isDefault = true;
} else {
if (caseLabel.BinaryOperatorType != BinaryOperatorType.None) {
AddError(caseLabel, "VB's Case Is currently not supported (Daniel's too lazy for VB stuff)");
} else {
B.Expression expr = ConvertExpression(caseLabel.Label);
if (expr != null) {
conditions.Add(new B.BinaryExpression(B.BinaryOperatorType.Equality,
new B.ReferenceExpression(currentSwitchTempName),
expr));
string labelName = expr.ToCodeString().GetHashCode().ToString(System.Globalization.NumberFormatInfo.InvariantInfo);
labels.Add(MakeLabel(currentSwitchTempName + "_" + labelName));
}
}
}
}
B.IfStatement s = null;
if (conditions.Count > 0) {
s = new B.IfStatement(GetLexicalInfo(switchSection));
if (surroundingIf != null) {
s.FalseBlock = surroundingIf.FalseBlock;
surroundingIf.FalseBlock = new B.Block();
surroundingIf.FalseBlock.Add(s);
}
s.TrueBlock = new B.Block();
foreach (B.Statement stmt in labels) {
s.TrueBlock.Add(stmt);
}
B.Expression combined = (B.Expression)conditions[0];
for (int i = 1; i < conditions.Count; i++) {
combined = new B.BinaryExpression(B.BinaryOperatorType.Or, combined, (B.Expression)conditions[i]);
}
s.Condition = combined;
foreach (Statement node in switchSection.Children) {
AddToBlock(node, s.TrueBlock);
}
}
if (s == null)
s = surroundingIf;
if (isDefault) {
if (s.FalseBlock == null)
s.FalseBlock = new B.Block();
s.FalseBlock.Add(MakeLabel(currentSwitchTempName + "_default"));
foreach (Statement node in switchSection.Children) {
AddToBlock(node, s.FalseBlock);
}
}
return s;
}
public object Visit(GotoCaseStatement gotoCaseStatement, object data)
{
if (currentSwitchTempName == null) {
AddError(gotoCaseStatement, "goto case cannot be used outside switch");
return null;
}
string labelName;
if (gotoCaseStatement.IsDefaultCase) {
labelName = "default";
} else {
B.Expression expr = ConvertExpression(gotoCaseStatement.Expression);
if (expr == null) return null;
labelName = expr.ToCodeString().GetHashCode().ToString(System.Globalization.NumberFormatInfo.InvariantInfo);
}
return new B.GotoStatement(GetLexicalInfo(gotoCaseStatement),
new B.ReferenceExpression(currentSwitchTempName + "_" + labelName));
}
public object Visit(CaseLabel caseLabel, object data)
{
throw new ApplicationException("CaseLabel was visited.");
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -