Exemplo n.º 1
0
        internal override void HyperCrunch()
        {
            // the block scope is used for catch blocks.
            // we don't want to introduce possible cross-browser problems, so
            // we need to make sure we don't rename our catch parameter to anything
            // already existing in our parent function scope.
            //
            // so walk through the parents (up to the first function or the global scope)
            // and add all existing crunched variable names to our verboten list.
            ActivationObject parentScope = Parent;

            while (parentScope != null)
            {
                // take all the variable names (crunched if they're crunched)
                // and add them to this block's verboten list if they aren't already.
                if (parentScope.NameTable.Count > 0)
                {
                    foreach (var variableField in parentScope.NameTable.Values)
                    {
                        // add it to our verboten list
                        if (!Verboten.ContainsKey(variableField))
                        {
                            Verboten.Add(variableField, variableField);
                        }
                    }
                }

                // also add everything in the parent's verboten list
                if (parentScope.Verboten.Count > 0)
                {
                    foreach (var variableField in parentScope.Verboten.Keys)
                    {
                        // add it to our verboten list
                        if (!Verboten.ContainsKey(variableField))
                        {
                            Verboten.Add(variableField, variableField);
                        }
                    }
                }

                // stop as soon as we've processed a funciton or global scope
                if (!(parentScope is BlockScope))
                {
                    break;
                }
                // next parent
                parentScope = parentScope.Parent;
            }

            // then just perform as usual
            base.HyperCrunch();
        }
Exemplo n.º 2
0
        internal virtual void ReserveFields()
        {
            // traverse through our children first to get depth-first
            foreach (ActivationObject scope in m_childScopes)
            {
                scope.ReserveFields();
            }

            // then reserve all our fields that need reserving
            // check for unused local fields or arguments
            foreach (JSVariableField variableField in m_nameTable.Values)
            {
                JSLocalField localField = variableField as JSLocalField;
                if (localField != null)
                {
                    // if this is a named-function-expression name, then we want to use the name of the
                    // outer field so we don't collide in IE
                    JSNamedFunctionExpressionField namedExprField = localField as JSNamedFunctionExpressionField;
                    if (namedExprField != null)
                    {
                        // make sure the field is in this scope's verboten list so we don't accidentally reuse
                        // an outer scope variable name
                        if (!Verboten.ContainsKey(localField))
                        {
                            Verboten.Add(localField, localField);
                        }

                        // we don't need to reserve up the scope because the named function expression's
                        // "outer" field is always in the very next scope
                    }
                    else if (localField.OuterField != null)
                    {
                        // if the outer field is not null, then this field (not the name) needs to be
                        // reserved up the scope chain until the scope where it's defined.
                        // make sure the field is in this scope's verboten list so we don't accidentally reuse
                        // the outer scope's variable name
                        if (!Verboten.ContainsKey(localField))
                        {
                            Verboten.Add(localField, localField);
                        }

                        for (ActivationObject scope = this; scope != null; scope = scope.Parent)
                        {
                            // get the local field by this name (if any)
                            JSLocalField scopeField = scope.GetLocalField(variableField.Name);
                            if (scopeField == null)
                            {
                                // it's not referenced in this scope -- if the field isn't in the verboten
                                // list, add it now
                                if (!scope.Verboten.ContainsKey(localField))
                                {
                                    scope.Verboten.Add(localField, localField);
                                }
                            }
                            else if (scopeField.OuterField == null)
                            {
                                // found the original field -- stop looking
                                break;
                            }
                        }
                    }
                    else if (m_parser.Settings.LocalRenaming == LocalRenaming.KeepLocalizationVars &&
                             localField.Name.StartsWith("L_", StringComparison.Ordinal))
                    {
                        // localization variable. don't crunch it.
                        // add it to this scope's verboten list in the extremely off-hand chance
                        // that a crunched variable might be the same pattern
                        if (!Verboten.ContainsKey(localField))
                        {
                            Verboten.Add(localField, localField);
                        }
                    }
                    else if (!localField.CanCrunch)
                    {
                        // this local field cannot be crunched for whatever reason
                        // (we probably already have a name picked out for it that we want to keep).
                        // add it to the verboten list, too.
                        if (!Verboten.ContainsKey(localField))
                        {
                            Verboten.Add(localField, localField);
                        }
                    }
                }
                else
                {
                    // must be a global of some sort
                    // reserve the name in this scope and all the way up the chain
                    for (ActivationObject scope = this; scope != null; scope = scope.Parent)
                    {
                        if (!scope.Verboten.ContainsKey(variableField))
                        {
                            scope.Verboten.Add(variableField, variableField);
                        }
                    }
                }
            }

            // finally, if this scope is not known at compile time,
            // AND we know we want to make all affected scopes safe
            // for the eval statement
            // AND we are actually referenced by the enclosing scope,
            // then our parent scope is also not known at compile time
            if (!m_isKnownAtCompileTime &&
                Parser.Settings.EvalTreatment == EvalTreatment.MakeAllSafe)
            {
                ActivationObject parentScope = (ActivationObject)Parent;
                FunctionScope    funcScope   = this as FunctionScope;
                if (funcScope == null)
                {
                    // we're not a function -- parent is unknown too
                    parentScope.IsKnownAtCompileTime = false;
                }
                else
                {
                    JSLocalField localField = parentScope.GetLocalField(funcScope.FunctionObject.Name);
                    if (localField == null || localField.IsReferenced)
                    {
                        parentScope.IsKnownAtCompileTime = false;
                    }
                }
            }
        }