public override object VisitBlockStatement(BlockStatement blockStatement, object data) { Push(); object result = base.VisitBlockStatement(blockStatement, data); Pop(); return result; }
private SmallBasicSimpleName(BlockStatement containingBlock, SmallBasicSimpleName template) : base(containingBlock, template) { if (template.rootClass != null) this.rootClass = (RootClassDeclaration)template.rootClass.MakeShallowCopyFor(containingBlock.ContainingNamespaceDeclaration); if (template.expressionToInferTargetTypeFrom != null) this.expressionToInferTargetTypeFrom = template.expressionToInferTargetTypeFrom.MakeCopyFor(containingBlock); }
void VisitBlockWithoutFixingBraces(BlockStatement blockStatement, bool indent) { if (indent) { curIndent.Push(IndentType.Block); } VisitChildrenToFormat (blockStatement, child => { if (child.Role == Roles.LBrace || child.Role == Roles.RBrace) { return; } if (child is Statement) { FixStatementIndentation(child.StartLocation); child.AcceptVisitor(this); } else if (child is Comment) { child.AcceptVisitor(this); } else if (child is NewLineNode) { // ignore } else { // pre processor directives at line start, if they are there. if (child.StartLocation.Column > 1) FixStatementIndentation(child.StartLocation); } }); if (indent) { curIndent.Pop (); } }
public virtual void Visit(BlockStatement blockStatement) { foreach (var xStatement in blockStatement.Statements) { xStatement.Dispatch(this); } }
CodeAction ActionFromUsingStatement(RefactoringContext context) { var initializer = context.GetNode<VariableInitializer>(); if (initializer == null) return null; var initializerRR = context.Resolve(initializer) as LocalResolveResult; if (initializerRR == null) return null; var elementType = GetElementType(initializerRR, context); if (elementType == null) return null; var usingStatement = initializer.Parent.Parent as UsingStatement; if (usingStatement == null) return null; return new CodeAction(context.TranslateString("Iterate via foreach"), script => { var iterator = MakeForeach(new IdentifierExpression(initializer.Name), elementType, context); if (usingStatement.EmbeddedStatement is EmptyStatement) { var blockStatement = new BlockStatement(); blockStatement.Statements.Add(iterator); script.Replace(usingStatement.EmbeddedStatement, blockStatement); script.FormatText(blockStatement); } else if (usingStatement.EmbeddedStatement is BlockStatement) { var anchorNode = usingStatement.EmbeddedStatement.FirstChild; script.InsertAfter(anchorNode, iterator); script.FormatText(usingStatement.EmbeddedStatement); } }); }
public override void VisitBlockStatement(BlockStatement blockStatement) { base.VisitBlockStatement (blockStatement); List<Statement> statements = new List<Statement>(); foreach (Statement statement in blockStatement.Statements) { bool loop = GetIsLoopStatement (statement); if (loop) { int nodeId = this.blockIds.Dequeue(); this.lineMap[nodeId] = statement.StartLocation.Line; } if (this.loopLevel > 0) { if (statement is ContinueStatement || statement is BreakStatement) this.id++; } statements.Add (statement.Clone()); if (loop) this.id++; } blockStatement.Statements.Clear(); blockStatement.Statements.AddRange (statements); }
/// <summary> /// Initializes a new instance of the CheckedStatement class. /// </summary> /// <param name="tokens"> /// The list of tokens that form the statement. /// </param> /// <param name="embeddedStatement"> /// The block statement embedded within this checked statement, if any. /// </param> internal CheckedStatement(CsTokenList tokens, BlockStatement embeddedStatement) : base(StatementType.Checked, tokens) { Param.AssertNotNull(tokens, "tokens"); Param.AssertNotNull(embeddedStatement, "embeddedStatement"); this.embeddedStatement = embeddedStatement; this.AddStatement(embeddedStatement); }
public override void VisitBlockStatement(BlockStatement node) { VisitChildren(node); var statements = node.Statements; for (AstNode child = node.FirstChild, next = null; child != null; child = next) { next = child.NextSibling; MangleStatement(statements, child); } }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="parameters">The metadata of the parameters declared by the method.</param> /// <param name="localVariables">The metadata of the local variables declared by the method.</param> /// <param name="body">The block statement representing the method's body.</param> public MethodBodyMetadata(IEnumerable<VariableMetadata> parameters, IEnumerable<VariableMetadata> localVariables, BlockStatement body) { Requires.NotNull(parameters, () => parameters); Requires.NotNull(localVariables, () => localVariables); Requires.NotNull(body, () => body); Parameters = parameters; LocalVariables = localVariables; Body = body; }
Ast.BlockStatement TransformBlock(ILBlock block) { Ast.BlockStatement astBlock = new BlockStatement(); if (block != null) { foreach(ILNode node in block.GetChildren()) { astBlock.AddRange(TransformNode(node)); } } return astBlock; }
public void TryFinally() { BlockStatement block = new BlockStatement { new TryCatchStatement { TryBlock = new BlockStatement { new GotoStatement("LABEL"), new AssignmentExpression(new IdentifierExpression("i"), new PrimitiveExpression(1)) }, CatchClauses = { new CatchClause { Body = new BlockStatement { new AssignmentExpression(new IdentifierExpression("i"), new PrimitiveExpression(3)) } } }, FinallyBlock = new BlockStatement { new AssignmentExpression(new IdentifierExpression("j"), new PrimitiveExpression(5)) } }, new LabelStatement { Label = "LABEL" }, new EmptyStatement() }; TryCatchStatement tryCatchStatement = (TryCatchStatement)block.Statements.First(); Statement stmt1 = tryCatchStatement.TryBlock.Statements.ElementAt(1); Statement stmt3 = tryCatchStatement.CatchClauses.Single().Body.Statements.Single(); Statement stmt5 = tryCatchStatement.FinallyBlock.Statements.Single(); LabelStatement label = (LabelStatement)block.Statements.ElementAt(1); DefiniteAssignmentAnalysis da = CreateDefiniteAssignmentAnalysis(block); da.Analyze("i"); Assert.AreEqual(0, da.UnassignedVariableUses.Count); Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(tryCatchStatement)); Assert.AreEqual(DefiniteAssignmentStatus.CodeUnreachable, da.GetStatusBefore(stmt1)); Assert.AreEqual(DefiniteAssignmentStatus.CodeUnreachable, da.GetStatusAfter(stmt1)); Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(stmt3)); Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(stmt3)); Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(stmt5)); Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusAfter(stmt5)); Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(tryCatchStatement)); Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusBefore(label)); Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusAfter(label)); da.Analyze("j"); Assert.AreEqual(0, da.UnassignedVariableUses.Count); Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(tryCatchStatement)); Assert.AreEqual(DefiniteAssignmentStatus.CodeUnreachable, da.GetStatusBefore(stmt1)); Assert.AreEqual(DefiniteAssignmentStatus.CodeUnreachable, da.GetStatusAfter(stmt1)); Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(stmt3)); Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusAfter(stmt3)); Assert.AreEqual(DefiniteAssignmentStatus.PotentiallyAssigned, da.GetStatusBefore(stmt5)); Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(stmt5)); Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(tryCatchStatement)); Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusBefore(label)); Assert.AreEqual(DefiniteAssignmentStatus.DefinitelyAssigned, da.GetStatusAfter(label)); }
bool IsNotImplemented(RefactoringContext context, BlockStatement body) { if (body.IsNull) return true; if (body.Statements.Count == 1) { var throwStmt = body.Statements.First () as ThrowStatement; if (throwStmt != null) { return context.Resolve (throwStmt.Expression).Type.FullName == "System.NotImplementedException"; } } return false; }
/// <summary> /// Initializes a new instance of the FinallyStatement class. /// </summary> /// <param name="tokens"> /// The list of tokens that form the statement. /// </param> /// <param name="tryStatement"> /// The try-statement that this finally-statement is embedded to. /// </param> /// <param name="embeddedStatement"> /// The statement embedded within the finally-statement. /// </param> internal FinallyStatement(CsTokenList tokens, TryStatement tryStatement, BlockStatement embeddedStatement) : base(StatementType.Finally, tokens) { Param.AssertNotNull(tokens, "tokens"); Param.AssertNotNull(tryStatement, "tryStatement"); Param.AssertNotNull(embeddedStatement, "embeddedStatement"); this.tryStatement = tryStatement; this.embeddedStatement = embeddedStatement; this.AddStatement(embeddedStatement); }
Ast.BlockStatement TransformBlock(ILBlock block) { Ast.BlockStatement astBlock = new BlockStatement(); if (block != null) { if (block.EntryGoto != null) astBlock.Add((Statement)TransformExpression(block.EntryGoto)); foreach(ILNode node in block.Body) { astBlock.AddRange(TransformNode(node)); } } return astBlock; }
public GlslVisitor(BlockStatement block, CustomAttribute attr, DecompilerContext ctx) : this() { _attr = attr; var trans1 = new ReplaceMethodCallsWithOperators(ctx); var trans2 = new RenameLocals(); ((IAstTransform)trans1).Run(block); trans2.Run(block); Result = block.AcceptVisitor(this, 0).ToString(); Result += Environment.NewLine; }
static BlockStatement ReplaceJump(JumpStatement jump, BlockStatement block) { if (jump.StartOffset < block.StartOffset) throw new ArgumentOutOfRangeException("jump", "jump should be inside the given block"); if (jump.JumpOffset > block.EndOffset) throw new ArgumentOutOfRangeException("jump", "jump should be inside the given block"); var newBlock = new BlockStatement(); var ifStatement = new IfStatement(Not(jump.Condition), new BlockStatement()){ StartOffset = jump.StartOffset, EndOffset = jump.JumpOffset }; var inside = false; foreach (var statement in block) { if (statement is IfStatement && statement.Contains(jump.StartOffset.Value) && statement.EndOffset >= jump.JumpOffset) { var ifStatement2 = (IfStatement)statement; var b2 = ReplaceJump(jump, (BlockStatement)ifStatement2.TrueStatement); var newIfStatement2 = new IfStatement(ifStatement2.Condition, new BlockStatement()){ StartOffset = ifStatement2.StartOffset, EndOffset = ifStatement2.EndOffset }; ((BlockStatement)newIfStatement2.TrueStatement).AddStatements((IEnumerable<Statement>)b2); newBlock.AddStatement(newIfStatement2); } else if (statement.StartOffset == jump.StartOffset) { inside = true; } else if (statement.StartOffset == jump.JumpOffset) { if (ifStatement == null) throw new InvalidOperationException("ifStatement can't be null"); newBlock.AddStatement(ifStatement); newBlock.AddStatement(statement); ifStatement = null; inside = false; } else if (inside) { ((BlockStatement)ifStatement.TrueStatement).AddStatement(statement); } else { var lastStatement = newBlock.LastOrDefault(); if (lastStatement != null && lastStatement.EndOffset > statement.StartOffset) { throw new NotSupportedException("invalid Statement"); } newBlock.AddStatement(statement); } } return newBlock; }
public Block(IEmitter emitter, BlockStatement blockStatement) : base(emitter, blockStatement) { this.Emitter = emitter; this.BlockStatement = blockStatement; if (this.Emitter.IgnoreBlock == blockStatement) { this.AsyncNoBraces = true; } if (this.Emitter.NoBraceBlock == blockStatement) { this.NoBraces = true; } }
public override void VisitBlockStatement(BlockStatement blockStatement) { base.VisitBlockStatement(blockStatement); if (blockStatement.Statements.Count == 1) { try { blockStatement.ReplaceWith(blockStatement.Statements.ElementAt(0)); } catch (ArgumentException) { // Can't simplify this... } } }
private void WriteBlock(BlockStatement blockstatement, StringBuilder programBuilder) { foreach (Statement statement in blockstatement.StatementList) { if (statement is ReturnStatement) { WriteReturnStatement(statement as ReturnStatement, programBuilder); } else if (statement is ExpressionStatement) { WriteExpressionStatemnt(statement as ExpressionStatement, programBuilder); } else if (statement is IdDeclarationStatement) { WriteIdDeclarationStatement(statement as IdDeclarationStatement, programBuilder); } else if (statement is IfStatement) { WriteIFStatement(statement as IfStatement, programBuilder); } else if (statement is ForStatement) { WriteForStatement(statement as ForStatement, programBuilder); } else if (statement is WhileStatement) { WriteWhileStatement(statement as WhileStatement, programBuilder); } else if (statement is DoStatement) { WriteDoStatement(statement as DoStatement, programBuilder); } else if (statement is SwitchStatement) { WriteSwitchStatement(statement as SwitchStatement, programBuilder); } else if (statement is BreakStatement) { WriteBreakStatement(statement as BreakStatement, programBuilder); } } }
protected virtual void FixMethodParameters(AstNodeCollection<ParameterDeclaration> parameters, BlockStatement body) { /*if (parameters.Count == 0) { return; } foreach (var p in parameters) { string newName = Emitter.FIX_ARGUMENT_NAME + p.Name; string oldName = p.Name; VariableDeclarationStatement varState = new VariableDeclarationStatement(p.Type.Clone(), oldName, new CastExpression(p.Type.Clone(), new IdentifierExpression(newName))); p.Name = newName; body.InsertChildBefore(body.FirstChild, varState, new Role<VariableDeclarationStatement>("Statement")); }*/ }
static BlockStatement ReplaceJump(JumpStatement jump, BlockStatement block) { if (jump.StartOffset < block.StartOffset) throw new ArgumentOutOfRangeException("jump", "jump should be inside the given block"); if (jump.JumpOffset > block.EndOffset) throw new ArgumentOutOfRangeException("jump", "jump should be inside the given block"); var newBlock = new BlockStatement(); var doWhileStatement = new DoWhileStatement(jump.Condition, new BlockStatement()){ StartOffset = jump.StartOffset, EndOffset = jump.JumpOffset }; var inside = false; foreach (var statement in block) { if (statement.StartOffset == jump.JumpOffset) { ((BlockStatement)doWhileStatement.Statement).AddStatement(statement); inside = true; } else if (statement.StartOffset == jump.StartOffset) { if (doWhileStatement == null) throw new InvalidOperationException("DoWhileStatement can't be null"); newBlock.AddStatement(doWhileStatement); doWhileStatement = null; inside = false; } else if (inside) { ((BlockStatement)doWhileStatement.Statement).AddStatement(statement); } else { var lastStatement = newBlock.LastOrDefault(); if (lastStatement != null && lastStatement.EndOffset > statement.StartOffset) { throw new NotSupportedException("invalid Statement"); } newBlock.AddStatement(statement); } } return newBlock; }
/// <summary> /// Initializes a new instance of the CatchStatement class. /// </summary> /// <param name="tokens">The list of tokens that form the statement.</param> /// <param name="tryStatement">The try-statement that this catch-statement is attached to.</param> /// <param name="classExpression">The inner expression.</param> /// <param name="embeddedStatement">The statement embedded within the catch-statement.</param> /// <param name="whenStatement">The when statement.</param> internal CatchStatement(CsTokenList tokens, TryStatement tryStatement, Expression classExpression, BlockStatement embeddedStatement, WhenStatement whenStatement) : base(StatementType.Catch, tokens) { Param.AssertNotNull(tokens, "tokens"); Param.AssertNotNull(tryStatement, "tryStatement"); Param.Ignore(classExpression); Param.AssertNotNull(embeddedStatement, "embeddedStatement"); Param.Ignore(whenStatement); // When statement can be null and not found for a try catch. this.tryStatement = tryStatement; this.catchExpression = classExpression; this.embeddedStatement = embeddedStatement; this.whenStatement = whenStatement; if (classExpression != null) { this.AddExpression(classExpression); if (classExpression != null) { if (classExpression.ExpressionType == ExpressionType.Literal) { this.classType = ((LiteralExpression)classExpression).Token as TypeToken; } else if (classExpression.ExpressionType == ExpressionType.VariableDeclaration) { VariableDeclarationExpression variableDeclaration = (VariableDeclarationExpression)classExpression; this.classType = variableDeclaration.Type; foreach (VariableDeclaratorExpression declarator in variableDeclaration.Declarators) { this.identifier = declarator.Identifier; break; } } } } this.AddStatement(embeddedStatement); }
public override IEnumerable<CodeAction> GetActions (RefactoringContext context) { // lambda var lambda = context.GetNode<LambdaExpression> (); if (lambda != null && lambda.ArrowToken.Contains(context.Location)) { if (ContainsLocalReferences (context, lambda, lambda.Body)) yield break; bool noReturn = false; BlockStatement body; if (lambda.Body is BlockStatement) { body = (BlockStatement)lambda.Body.Clone (); } else { if (!(lambda.Body is Expression)) yield break; body = new BlockStatement (); var type = LambdaHelper.GetLambdaReturnType (context, lambda); if (type == null || type.ReflectionName == "System.Void") { noReturn = true; body.Add ((Expression)lambda.Body.Clone ()); } else { body.Add (new ReturnStatement ((Expression)lambda.Body.Clone ())); } } var method = GetMethod (context, (LambdaResolveResult)context.Resolve (lambda), body, noReturn); yield return GetAction (context, lambda, method); } // anonymous method var anonymousMethod = context.GetNode<AnonymousMethodExpression> (); if (anonymousMethod != null && anonymousMethod.DelegateToken.Contains(context.Location)) { if (ContainsLocalReferences (context, anonymousMethod, anonymousMethod.Body)) yield break; var method = GetMethod (context, (LambdaResolveResult)context.Resolve (anonymousMethod), (BlockStatement)anonymousMethod.Body.Clone ()); yield return GetAction (context, anonymousMethod, method); } }
void FindIssuesInNode(AstNode anchor, BlockStatement body, string accessorName = "setter") { if (!IsEligible(body)) return; var localResolveResult = ctx.GetResolverStateBefore(body) .LookupSimpleNameOrTypeName("value", new List<IType>(), NameLookupMode.Expression) as LocalResolveResult; if (localResolveResult == null) return; bool referenceFound = false; foreach (var result in ctx.FindReferences (body, localResolveResult.Variable)) { var node = result.Node; if (node.StartLocation >= body.StartLocation && node.EndLocation <= body.EndLocation) { referenceFound = true; break; } } if(!referenceFound) AddIssue(anchor, ctx.TranslateString("The " + accessorName + " does not use the 'value' parameter")); }
/// <summary> /// Parser for BlockStatement /// </summary> /// <returns>Parsed BlockStatement</returns> public BlockStatement ParseBlockStatement() { BlockStatement blockStatement = new BlockStatement(); //Skip { token NextToken("{", "{ statements* }", '{'); //Parse statements while (TokenStream.HasNext()) { if (TokenStream.Peek(1).GetValue().ToString() == "}") { //End of blockstatement break; } blockStatement.AddStatement(ParseStatement()); } //Skip } token NextToken("}", "{ statements* }", '}'); return blockStatement; }
public override BlockStatement Process(DecompilationContext context, BlockStatement block) { this.context = context; dummyVar0 = this.suggestedNames.Add(this.GetMethodName(context.get_MethodContext().get_Method())); return(this.Process(context, block)); }
public static InvocationExpression add_Invocation(this BlockStatement blockStatement, string methodName) { return(blockStatement.add_Invocation("", methodName)); }
void CollectIssues(AstNode variableDecl, BlockStatement rootStatement, LocalResolveResult resolveResult) { if (rootStatement == null || resolveResult == null) { return; } var references = new HashSet <AstNode>(); var refStatements = new HashSet <Statement>(); var usedInLambda = false; var results = ctx.FindReferences(rootStatement, resolveResult.Variable); foreach (var result in results) { var node = result.Node; if (node == variableDecl) { continue; } var parent = node.Parent; while (!(parent == null || parent is Statement || parent is LambdaExpression || parent is QueryExpression)) { parent = parent.Parent; } if (parent == null) { continue; } var statement = parent as Statement; if (statement != null) { references.Add(node); refStatements.Add(statement); } while (parent != null && parent != rootStatement) { if (parent is LambdaExpression || parent is AnonymousMethodExpression || parent is QueryExpression) { usedInLambda = true; break; } parent = parent.Parent; } if (usedInLambda) { break; } } // stop analyzing if the variable is used in any lambda expression or anonymous method if (usedInLambda) { return; } var startNode = new VariableReferenceGraphBuilder(ctx).Build(rootStatement, references, refStatements, ctx); var variableInitializer = variableDecl as VariableInitializer; if (variableInitializer != null && !variableInitializer.Initializer.IsNull) { startNode.References.Insert(0, variableInitializer); } ProcessNodes(startNode); }
public override object VisitBlockStatement(BlockStatement blockStatement, object data) { int numberOfVariablesOutsideBlock = currentlyUsedVariableNames.Count; base.VisitBlockStatement(blockStatement, data); foreach (ExpressionStatement stmt in blockStatement.Statements.OfType <ExpressionStatement>().ToArray()) { Match displayClassAssignmentMatch = displayClassAssignmentPattern.Match(stmt); if (!displayClassAssignmentMatch.Success) { continue; } ILVariable variable = displayClassAssignmentMatch.Get <AstNode>("variable").Single().Annotation <ILVariable>(); if (variable == null) { continue; } TypeDefinition type = variable.Type.ResolveWithinSameModule(); if (!IsPotentialClosure(context, type)) { continue; } if (displayClassAssignmentMatch.Get <AstType>("type").Single().Annotation <TypeReference>().ResolveWithinSameModule() != type) { continue; } // Looks like we found a display class creation. Now let's verify that the variable is used only for field accesses: bool ok = true; foreach (var identExpr in blockStatement.Descendants.OfType <IdentifierExpression>()) { if (identExpr.Identifier == variable.Name && identExpr != displayClassAssignmentMatch.Get("variable").Single()) { if (!(identExpr.Parent is MemberReferenceExpression && identExpr.Parent.Annotation <FieldReference>() != null)) { ok = false; } } } if (!ok) { continue; } Dictionary <FieldReference, AstNode> dict = new Dictionary <FieldReference, AstNode>(); // Delete the variable declaration statement: VariableDeclarationStatement displayClassVarDecl = PatternStatementTransform.FindVariableDeclaration(stmt, variable.Name); if (displayClassVarDecl != null) { displayClassVarDecl.Remove(); } // Delete the assignment statement: AstNode cur = stmt.NextSibling; stmt.Remove(); // Delete any following statements as long as they assign parameters to the display class BlockStatement rootBlock = blockStatement.Ancestors.OfType <BlockStatement>().LastOrDefault() ?? blockStatement; List <ILVariable> parameterOccurrances = rootBlock.Descendants.OfType <IdentifierExpression>() .Select(n => n.Annotation <ILVariable>()).Where(p => p != null && p.IsParameter).ToList(); AstNode next; for (; cur != null; cur = next) { next = cur.NextSibling; // Test for the pattern: // "variableName.MemberName = right;" ExpressionStatement closureFieldAssignmentPattern = new ExpressionStatement( new AssignmentExpression( new NamedNode("left", new MemberReferenceExpression { Target = new IdentifierExpression(variable.Name) }), new AnyNode("right") ) ); Match m = closureFieldAssignmentPattern.Match(cur); if (m.Success) { FieldDefinition fieldDef = m.Get <MemberReferenceExpression>("left").Single().Annotation <FieldReference>().ResolveWithinSameModule(); AstNode right = m.Get <AstNode>("right").Single(); bool isParameter = false; bool isDisplayClassParentPointerAssignment = false; if (right is ThisReferenceExpression) { isParameter = true; } else if (right is IdentifierExpression) { // handle parameters only if the whole method contains no other occurrence except for 'right' ILVariable v = right.Annotation <ILVariable>(); isParameter = v.IsParameter && parameterOccurrances.Count(c => c == v) == 1; if (!isParameter && IsPotentialClosure(context, v.Type.ResolveWithinSameModule())) { // parent display class within the same method // (closure2.localsX = closure1;) isDisplayClassParentPointerAssignment = true; } } else if (right is MemberReferenceExpression) { // copy of parent display class reference from an outer lambda // closure2.localsX = this.localsY MemberReferenceExpression mre = m.Get <MemberReferenceExpression>("right").Single(); do { // descend into the targets of the mre as long as the field types are closures FieldDefinition fieldDef2 = mre.Annotation <FieldReference>().ResolveWithinSameModule(); if (fieldDef2 == null || !IsPotentialClosure(context, fieldDef2.FieldType.ResolveWithinSameModule())) { break; } // if we finally get to a this reference, it's copying a display class parent pointer if (mre.Target is ThisReferenceExpression) { isDisplayClassParentPointerAssignment = true; } mre = mre.Target as MemberReferenceExpression; } while (mre != null); } if (isParameter || isDisplayClassParentPointerAssignment) { dict[fieldDef] = right; cur.Remove(); } else { break; } } else { break; } } // Now create variables for all fields of the display class (except for those that we already handled as parameters) List <Tuple <AstType, string> > variablesToDeclare = new List <Tuple <AstType, string> >(); foreach (FieldDefinition field in type.Fields) { if (field.IsStatic) { continue; // skip static fields } if (dict.ContainsKey(field)) // skip field if it already was handled as parameter { continue; } EnsureVariableNameIsAvailable(blockStatement, field.Name); currentlyUsedVariableNames.Add(field.Name); variablesToDeclare.Add(Tuple.Create(AstBuilder.ConvertType(field.FieldType, field), field.Name)); dict[field] = new IdentifierExpression(field.Name); } // Now figure out where the closure was accessed and use the simpler replacement expression there: foreach (var identExpr in blockStatement.Descendants.OfType <IdentifierExpression>()) { if (identExpr.Identifier == variable.Name) { MemberReferenceExpression mre = (MemberReferenceExpression)identExpr.Parent; AstNode replacement; if (dict.TryGetValue(mre.Annotation <FieldReference>().ResolveWithinSameModule(), out replacement)) { mre.ReplaceWith(replacement.Clone()); } } } // Now insert the variable declarations (we can do this after the replacements only so that the scope detection works): Statement insertionPoint = blockStatement.Statements.FirstOrDefault(); foreach (var tuple in variablesToDeclare) { var newVarDecl = new VariableDeclarationStatement(tuple.Item1, tuple.Item2); newVarDecl.Variables.Single().AddAnnotation(new CapturedVariableAnnotation()); blockStatement.Statements.InsertBefore(insertionPoint, newVarDecl); } } currentlyUsedVariableNames.RemoveRange(numberOfVariablesOutsideBlock, currentlyUsedVariableNames.Count - numberOfVariablesOutsideBlock); return(null); }
public UncheckedStatement(BlockStatement body) { AddChild(body, Roles.Body); }
public static VariableDeclaration add_Variable(this BlockStatement blockDeclaration, string name, Expression expression, string typeReference) { return(blockDeclaration.add_Variable(name, expression, new TypeReference(typeReference))); }
private void TransformToClass() { if (transformerDefinition.TransformResults == null) { throw new TransformCompilationException("Cannot compile a transformer without a transformer function"); } try { CSharpSafeName = "Transformer_" + Regex.Replace(Name, @"[^\w\d]", "_"); var type = new TypeDeclaration { Modifiers = Modifiers.Public, BaseTypes = { new SimpleType(typeof(AbstractTransformer).FullName) }, Name = CSharpSafeName, ClassType = ClassType.Class }; var body = new BlockStatement(); // this.ViewText = "96E65595-1C9E-4BFB-A0E5-80BF2D6FC185"; // Will be replaced later var viewText = new ExpressionStatement( new AssignmentExpression( new MemberReferenceExpression(new ThisReferenceExpression(), "ViewText"), AssignmentOperatorType.Assign, new StringLiteralExpression(uniqueTextToken))); body.Statements.Add(viewText); var ctor = new ConstructorDeclaration { Name = CSharpSafeName, Modifiers = Modifiers.Public, Body = body }; type.Members.Add(ctor); VariableInitializer translatorDeclaration; if (transformerDefinition.TransformResults.Trim().StartsWith("from")) { translatorDeclaration = QueryParsingUtils.GetVariableDeclarationForLinqQuery(transformerDefinition.TransformResults, requiresSelectNewAnonymousType: false); translatorDeclaration.AcceptVisitor(new TransformFromClauses(), null); } else { translatorDeclaration = QueryParsingUtils.GetVariableDeclarationForLinqMethods(transformerDefinition.TransformResults, requiresSelectNewAnonymousType: false); } translatorDeclaration.AcceptVisitor(new ThrowOnInvalidMethodCallsForTransformResults(), null); // this.Translator = (results) => from doc in results ...; ctor.Body.Statements.Add(new ExpressionStatement( new AssignmentExpression( new MemberReferenceExpression(new ThisReferenceExpression(), "TransformResultsDefinition"), AssignmentOperatorType.Assign, new LambdaExpression { Parameters = { new ParameterDeclaration(null, "results") }, Body = translatorDeclaration.Initializer.Clone() }))); CompiledQueryText = QueryParsingUtils.GenerateText(type, extensions); var sb = new StringBuilder("@\""); sb.AppendLine(transformerDefinition.TransformResults.Replace("\"", "\"\"")); sb.Append("\""); CompiledQueryText = CompiledQueryText.Replace('"' + uniqueTextToken + '"', sb.ToString()); } catch (Exception ex) { throw new TransformCompilationException(ex.Message, ex); } }
/// <nodoc /> public virtual void Visit(BlockStatement blockStatement) { }
public virtual object VisitBlockStatement(BlockStatement blockStatement, object data) { throw new global::System.NotImplementedException("BlockStatement"); }
public override void VisitBlockStatement(BlockStatement blockStatement) { blockDepth++; base.VisitBlockStatement(blockStatement); blockDepth--; }
public override void VisitBlockStatement (BlockStatement blockStatement) { if (blockStatement.Statements.Count == 1 && blockStatement.Statements.First () is ThrowStatement) Throws = true; }
void WriteMethodBody(BlockStatement body) { if (body.IsNull) { Semicolon(); } else { VisitBlockStatement(body); } }
Result GetResultFromBlock(BlockStatement block) { // For a block, we are tracking 4 possibilities: // a) context is checked, no unchecked block open Cost costCheckedContext = new Cost(0, 0); InsertedNode nodesCheckedContext = null; // b) context is checked, an unchecked block is open Cost costCheckedContextUncheckedBlockOpen = Cost.Infinite; InsertedNode nodesCheckedContextUncheckedBlockOpen = null; Statement uncheckedBlockStart = null; // c) context is unchecked, no checked block open Cost costUncheckedContext = new Cost(0, 0); InsertedNode nodesUncheckedContext = null; // d) context is unchecked, a checked block is open Cost costUncheckedContextCheckedBlockOpen = Cost.Infinite; InsertedNode nodesUncheckedContextCheckedBlockOpen = null; Statement checkedBlockStart = null; Statement statement = block.Statements.FirstOrDefault(); while (true) { // Blocks can be closed 'for free'. We use '<=' so that blocks are closed as late as possible (goal 4b) if (costCheckedContextUncheckedBlockOpen <= costCheckedContext) { costCheckedContext = costCheckedContextUncheckedBlockOpen; nodesCheckedContext = nodesCheckedContextUncheckedBlockOpen + new InsertedBlock(uncheckedBlockStart, statement, false); } if (costUncheckedContextCheckedBlockOpen <= costUncheckedContext) { costUncheckedContext = costUncheckedContextCheckedBlockOpen; nodesUncheckedContext = nodesUncheckedContextCheckedBlockOpen + new InsertedBlock(checkedBlockStart, statement, true); } if (statement == null) { break; } // Now try opening blocks. We use '<=' so that blocks are opened as late as possible. (goal 4a) if (costCheckedContext + new Cost(1, 0) <= costCheckedContextUncheckedBlockOpen) { costCheckedContextUncheckedBlockOpen = costCheckedContext + new Cost(1, 0); nodesCheckedContextUncheckedBlockOpen = nodesCheckedContext; uncheckedBlockStart = statement; } if (costUncheckedContext + new Cost(1, 0) <= costUncheckedContextCheckedBlockOpen) { costUncheckedContextCheckedBlockOpen = costUncheckedContext + new Cost(1, 0); nodesUncheckedContextCheckedBlockOpen = nodesUncheckedContext; checkedBlockStart = statement; } // Now handle the statement Result stmtResult = GetResult(statement); costCheckedContext += stmtResult.CostInCheckedContext; nodesCheckedContext += stmtResult.NodesToInsertInCheckedContext; costCheckedContextUncheckedBlockOpen += stmtResult.CostInUncheckedContext; nodesCheckedContextUncheckedBlockOpen += stmtResult.NodesToInsertInUncheckedContext; costUncheckedContext += stmtResult.CostInUncheckedContext; nodesUncheckedContext += stmtResult.NodesToInsertInUncheckedContext; costUncheckedContextCheckedBlockOpen += stmtResult.CostInCheckedContext; nodesUncheckedContextCheckedBlockOpen += stmtResult.NodesToInsertInCheckedContext; if (statement is LabelStatement || statement is LocalFunctionDeclarationStatement) { // We can't move labels into blocks because that might cause goto-statements // to be unable to jump to the labels. // Also, we can't move local functions into blocks, because that might cause // them to become out of scope from the call-sites. costCheckedContextUncheckedBlockOpen = Cost.Infinite; costUncheckedContextCheckedBlockOpen = Cost.Infinite; } statement = statement.GetNextStatement(); } return(new Result { CostInCheckedContext = costCheckedContext, NodesToInsertInCheckedContext = nodesCheckedContext, CostInUncheckedContext = costUncheckedContext, NodesToInsertInUncheckedContext = nodesUncheckedContext }); }
public override void VisitBlockStatement(BlockStatement blockStatement) { //We never need to visit the children of block statements }
public BlockStatement Process(DecompilationContext context, BlockStatement body) { return((BlockStatement)VisitBlockStatement(body)); }
public object VisitBlockStatement(BlockStatement statement) { ExecuteBlock(statement.Statements, new Environment(environment)); return(null); }
Statement TransformToForeach(UsingInstruction inst, out Expression resource) { // Check if the using resource matches the GetEnumerator pattern. resource = exprBuilder.Translate(inst.ResourceExpression); var m = getEnumeratorPattern.Match(resource); // The using body must be a BlockContainer. if (!(inst.Body is BlockContainer container) || !m.Success) { return(null); } // The using-variable is the enumerator. var enumeratorVar = inst.Variable; // If there's another BlockContainer nested in this container and it only has one child block, unwrap it. // If there's an extra leave inside the block, extract it into optionalReturnAfterLoop. var loopContainer = UnwrapNestedContainerIfPossible(container, out var optionalReturnAfterLoop); // Detect whether we're dealing with a while loop with multiple embedded statements. var loop = DetectedLoop.DetectLoop(loopContainer); if (loop.Kind != LoopKind.While || !(loop.Body is Block body)) { return(null); } // The loop condition must be a call to enumerator.MoveNext() var condition = exprBuilder.TranslateCondition(loop.Conditions.Single()); var m2 = moveNextConditionPattern.Match(condition.Expression); if (!m2.Success) { return(null); } // Check enumerator variable references. var enumeratorVar2 = m2.Get <IdentifierExpression>("enumerator").Single().GetILVariable(); if (enumeratorVar2 != enumeratorVar) { return(null); } // Detect which foreach-variable transformation is necessary/possible. var transformation = DetectGetCurrentTransformation(container, body, enumeratorVar, condition.ILInstructions.Single(), out var singleGetter, out var foreachVariable); if (transformation == RequiredGetCurrentTransformation.NoForeach) { return(null); } // The existing foreach variable, if found, can only be used in the loop container. if (foreachVariable != null && !(foreachVariable.CaptureScope == null || foreachVariable.CaptureScope == loopContainer)) { return(null); } // Extract in-expression var collectionExpr = m.Get <Expression>("collection").Single(); // Special case: foreach (var item in this) is decompiled as foreach (var item in base) // but a base reference is not valid in this context. if (collectionExpr is BaseReferenceExpression) { collectionExpr = new ThisReferenceExpression().CopyAnnotationsFrom(collectionExpr); } // Handle explicit casts: // This is the case if an explicit type different from the collection-item-type was used. // For example: foreach (ClassA item in nonGenericEnumerable) var type = singleGetter.Method.ReturnType; ILInstruction instToReplace = singleGetter; switch (instToReplace.Parent) { case CastClass cc: type = cc.Type; instToReplace = cc; break; case UnboxAny ua: type = ua.Type; instToReplace = ua; break; } // Handle the required foreach-variable transformation: switch (transformation) { case RequiredGetCurrentTransformation.UseExistingVariable: foreachVariable.Type = type; foreachVariable.Kind = VariableKind.ForeachLocal; foreachVariable.Name = AssignVariableNames.GenerateForeachVariableName(currentFunction, collectionExpr.Annotation <ILInstruction>(), foreachVariable); break; case RequiredGetCurrentTransformation.UninlineAndUseExistingVariable: // Unwrap stloc chain. var nestedStores = new Stack <ILVariable>(); var currentInst = instToReplace; // instToReplace is the innermost value of the stloc chain. while (currentInst.Parent is StLoc stloc) { // Exclude nested stores to foreachVariable // we'll insert one store at the beginning of the block. if (stloc.Variable != foreachVariable && stloc.Parent is StLoc) { nestedStores.Push(stloc.Variable); } currentInst = stloc; } // Rebuild the nested store instructions: ILInstruction reorderedStores = new LdLoc(foreachVariable); while (nestedStores.Count > 0) { reorderedStores = new StLoc(nestedStores.Pop(), reorderedStores); } currentInst.ReplaceWith(reorderedStores); body.Instructions.Insert(0, new StLoc(foreachVariable, instToReplace)); // Adjust variable type, kind and name. goto case RequiredGetCurrentTransformation.UseExistingVariable; case RequiredGetCurrentTransformation.IntroduceNewVariable: foreachVariable = currentFunction.RegisterVariable( VariableKind.ForeachLocal, type, AssignVariableNames.GenerateForeachVariableName(currentFunction, collectionExpr.Annotation <ILInstruction>()) ); instToReplace.ReplaceWith(new LdLoc(foreachVariable)); body.Instructions.Insert(0, new StLoc(foreachVariable, instToReplace)); break; } // Convert the modified body to C# AST: var whileLoop = (WhileStatement)ConvertAsBlock(container).First(); BlockStatement foreachBody = (BlockStatement)whileLoop.EmbeddedStatement.Detach(); // Remove the first statement, as it is the foreachVariable = enumerator.Current; statement. foreachBody.Statements.First().Detach(); // Construct the foreach loop. var foreachStmt = new ForeachStatement { VariableType = settings.AnonymousTypes && foreachVariable.Type.ContainsAnonymousType() ? new SimpleType("var") : exprBuilder.ConvertType(foreachVariable.Type), VariableName = foreachVariable.Name, InExpression = collectionExpr.Detach(), EmbeddedStatement = foreachBody }; // Add the variable annotation for highlighting (TokenTextWriter expects it directly on the ForeachStatement). foreachStmt.AddAnnotation(new ILVariableResolveResult(foreachVariable, foreachVariable.Type)); // If there was an optional return statement, return it as well. if (optionalReturnAfterLoop != null) { return(new BlockStatement { Statements = { foreachStmt, optionalReturnAfterLoop.AcceptVisitor(this) } }); } return(foreachStmt); }
static bool IsEmpty(BlockStatement blockStatement) { return(!blockStatement.Descendants.Any(s => s is Statement && !(s is EmptyStatement || s is BlockStatement))); }
protected override CodeAction GetAction(RefactoringContext ctx, IfElseStatement ifElseStatement) { var isExpr = ctx.GetNode <IsExpression>(); if (isExpr == null || !isExpr.IsToken.Contains(ctx.Location)) { return(null); } int foundCasts; var action = ScanIfElse(ctx, ifElseStatement, out isExpr, out foundCasts); if (action != null) { return(action); } isExpr = ctx.GetNode <IsExpression>(); var node = isExpr.Parent; while (node is ParenthesizedExpression) { node = node.Parent; } var uOp = node as UnaryOperatorExpression; if (uOp != null && uOp.Operator == UnaryOperatorType.Not) { var rr = ctx.Resolve(isExpr.Type); if (rr == null || rr.IsError || rr.Type.IsReferenceType == false) { return(null); } return(new CodeAction(ctx.TranslateString("Use 'as' and check for null"), script => { var varName = ctx.GetNameProposal(CreateMethodDeclarationAction.GuessNameFromType(rr.Type), ifElseStatement.StartLocation); var varDec = new VariableDeclarationStatement(new PrimitiveType("var"), varName, new AsExpression(isExpr.Expression.Clone(), isExpr.Type.Clone())); var binaryOperatorIdentifier = new IdentifierExpression(varName); var binaryOperatorExpression = new BinaryOperatorExpression(binaryOperatorIdentifier, BinaryOperatorType.Equality, new NullReferenceExpression()); if (IsEmbeddedStatement(ifElseStatement)) { var block = new BlockStatement(); block.Add(varDec); var newIf = (IfElseStatement)ifElseStatement.Clone(); newIf.Condition = binaryOperatorExpression; block.Add(newIf); script.Replace(ifElseStatement, block); } else { script.InsertBefore(ifElseStatement, varDec); script.Replace(uOp, binaryOperatorExpression); } }, isExpr.IsToken)); } var obj = isExpr.Expression; var castToType = isExpr.Type; var cast = new Choice { PatternHelper.OptionalParentheses(PatternHelper.OptionalParentheses(obj.Clone()).CastTo(castToType.Clone())), PatternHelper.OptionalParentheses(PatternHelper.OptionalParentheses(obj.Clone()).CastAs(castToType.Clone())) }; var rr2 = ctx.Resolve(castToType); if (rr2 == null || rr2.IsError || rr2.Type.IsReferenceType == false) { return(null); } var foundCasts2 = isExpr.GetParent <Statement>().DescendantNodesAndSelf(n => !cast.IsMatch(n)).Where(n => isExpr.StartLocation < n.StartLocation && cast.IsMatch(n)).ToList(); return(new CodeAction(ctx.TranslateString("Use 'as' and check for null"), script => { var varName = ctx.GetNameProposal(CreateMethodDeclarationAction.GuessNameFromType(rr2.Type), ifElseStatement.StartLocation); var varDec = new VariableDeclarationStatement(new PrimitiveType("var"), varName, new AsExpression(obj.Clone(), castToType.Clone())); var binaryOperatorIdentifier = new IdentifierExpression(varName); var binaryOperatorExpression = new BinaryOperatorExpression(binaryOperatorIdentifier, BinaryOperatorType.InEquality, new NullReferenceExpression()); var linkedNodes = new List <AstNode>(); linkedNodes.Add(varDec.Variables.First().NameToken); linkedNodes.Add(binaryOperatorIdentifier); if (IsEmbeddedStatement(ifElseStatement)) { var block = new BlockStatement(); block.Add(varDec); var newIf = (IfElseStatement)ifElseStatement.Clone(); newIf.Condition = binaryOperatorExpression; foreach (var node2 in newIf.DescendantNodesAndSelf(n => !cast.IsMatch(n)).Where(n => cast.IsMatch(n))) { var id = new IdentifierExpression(varName); linkedNodes.Add(id); node2.ReplaceWith(id); } block.Add(newIf); script.Replace(ifElseStatement, block); } else { script.InsertBefore(ifElseStatement, varDec); script.Replace(isExpr, binaryOperatorExpression); foreach (var c in foundCasts2) { var id = new IdentifierExpression(varName); linkedNodes.Add(id); script.Replace(c, id); } } script.Link(linkedNodes); }, isExpr.IsToken)); }
public BlockStatement Process(DecompilationContext context, BlockStatement body) { this.context = context; return((BlockStatement)this.VisitBlockStatement(body)); }
static CodeAction HandleNegatedCase(BaseRefactoringContext ctx, IfElseStatement ifElseStatement, Match match, out IsExpression isExpression, out int foundCastCount) { foundCastCount = 0; var outerIs = match.Get <Expression>("isExpression").Single(); isExpression = AlUtil.GetInnerMostExpression(outerIs) as IsExpression; var obj = AlUtil.GetInnerMostExpression(isExpression.Expression); var castToType = isExpression.Type; var cast = new Choice { PatternHelper.OptionalParentheses(PatternHelper.OptionalParentheses(obj.Clone()).CastTo(castToType.Clone())), PatternHelper.OptionalParentheses(PatternHelper.OptionalParentheses(obj.Clone()).CastAs(castToType.Clone())) }; var rr = ctx.Resolve(castToType); if (rr == null || rr.IsError || rr.Type.IsReferenceType == false) { return(null); } var foundCasts = ifElseStatement.GetParent <BlockStatement>().DescendantNodes(n => n.StartLocation >= ifElseStatement.StartLocation && !cast.IsMatch(n)).Where(n => cast.IsMatch(n)).ToList(); foundCastCount = foundCasts.Count; return(new CodeAction(ctx.TranslateString("Use 'as' and check for null"), script => { var varName = ctx.GetNameProposal(CreateMethodDeclarationAction.GuessNameFromType(rr.Type), ifElseStatement.StartLocation); var varDec = new VariableDeclarationStatement(new PrimitiveType("var"), varName, new AsExpression(obj.Clone(), castToType.Clone())); var binaryOperatorIdentifier = new IdentifierExpression(varName); var binaryOperatorExpression = new BinaryOperatorExpression(binaryOperatorIdentifier, BinaryOperatorType.Equality, new NullReferenceExpression()); var linkedNodes = new List <AstNode>(); linkedNodes.Add(varDec.Variables.First().NameToken); linkedNodes.Add(binaryOperatorIdentifier); if (IsEmbeddedStatement(ifElseStatement)) { var block = new BlockStatement(); block.Add(varDec); var newIf = (IfElseStatement)ifElseStatement.Clone(); newIf.Condition = binaryOperatorExpression; foreach (var node in newIf.DescendantNodesAndSelf(n => !cast.IsMatch(n)).Where(n => cast.IsMatch(n))) { var id = new IdentifierExpression(varName); linkedNodes.Add(id); node.ReplaceWith(id); } block.Add(newIf); script.Replace(ifElseStatement, block); } else { script.InsertBefore(ifElseStatement, varDec); script.Replace(ifElseStatement.Condition, binaryOperatorExpression); foreach (var c in foundCasts) { var id = new IdentifierExpression(varName); linkedNodes.Add(id); script.Replace(c, id); } } script.Link(linkedNodes); }, isExpression.IsToken)); }
public void Visit(BlockStatement node) { // if we got here, then the block is at the statement level, which means it's // a nested block that hasn't been optimized out. // Therefore it starts with a '{' and we don't care. }
Result GetResultFromBlock(BlockStatement block) { // For a block, we are tracking 4 possibilities: // a) context is checked, no unchecked block open Cost costCheckedContext = new Cost(0, 0); InsertedNode nodesCheckedContext = null; // b) context is checked, an unchecked block is open Cost costCheckedContextUncheckedBlockOpen = Cost.Infinite; InsertedNode nodesCheckedContextUncheckedBlockOpen = null; Statement uncheckedBlockStart = null; // c) context is unchecked, no checked block open Cost costUncheckedContext = new Cost(0, 0); InsertedNode nodesUncheckedContext = null; // d) context is unchecked, a checked block is open Cost costUncheckedContextCheckedBlockOpen = Cost.Infinite; InsertedNode nodesUncheckedContextCheckedBlockOpen = null; Statement checkedBlockStart = null; Statement statement = block.Statements.FirstOrDefault(); while (true) { // Blocks can be closed 'for free'. We use '<=' so that blocks are closed as late as possible (goal 4b) if (costCheckedContextUncheckedBlockOpen <= costCheckedContext) { costCheckedContext = costCheckedContextUncheckedBlockOpen; nodesCheckedContext = nodesCheckedContextUncheckedBlockOpen + new InsertedBlock(uncheckedBlockStart, statement, false); } if (costUncheckedContextCheckedBlockOpen <= costUncheckedContext) { costUncheckedContext = costUncheckedContextCheckedBlockOpen; nodesUncheckedContext = nodesUncheckedContextCheckedBlockOpen + new InsertedBlock(checkedBlockStart, statement, true); } if (statement == null) { break; } // Now try opening blocks. We use '<=' so that blocks are opened as late as possible. (goal 4a) if (costCheckedContext + new Cost(1, 0) <= costCheckedContextUncheckedBlockOpen) { costCheckedContextUncheckedBlockOpen = costCheckedContext + new Cost(1, 0); nodesCheckedContextUncheckedBlockOpen = nodesCheckedContext; uncheckedBlockStart = statement; } if (costUncheckedContext + new Cost(1, 0) <= costUncheckedContextCheckedBlockOpen) { costUncheckedContextCheckedBlockOpen = costUncheckedContext + new Cost(1, 0); nodesUncheckedContextCheckedBlockOpen = nodesUncheckedContext; checkedBlockStart = statement; } // Now handle the statement Result stmtResult = GetResult(statement); costCheckedContext += stmtResult.CostInCheckedContext; nodesCheckedContext += stmtResult.NodesToInsertInCheckedContext; costCheckedContextUncheckedBlockOpen += stmtResult.CostInUncheckedContext; nodesCheckedContextUncheckedBlockOpen += stmtResult.NodesToInsertInUncheckedContext; costUncheckedContext += stmtResult.CostInUncheckedContext; nodesUncheckedContext += stmtResult.NodesToInsertInUncheckedContext; costUncheckedContextCheckedBlockOpen += stmtResult.CostInCheckedContext; nodesUncheckedContextCheckedBlockOpen += stmtResult.NodesToInsertInCheckedContext; statement = statement.GetNextStatement(); } return(new Result { CostInCheckedContext = costCheckedContext, NodesToInsertInCheckedContext = nodesCheckedContext, CostInUncheckedContext = costUncheckedContext, NodesToInsertInUncheckedContext = nodesUncheckedContext }); }
/// <summary> /// Makes sure that the PHP-visible type derives from PhpObject and adds appropriate constructors. /// </summary> private void FixInheritance(TypeDeclaration type, TypeDeclaration outType) { // make the type inherit from PhpObject bool has_base = false; foreach (TypeReference base_type in type.BaseTypes) { // TODO: base this decision on an attribute? if (!base_type.Type.StartsWith("I") && !base_type.Type.StartsWith("SPL.")) { has_base = true; break; } } if (!has_base) { outType.BaseTypes.Add(new TypeReference("PhpObject")); } // add the necessary constructors bool has_short_ctor = false; bool has_long_ctor = false; BlockStatement default_ctor_body = null; foreach (INode member in type.Children) { ConstructorDeclaration ctor = member as ConstructorDeclaration; if (ctor != null) { if (ctor.Parameters.Count == 2 && Utility.IsType(ctor.Parameters[0].TypeReference, "PHP.Core.ScriptContext")) { if (Utility.IsType(ctor.Parameters[1].TypeReference, "System.Boolean")) { has_short_ctor = true; } if (Utility.IsType(ctor.Parameters[1].TypeReference, "PHP.Core.Reflection.DTypeDesc")) { has_long_ctor = true; } } else if (ctor.Parameters.Count == 0) { default_ctor_body = ctor.Body; } } } if (!has_short_ctor) { ConstructorDeclaration ctor = new ConstructorDeclaration(type.Name, Modifier.Public, new List <ParameterDeclarationExpression>(), null); ctor.Parameters.Add(new ParameterDeclarationExpression(new TypeReference("ScriptContext"), "context")); ctor.Parameters.Add(new ParameterDeclarationExpression(new TypeReference("Boolean"), "newInstance")); ctor.ConstructorInitializer = new ConstructorInitializer(); ctor.ConstructorInitializer.ConstructorInitializerType = ConstructorInitializerType.Base; ctor.ConstructorInitializer.Arguments.Add(new IdentifierExpression("context")); ctor.ConstructorInitializer.Arguments.Add(new IdentifierExpression("newInstance")); if (default_ctor_body == null) { ctor.Body = new BlockStatement(); } else { ctor.Body = default_ctor_body; } Utility.MakeNonBrowsable(ctor); outType.AddChild(ctor); } if (!has_long_ctor) { ConstructorDeclaration ctor = new ConstructorDeclaration(type.Name, Modifier.Public, new List <ParameterDeclarationExpression>(), null); ctor.Parameters.Add(new ParameterDeclarationExpression(new TypeReference("ScriptContext"), "context")); ctor.Parameters.Add(new ParameterDeclarationExpression(new TypeReference("DTypeDesc"), "caller")); IdentifierExpression context_param = new IdentifierExpression("context"); IdentifierExpression caller_param = new IdentifierExpression("caller"); ctor.ConstructorInitializer = new ConstructorInitializer(); ctor.ConstructorInitializer.ConstructorInitializerType = ConstructorInitializerType.This; ctor.ConstructorInitializer.Arguments.Add(context_param); ctor.ConstructorInitializer.Arguments.Add(new PrimitiveExpression(true, String.Empty)); InvocationExpression invocation = new InvocationExpression( new FieldReferenceExpression(new ThisReferenceExpression(), "InvokeConstructor"), new ArrayList()); invocation.Arguments.Add(context_param); invocation.Arguments.Add(caller_param); ctor.Body = new BlockStatement(); ctor.Body.AddChild(new StatementExpression(invocation)); Utility.MakeNonBrowsable(ctor); outType.AddChild(ctor); } }
public override void VisitBlockStatement(BlockStatement node) { WriteBlock(() => Visit(node.Statements)); }
public override object VisitBlockStatement(BlockStatement blockStatement, object data) { return(base.VisitBlockStatement(blockStatement, data)); }
public BlockStatement Process(DecompilationContext context, BlockStatement block) { this.typeSystem = context.get_MethodContext().get_Method().get_Module().get_TypeSystem(); this.context = context; return((BlockStatement)this.VisitBlockStatement(block)); }
bool HandleAnonymousMethod(ObjectCreateExpression objectCreateExpression, Expression target, MethodReference methodRef) { if (!context.Settings.AnonymousMethods) { return(false); // anonymous method decompilation is disabled } // Anonymous methods are defined in the same assembly MethodDefinition method = methodRef.ResolveWithinSameModule(); if (!IsAnonymousMethod(context, method)) { return(false); } // Create AnonymousMethodExpression and prepare parameters AnonymousMethodExpression ame = new AnonymousMethodExpression(); ame.Parameters.AddRange(AstBuilder.MakeParameters(method.Parameters)); ame.HasParameterList = true; // Decompile the anonymous method: DecompilerContext subContext = context.Clone(); subContext.CurrentMethod = method; BlockStatement body = AstMethodBodyBuilder.CreateMethodBody(method, subContext, ame.Parameters); TransformationPipeline.RunTransformationsUntil(body, v => v is DelegateConstruction, subContext); body.AcceptVisitor(this, null); bool isLambda = false; if (ame.Parameters.All(p => p.ParameterModifier == ParameterModifier.None)) { isLambda = (body.Statements.Count == 1 && body.Statements.Single() is ReturnStatement); } // Remove the parameter list from an AnonymousMethodExpression if the original method had no names, // and the parameters are not used in the method body if (!isLambda && method.Parameters.All(p => string.IsNullOrEmpty(p.Name))) { var parameterReferencingIdentifiers = from ident in body.Descendants.OfType <IdentifierExpression>() let v = ident.Annotation <ILVariable>() where v != null && v.IsParameter && method.Parameters.Contains(v.OriginalParameter) select ident; if (!parameterReferencingIdentifiers.Any()) { ame.Parameters.Clear(); ame.HasParameterList = false; } } // Replace all occurrences of 'this' in the method body with the delegate's target: foreach (AstNode node in body.Descendants) { if (node is ThisReferenceExpression) { node.ReplaceWith(target.Clone()); } } if (isLambda) { LambdaExpression lambda = new LambdaExpression(); ame.Parameters.MoveTo(lambda.Parameters); Expression returnExpr = ((ReturnStatement)body.Statements.Single()).Expression; returnExpr.Remove(); lambda.Body = returnExpr; objectCreateExpression.ReplaceWith(lambda); } else { ame.Body = body; objectCreateExpression.ReplaceWith(ame); } return(true); }
protected JsBlock ExportConstructorBody(IMethod ctor) { var ctorNode = (ConstructorDeclaration)ctor.GetDeclaration(); BlockStatement ccc = null; if (ctorNode != null) { ccc = ctorNode.Body; } //var ccc = ctor.GetDefinition();//.decl as CsConstructor; //var ccc = ctor.GetDefinition(); var block2 = (JsBlock)AstNodeConverter.Visit(ccc); if (block2 == null) { block2 = new JsBlock { Statements = new List <JsStatement>() } } ; var ce = ctor.GetDeclaringTypeDefinition(); var isClr = Sk.IsClrType(ce); var isPrototype = Sk.IsNativeType(ce); var statements = new List <JsStatement>(); //instance fields initializations if (!Sk.InlineFields(ce)) { var isGlobal = Sk.IsGlobalType(ce); var fields = GetExportedDeclaredAndGeneratedFields(ce, ctor.IsStatic); //var fields = ctor.GetDeclaringTypeDefinition().GetFields(null, GetMemberOptions.IgnoreInheritedMembers).Where(t => t.IsStatic() == ctor.IsStatic).ToList(); //fields = fields.Where(ShouldExportField).ToList(); //fields.AddRange(GeneratePropertyFields(ctor.DeclaringTypeDefinition, ctor.IsStatic)); //var props = ctor.GetDeclaringTypeDefinition().GetProperties(null, GetMemberOptions.IgnoreInheritedMembers).Where(t => t.IsStatic() == ctor.IsStatic).ToList(); //props = props.Where(t=>Sk.IsNativeField(t)).ToList(); //props = props.Where(t => Sk.IsJsExported(t)).ToList(); //var fieldsAndProperties = fields.Cast<IEntity>().Concat(props.Cast<IEntity>()); var initializers = fields.Select(fe => ExportInitializer(fe, null, isGlobal, false)).Cast <JsStatement>().ToList(); if (initializers.Contains(null)) { Log.Warn("Some field initializers were not exported"); } statements.AddRange(initializers.Where(t => t != null)); } if (!ctor.IsStatic) { //base/this ctor invocation var invocation = GetConstructorBaseOrThisInvocation2(ctor); if (invocation != null) { var baseThisCe = invocation.Member.DeclaringType; var isBaseClr = Sk.IsClrType(baseThisCe.GetDefinition()); var isBasePrototype = Sk.IsNativeType(baseThisCe.GetDefinition()) && !Sk.IsJsonMode(baseThisCe.GetDefinition()) && !Sk.IsGlobalType(baseThisCe.GetDefinition()); //happens when prototype inherits from json if (isBaseClr == isClr && isBasePrototype == isPrototype) //base and derived are both prototype, or both are clr { var newObjExp2 = AstNodeConverter.VisitExpression(invocation); JsInvocationExpression invocation2; if (newObjExp2 is JsNewObjectExpression) { var newObjExp = (JsNewObjectExpression)newObjExp2; invocation2 = newObjExp.Invocation; } else if (newObjExp2 is JsInvocationExpression) { invocation2 = (JsInvocationExpression)newObjExp2; } else { throw new Exception("Unexpected node: " + newObjExp2); } if (Sk.IsExtJsType(ce)) { var invocation3 = Js.This().Member("callParent").Invoke(); if (invocation2.Arguments.IsNotNullOrEmpty()) { invocation3.Arguments = new List <JsExpression> { Js.NewJsonArray(invocation2.Arguments.NotNull().ToArray()) } } ; statements.Add(invocation3.Statement()); } else { JsRefactorer.ToCallWithContext(invocation2, new JsThis()); statements.Add(invocation2.Statement()); } } } } if (block2.Statements == null) { block2.Statements = new List <JsStatement>(); } block2.Statements.InsertRange(0, statements); return(block2); } void ExportConstructorParameters(IMethod ctor, JsFunction func) { var ce = ctor.GetDeclaringTypeDefinition(); var list = new List <string>(); if (!Sk.IgnoreTypeArguments(ce)) { //danel var gprms = ce.TypeParameters.ToList();//.GetGenericArguments().Where(ga => ga.isGenericParam()).ToList(); if (gprms.IsNotNullOrEmpty()) { var i = 0; foreach (var gprm in gprms) { func.Parameters.Add(gprm.Name); if (!ctor.IsStatic && func.Block != null) { func.Block.Statements.Insert(i, Js.This().Member(gprm.Name).Assign(Js.Member(gprm.Name)).Statement()); i++; } } } } var prms = ctor.Parameters; if (prms != null) { func.Parameters.AddRange(prms.Select(t => t.Name)); } }
public void VisitBlockStatement(BlockStatement blockStatement) { StartNode(blockStatement); BraceStyle style; if (blockStatement.Parent is AnonymousMethodExpression || blockStatement.Parent is LambdaExpression) { style = policy.AnonymousMethodBraceStyle; } else if (blockStatement.Parent is ConstructorDeclaration) { style = policy.ConstructorBraceStyle; } else if (blockStatement.Parent is DestructorDeclaration) { style = policy.DestructorBraceStyle; } else if (blockStatement.Parent is MethodDeclaration) { style = policy.MethodBraceStyle; } else if (blockStatement.Parent is Accessor) { if (blockStatement.Parent.Role == PropertyDeclaration.GetterRole) { style = policy.PropertyGetBraceStyle; } else if (blockStatement.Parent.Role == PropertyDeclaration.SetterRole) { style = policy.PropertySetBraceStyle; } else if (blockStatement.Parent.Role == CustomEventDeclaration.AddAccessorRole) { style = policy.EventAddBraceStyle; } else if (blockStatement.Parent.Role == CustomEventDeclaration.RemoveAccessorRole) { style = policy.EventRemoveBraceStyle; } else { style = policy.StatementBraceStyle; } } else { style = policy.StatementBraceStyle; } OpenBrace(style); foreach (var node in blockStatement.Statements) { node.AcceptVisitor(this); } CloseBrace(style); if (!(blockStatement.Parent is Expression)) NewLine(); EndNode(blockStatement); }
public override object VisitBlockStatement(BlockStatement blockStatement, object data) { base.VisitBlockStatement(blockStatement, data); foreach (ExpressionStatement stmt in blockStatement.Statements.OfType <ExpressionStatement>().ToArray()) { Match displayClassAssignmentMatch = displayClassAssignmentPattern.Match(stmt); if (displayClassAssignmentMatch == null) { continue; } ILVariable variable = displayClassAssignmentMatch.Get("variable").Single().Annotation <ILVariable>(); if (variable == null) { continue; } TypeDefinition type = variable.Type.ResolveWithinSameModule(); if (!IsPotentialClosure(context, type)) { continue; } if (displayClassAssignmentMatch.Get("type").Single().Annotation <TypeReference>().ResolveWithinSameModule() != type) { continue; } // Looks like we found a display class creation. Now let's verify that the variable is used only for field accesses: bool ok = true; foreach (var identExpr in blockStatement.Descendants.OfType <IdentifierExpression>()) { if (identExpr.Identifier == variable.Name && identExpr != displayClassAssignmentMatch.Get("variable").Single()) { if (!(identExpr.Parent is MemberReferenceExpression && identExpr.Parent.Annotation <FieldReference>() != null)) { ok = false; } } } if (!ok) { continue; } Dictionary <FieldReference, AstNode> dict = new Dictionary <FieldReference, AstNode>(); // Delete the variable declaration statement: AstNode cur = stmt.NextSibling; stmt.Remove(); if (blockStatement.Parent.NodeType == NodeType.Member || blockStatement.Parent is Accessor) { // Delete any following statements as long as they assign parameters to the display class // Do parameter handling only for closures created in the top scope (direct child of method/accessor) List <ILVariable> parameterOccurrances = blockStatement.Descendants.OfType <IdentifierExpression>() .Select(n => n.Annotation <ILVariable>()).Where(p => p != null && p.IsParameter).ToList(); AstNode next; for (; cur != null; cur = next) { next = cur.NextSibling; // Test for the pattern: // "variableName.MemberName = right;" ExpressionStatement closureFieldAssignmentPattern = new ExpressionStatement( new AssignmentExpression( new NamedNode("left", new MemberReferenceExpression { Target = new IdentifierExpression(variable.Name) }), new AnyNode("right") ) ); Match m = closureFieldAssignmentPattern.Match(cur); if (m != null) { AstNode right = m.Get("right").Single(); bool isParameter = false; if (right is ThisReferenceExpression) { isParameter = true; } else if (right is IdentifierExpression) { // handle parameters only if the whole method contains no other occurrance except for 'right' ILVariable param = right.Annotation <ILVariable>(); isParameter = param.IsParameter && parameterOccurrances.Count(c => c == param) == 1; } if (isParameter) { dict[m.Get <MemberReferenceExpression>("left").Single().Annotation <FieldReference>().ResolveWithinSameModule()] = right; cur.Remove(); } else { break; } } else { break; } } } // Now create variables for all fields of the display class (except for those that we already handled as parameters) List <Tuple <AstType, string> > variablesToDeclare = new List <Tuple <AstType, string> >(); foreach (FieldDefinition field in type.Fields) { if (dict.ContainsKey(field)) { continue; } variablesToDeclare.Add(Tuple.Create(AstBuilder.ConvertType(field.FieldType, field), field.Name)); dict[field] = new IdentifierExpression(field.Name); } // Now figure out where the closure was accessed and use the simpler replacement expression there: foreach (var identExpr in blockStatement.Descendants.OfType <IdentifierExpression>()) { if (identExpr.Identifier == variable.Name) { MemberReferenceExpression mre = (MemberReferenceExpression)identExpr.Parent; AstNode replacement; if (dict.TryGetValue(mre.Annotation <FieldReference>().ResolveWithinSameModule(), out replacement)) { mre.ReplaceWith(replacement.Clone()); } } } // Now insert the variable declarations (we can do this after the replacements only so that the scope detection works): Statement insertionPoint = blockStatement.Statements.FirstOrDefault(); foreach (var tuple in variablesToDeclare) { var newVarDecl = new VariableDeclarationStatement(tuple.Item1, tuple.Item2); newVarDecl.Variables.Single().AddAnnotation(new CapturedVariableAnnotation()); blockStatement.Statements.InsertBefore(insertionPoint, newVarDecl); } } return(null); }
public void AddTo(BlockStatement bodyStatement, AstNode newNode) { var startOffset = GetCurrentOffset(bodyStatement.LBraceToken.EndLocation); var output = OutputNode(1 + GetIndentLevelAt(startOffset), newNode, true); InsertText(startOffset, output.Text); output.RegisterTrackedSegments(this, startOffset); CorrectFormatting (null, newNode); }
public Completion ExecuteBlockStatement(BlockStatement blockStatement) { return(ExecuteStatementList(blockStatement.Body)); }
public override void VisitBlockStatement (BlockStatement blockStatement) { }
public abstract StringBuilder VisitBlockStatement(BlockStatement blockStmt);