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 ();
			}
		}
Example #4
0
 public virtual void Visit(BlockStatement blockStatement)
 {
     foreach (var xStatement in blockStatement.Statements)
     {
         xStatement.Dispatch(this);
     }
 }
Example #5
0
		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);
				}
			});
		}
Example #6
0
        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);
        }
Example #8
0
        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;
		}
Example #10
0
		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);
        }
Example #14
0
		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;
		}
Example #15
0
        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;
        }
Example #16
0
        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;
        }
Example #17
0
        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...
                }
            }
        }
Example #19
0
 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);
         }
     }
 }
Example #20
0
        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"));

            }*/
        }
Example #21
0
        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"));
			}
Example #25
0
        /// <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;
        }
Example #26
0
 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);
            }
Example #29
0
        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);
        }
Example #30
0
 public UncheckedStatement(BlockStatement body)
 {
     AddChild(body, Roles.Body);
 }
Example #31
0
 public static VariableDeclaration add_Variable(this BlockStatement blockDeclaration, string name, Expression expression, string typeReference)
 {
     return(blockDeclaration.add_Variable(name, expression, new TypeReference(typeReference)));
 }
Example #32
0
        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);
            }
        }
Example #33
0
 /// <nodoc />
 public virtual void Visit(BlockStatement blockStatement)
 {
 }
Example #34
0
 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;
			}
Example #37
0
		void WriteMethodBody(BlockStatement body)
		{
			if (body.IsNull) {
				Semicolon();
			} else {
				VisitBlockStatement(body);
			}
		}
Example #38
0
        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
            });
        }
Example #39
0
 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));
 }
Example #41
0
        public object VisitBlockStatement(BlockStatement statement)
        {
            ExecuteBlock(statement.Statements, new Environment(environment));

            return(null);
        }
Example #42
0
        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)));
 }
Example #44
0
        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));
        }
Example #45
0
 public BlockStatement Process(DecompilationContext context, BlockStatement body)
 {
     this.context = context;
     return((BlockStatement)this.VisitBlockStatement(body));
 }
Example #46
0
        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.
 }
Example #48
0
        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
            });
        }
Example #49
0
        /// <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));
 }
Example #51
0
 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));
 }
Example #53
0
        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);
        }
Example #54
0
        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));
            }
        }
Example #55
0
		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);
		}
Example #56
0
        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);
        }
Example #57
0
	    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);