Example #1
0
 public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats)
 {
 }
Example #2
0
        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
                 *  };
                 * }*/
            }
        }