public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { baseOptimize(ref _this, owner, message, opts, stats); var vr = _left as VariableReference; if (vr != null) { if (vr._descriptor.IsDefined) { var stype = _right.ResultType; if (vr._descriptor.lastPredictedType == PredictedType.Unknown) { vr._descriptor.lastPredictedType = stype; } else if (vr._descriptor.lastPredictedType != stype) { if (Tools.IsEqual(vr._descriptor.lastPredictedType, stype, PredictedType.Group)) { vr._descriptor.lastPredictedType = stype & PredictedType.Group; } else { if (message != null && stype >= PredictedType.Undefined && vr._descriptor.lastPredictedType >= PredictedType.Undefined) { message(MessageLevel.Warning, Position, Length, "Variable \"" + vr.Name + "\" has ambiguous type. It can be make impossible some optimizations and cause errors."); } vr._descriptor.lastPredictedType = PredictedType.Ambiguous; } } } else { message?.Invoke(MessageLevel.CriticalWarning, Position, Length, "Assign to undefined variable \"" + vr.Name + "\". It will declare a global variable."); } } var variable = _left as Variable; if (variable != null && variable._descriptor.IsDefined && (_codeContext & CodeContext.InWith) == 0 && !variable._descriptor.captured) { if (!stats.ContainsEval && !stats.ContainsWith) { if (owner != null // не будем это применять в корневом узле. Только в функциях. // Иначе это может задумываться как настройка контекста для последующего использования в Eval && (opts & Options.SuppressUselessExpressionsElimination) == 0 && (_codeContext & CodeContext.InLoop) == 0) { if ((owner.Body._strict || variable._descriptor.owner != owner || !owner.FunctionInfo.ContainsArguments)) // аргументы это одна сущность с двумя именами { bool last = true; for (var i = 0; last && i < variable._descriptor.references.Count; i++) { last &= variable._descriptor.references[i].Eliminated || variable._descriptor.references[i].Position <= Position; } if (last) { if (_right.ContextIndependent) { _this.Eliminated = true; _this = Empty.Instance; } else { _this = _right; _right = null; Eliminated = true; _right = _this as Expression; } } } } } /*if (_this == this && second.ResultInTempContainer) // это присваивание, не последнее, без with * { * _this = new AssignmentOverReplace(first, second) * { * Position = Position, * Length = Length, * _codeContext = _codeContext * }; * }*/ } }