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(); }
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; } } } }