public UsingStatement TransformUsings(ExpressionStatement node) { Match m1 = variableAssignPattern.Match(node); if (m1 == null) { return(null); } AstNode tryCatch = node.NextSibling; Match m2 = usingTryCatchPattern.Match(tryCatch); if (m2 == null) { return(null); } string variableName = m1.Get <IdentifierExpression>("variable").Single().Identifier; if (variableName == m2.Get <IdentifierExpression>("ident").Single().Identifier) { if (m2.Has("valueType")) { // if there's no if(x!=null), then it must be a value type ILVariable v = m1.Get("variable").Single().Annotation <ILVariable>(); if (v == null || v.Type == null || !v.Type.IsValueType) { return(null); } } node.Remove(); BlockStatement body = m2.Get <BlockStatement>("body").Single(); UsingStatement usingStatement = new UsingStatement(); usingStatement.ResourceAcquisition = node.Expression.Detach(); usingStatement.EmbeddedStatement = body.Detach(); tryCatch.ReplaceWith(usingStatement); // Move the variable declaration into the resource acquisition, if possible // This is necessary for the foreach-pattern to work on the result of the using-pattern VariableDeclarationStatement varDecl = FindVariableDeclaration(usingStatement, variableName); if (varDecl != null && varDecl.Parent is BlockStatement) { Statement declarationPoint; if (CanMoveVariableDeclarationIntoStatement(varDecl, usingStatement, out declarationPoint)) { Debug.Assert(declarationPoint == usingStatement); // Moving the variable into the UsingStatement is allowed: usingStatement.ResourceAcquisition = new VariableDeclarationStatement { Type = (AstType)varDecl.Type.Clone(), Variables = { new VariableInitializer { Name = variableName, Initializer = m1.Get <Expression>("initializer").Single().Detach() }.CopyAnnotationsFrom(usingStatement.ResourceAcquisition) } }.CopyAnnotationsFrom(node); } } return(usingStatement); } return(null); }
public DoWhileStatement TransformDoWhile(WhileStatement whileLoop) { Match m = doWhilePattern.Match(whileLoop); if (m.Success) { DoWhileStatement doLoop = new DoWhileStatement(); doLoop.Condition = new UnaryOperatorExpression(UnaryOperatorType.Not, m.Get <Expression>("condition").Single().Detach()); //doLoop.Condition.AcceptVisitor(new PushNegation(), null); BlockStatement block = (BlockStatement)whileLoop.EmbeddedStatement; block.Statements.Last().Remove(); // remove if statement doLoop.EmbeddedStatement = block.Detach(); doLoop.CopyAnnotationsFrom(whileLoop); whileLoop.ReplaceWith(doLoop); // we may have to extract variable definitions out of the loop if they were used in the condition: foreach (var varDecl in block.Statements.OfType <VariableDeclarationStatement>()) { VariableInitializer v = varDecl.Variables.Single(); if (doLoop.Condition.DescendantsAndSelf.OfType <IdentifierExpression>().Any(i => i.Identifier == v.Name)) { AssignmentExpression assign = new AssignmentExpression(new IdentifierExpression(v.Name), v.Initializer.Detach()); // move annotations from v to assign: assign.CopyAnnotationsFrom(v); v.RemoveAnnotations <object>(); // remove varDecl with assignment; and move annotations from varDecl to the ExpressionStatement: varDecl.ReplaceWith(new ExpressionStatement(assign).CopyAnnotationsFrom(varDecl)); varDecl.RemoveAnnotations <object>(); // insert the varDecl above the do-while loop: doLoop.Parent.InsertChildBefore(doLoop, varDecl, BlockStatement.StatementRole); } } return(doLoop); } return(null); }
public SwitchStatement TransformSwitchOnString(IfElseStatement node) { Match m = switchOnStringPattern.Match(node); if (!m.Success) { return(null); } // switchVar must be the same as switchExpr; or switchExpr must be an assignment and switchVar the left side of that assignment if (!m.Get("switchVar").Single().IsMatch(m.Get("switchExpr").Single())) { AssignmentExpression assign = m.Get("switchExpr").Single() as AssignmentExpression; if (!(assign != null && m.Get("switchVar").Single().IsMatch(assign.Left))) { return(null); } } FieldReference cachedDictField = m.Get <AstNode>("cachedDict").Single().Annotation <FieldReference>(); if (cachedDictField == null) { return(null); } List <Statement> dictCreation = m.Get <BlockStatement>("dictCreation").Single().Statements.ToList(); List <KeyValuePair <string, int> > dict = BuildDictionary(dictCreation); SwitchStatement sw = m.Get <SwitchStatement>("switch").Single(); sw.Expression = m.Get <Expression>("switchExpr").Single().Detach(); foreach (SwitchSection section in sw.SwitchSections) { List <CaseLabel> labels = section.CaseLabels.ToList(); section.CaseLabels.Clear(); foreach (CaseLabel label in labels) { PrimitiveExpression expr = label.Expression as PrimitiveExpression; if (expr == null || !(expr.Value is int)) { continue; } int val = (int)expr.Value; foreach (var pair in dict) { if (pair.Value == val) { section.CaseLabels.Add(new CaseLabel { Expression = new PrimitiveExpression(pair.Key) }); } } } } if (m.Has("nullStmt")) { SwitchSection section = new SwitchSection(); section.CaseLabels.Add(new CaseLabel { Expression = new NullReferenceExpression() }); BlockStatement block = m.Get <BlockStatement>("nullStmt").Single(); block.Statements.Add(new BreakStatement()); section.Statements.Add(block.Detach()); sw.SwitchSections.Add(section); } else if (m.Has("nonNullDefaultStmt")) { sw.SwitchSections.Add( new SwitchSection { CaseLabels = { new CaseLabel { Expression = new NullReferenceExpression() } }, Statements = { new BlockStatement { new BreakStatement() } } }); } if (m.Has("nonNullDefaultStmt")) { SwitchSection section = new SwitchSection(); section.CaseLabels.Add(new CaseLabel()); BlockStatement block = new BlockStatement(); block.Statements.AddRange(m.Get <Statement>("nonNullDefaultStmt").Select(s => s.Detach())); block.Add(new BreakStatement()); section.Statements.Add(block); sw.SwitchSections.Add(section); } node.ReplaceWith(sw); return(sw); }