public static JSTemporaryVariable ForFunction( JSFunctionExpression function, TypeReference type, IFunctionSource functionSource ) { var index = function.TemporaryVariableTypes.Count; function.TemporaryVariableTypes.Add(type); MethodReference methodRef = null; if (function.Method != null) { methodRef = function.Method.Reference; } var id = string.Format("$temp{0:X2}", index); var result = new JSTemporaryVariable(id, type, methodRef); function.AllVariables.Add(id, result); // HACK: If the static analysis data for the function is stale, this temporary // variable might get eliminated later despite being in use. // We should really just fix all the transforms that aren't invalidating static // analysis data when they should, but this is good enough for now. if (function.Method != null) { functionSource.InvalidateFirstPass(function.Method.QualifiedIdentifier); } return(result); }
public void VisitNode(JSFunctionExpression fn) { // Create a new visitor for nested function expressions if (Stack.OfType <JSFunctionExpression>().Skip(1).FirstOrDefault() != null) { var nested = new OptimizeArrayEnumerators(TypeSystem, FunctionSource); nested.Visit(fn); return; } Function = fn; FirstPass = FunctionSource.GetFirstPass(Function.Method.QualifiedIdentifier); VisitChildren(fn); if (EnumeratorsToKill.Count > 0) { // Rerun the static analyzer since we made major changes FunctionSource.InvalidateFirstPass(Function.Method.QualifiedIdentifier); FirstPass = FunctionSource.GetFirstPass(Function.Method.QualifiedIdentifier); // Scan to see if any of the enumerators we eliminated uses of are now // unreferenced. If they are, eliminate them entirely. foreach (var variable in EnumeratorsToKill) { var variableName = variable.Name; var accesses = ( from a in FirstPass.Accesses where a.Source.Name == variableName select a ); if (!accesses.Any()) { var eliminator = new VariableEliminator( variable, new JSNullExpression() ); eliminator.Visit(fn); } } } }
protected void EliminateVariable(JSNode context, JSVariable variable, JSExpression replaceWith, QualifiedMemberIdentifier method) { { var replacer = new VariableEliminator( variable, JSChangeTypeExpression.New(replaceWith, TypeSystem, variable.GetActualType(TypeSystem)) ); replacer.Visit(context); } { var replacer = new VariableEliminator(variable, replaceWith); var assignments = (from a in FirstPass.Assignments where variable.Equals(a.NewValue) || a.NewValue.SelfAndChildrenRecursive.Any((_n) => variable.Equals(_n)) select a).ToArray(); foreach (var a in assignments) { if (variable.Equals(a.NewValue)) { FirstPass.Assignments.Remove(a); FirstPass.Assignments.Add( new FunctionAnalysis1stPass.Assignment( a.ParentNodeIndices, a.StatementIndex, a.NodeIndex, a.Target, replaceWith, a.Operator, a.TargetType, a.SourceType ) ); } else { replacer.Visit(a.NewValue); } } } Variables.Remove(variable.Identifier); FunctionSource.InvalidateFirstPass(method); }
protected void InvalidateFirstPass() { FunctionSource.InvalidateFirstPass(Member); }