Ejemplo n.º 1
0
		public void Run(AstNode node)
		{
			Run(node, null);
			// Declare all the variables at the end, after all the logic has run.
			// This is done so that definite assignment analysis can work on a single representation and doesn't have to be updated
			// when we change the AST.
			foreach (var v in variablesToDeclare) {
				if (v.ReplacedAssignment == null) {
					BlockStatement block = (BlockStatement)v.InsertionPoint.Parent;
					block.Statements.InsertBefore(
						v.InsertionPoint,
						new VariableDeclarationStatement((AstType)v.Type.Clone(), v.Name));
				}
			}
			// First do all the insertions, then do all the replacements. This is necessary because a replacement might remove our reference point from the AST.
			foreach (var v in variablesToDeclare) {
				if (v.ReplacedAssignment != null) {
					// We clone the right expression so that it doesn't get removed from the old ExpressionStatement,
					// which might be still in use by the definite assignment graph.
					VariableDeclarationStatement varDecl = new VariableDeclarationStatement {
						Type = (AstType)v.Type.Clone(),
						Variables = { new VariableInitializer(v.Name, v.ReplacedAssignment.Right.Detach()).CopyAnnotationsFrom(v.ReplacedAssignment) }
					};
					ExpressionStatement es = v.ReplacedAssignment.Parent as ExpressionStatement;
					if (es != null) {
						// Note: if this crashes with 'Cannot replace the root node', check whether two variables were assigned the same name
						es.ReplaceWith(varDecl.CopyAnnotationsFrom(es));
					} else {
						v.ReplacedAssignment.ReplaceWith(varDecl);
					}
				}
			}
			variablesToDeclare = null;
		}
Ejemplo n.º 2
0
 public void Run(AstNode node)
 {
     Run(node, null);
     // Declare all the variables at the end, after all the logic has run.
     // This is done so that definite assignment analysis can work on a single representation and doesn't have to be updated
     // when we change the AST.
     foreach (var v in variablesToDeclare)
     {
         if (v.ReplacedAssignment == null)
         {
             BlockStatement block = (BlockStatement)v.InsertionPoint.Parent;
             var            decl  = new VariableDeclarationStatement(v.ILVariable != null && v.ILVariable.IsParameter ? TextTokenKind.Parameter : TextTokenKind.Local, (AstType)v.Type.Clone(), v.Name);
             if (v.ILVariable != null)
             {
                 decl.Variables.Single().AddAnnotation(v.ILVariable);
             }
             block.Statements.InsertBefore(
                 v.InsertionPoint,
                 decl);
         }
     }
     // First do all the insertions, then do all the replacements. This is necessary because a replacement might remove our reference point from the AST.
     foreach (var v in variablesToDeclare)
     {
         if (v.ReplacedAssignment != null)
         {
             // We clone the right expression so that it doesn't get removed from the old ExpressionStatement,
             // which might be still in use by the definite assignment graph.
             VariableInitializer          initializer = new VariableInitializer(v.ILVariable != null && v.ILVariable.IsParameter ? TextTokenKind.Parameter : TextTokenKind.Local, v.Name, v.ReplacedAssignment.Right.Detach()).CopyAnnotationsFrom(v.ReplacedAssignment).WithAnnotation(v.ILVariable);
             VariableDeclarationStatement varDecl     = new VariableDeclarationStatement {
                 Type      = (AstType)v.Type.Clone(),
                 Variables = { initializer }
             };
             ExpressionStatement es = v.ReplacedAssignment.Parent as ExpressionStatement;
             if (es != null)
             {
                 // Note: if this crashes with 'Cannot replace the root node', check whether two variables were assigned the same name
                 es.ReplaceWith(varDecl.CopyAnnotationsFrom(es));
                 varDecl.AddAnnotation(es.GetAllRecursiveILRanges());
             }
             else
             {
                 varDecl.AddAnnotation(v.ReplacedAssignment.GetAllRecursiveILRanges());
                 v.ReplacedAssignment.ReplaceWith(varDecl);
             }
         }
     }
     variablesToDeclare.Clear();
 }
		/// <summary>
		/// Declares a variable in the smallest required scope.
		/// </summary>
		/// <param name="node">The root of the subtree being searched for the best insertion position</param>
		/// <param name="type">The type of the new variable</param>
		/// <param name="name">The name of the new variable</param>
		/// <param name="allowPassIntoLoops">Whether the variable is allowed to be placed inside a loop</param>
		public static VariableDeclarationStatement DeclareVariable(AstNode node, AstType type, string name, bool allowPassIntoLoops = true)
		{
			VariableDeclarationStatement result = null;
			AstNode pos = FindInsertPos(node, name, allowPassIntoLoops);
			if (pos != null) {
				Match m = assignmentPattern.Match(pos);
				if (m != null && m.Get<IdentifierExpression>("ident").Single().Identifier == name) {
					result = new VariableDeclarationStatement(type, name, m.Get<Expression>("init").Single().Detach());
					result.Variables.Single().CopyAnnotationsFrom(((ExpressionStatement)pos).Expression);
					result.CopyAnnotationsFrom(pos);
					pos.ReplaceWith(result);
				} else {
					result = new VariableDeclarationStatement(type, name);
					pos.Parent.InsertChildBefore(pos, result, BlockStatement.StatementRole);
				}
			}
			return result;
		}
Ejemplo n.º 4
0
 public void Run(AstNode node)
 {
     Run(node, null);
     // Declare all the variables at the end, after all the logic has run.
     // This is done so that definite assignment analysis can work on a single representation and doesn't have to be updated
     // when we change the AST.
     foreach (var v in variablesToDeclare)
     {
         if (v.ReplacedAssignment == null)
         {
             BlockStatement block = (BlockStatement)v.InsertionPoint.Parent;
             block.Statements.InsertBefore(
                 v.InsertionPoint,
                 new VariableDeclarationStatement((AstType)v.Type.Clone(), v.Name));
         }
     }
     // First do all the insertions, then do all the replacements. This is necessary because a replacement might remove our reference point from the AST.
     foreach (var v in variablesToDeclare)
     {
         if (v.ReplacedAssignment != null)
         {
             // We clone the right expression so that it doesn't get removed from the old ExpressionStatement,
             // which might be still in use by the definite assignment graph.
             VariableDeclarationStatement varDecl = new VariableDeclarationStatement {
                 Type      = (AstType)v.Type.Clone(),
                 Variables = { new VariableInitializer(v.Name, v.ReplacedAssignment.Right.Detach()).CopyAnnotationsFrom(v.ReplacedAssignment) }
             };
             ExpressionStatement es = v.ReplacedAssignment.Parent as ExpressionStatement;
             if (es != null)
             {
                 es.ReplaceWith(varDecl.CopyAnnotationsFrom(es));
             }
             else
             {
                 v.ReplacedAssignment.ReplaceWith(varDecl);
             }
         }
     }
     variablesToDeclare = null;
 }