public void KnownNames() { string name; for (var ndx = 0; (name = CrunchEnumerator.GenerateNameFromNumber(ndx)).Length < 4; ++ndx) { Trace.WriteLine(string.Format("{0}: {1}", ndx, name)); } Assert.AreEqual("n", CrunchEnumerator.GenerateNameFromNumber(0), "name for 0"); Assert.AreEqual("t", CrunchEnumerator.GenerateNameFromNumber(1), "name for 1"); Assert.AreEqual("g", CrunchEnumerator.GenerateNameFromNumber(20), "name for last one-digit"); Assert.AreEqual("nt", CrunchEnumerator.GenerateNameFromNumber(21), "name for first roll-over"); Assert.AreEqual("tt", CrunchEnumerator.GenerateNameFromNumber(22), "name for first roll-over + 1"); Assert.AreEqual("it", CrunchEnumerator.GenerateNameFromNumber(23), "name for first roll-over + 2"); Assert.AreEqual("gn", CrunchEnumerator.GenerateNameFromNumber(461), "name for last two-digit"); Assert.AreEqual("ntt", CrunchEnumerator.GenerateNameFromNumber(462), "name for first three-digit"); Assert.AreEqual("gnn", CrunchEnumerator.GenerateNameFromNumber(9722), "name of last three-digit"); Assert.AreEqual("nttt", CrunchEnumerator.GenerateNameFromNumber(9723), "name for first four-digit"); }
internal virtual void AutoRenameFields() { // if we're not known at compile time, then we can't crunch // the local variables in this scope, because we can't know if // something will reference any of it at runtime. // eval is something that will make the scope unknown because we // don't know what eval will evaluate to until runtime if (m_isKnownAtCompileTime) { // get an array of all the uncrunched local variables defined in this scope var localFields = GetUncrunchedLocals(); if (localFields != null) { // create a crunch-name enumerator, taking into account any fields within our // scope that have already been crunched. var avoidSet = new HashSet<string>(); foreach (var field in NameTable.Values) { // if the field can't be crunched, or if it can but we've already crunched it, // add it to the avoid list so we don't reuse that name if (!field.CanCrunch || field.CrunchedName != null) { avoidSet.Add(field.ToString()); } } var crunchEnum = new CrunchEnumerator(avoidSet); foreach (var localField in localFields) { // if we are an unambiguous reference to a named function expression and we are not // referenced by anyone else, then we can just skip this variable because the // name will be stripped from the output anyway. // we also always want to crunch "placeholder" fields. if (localField.CanCrunch && (localField.RefCount > 0 || localField.IsDeclared || localField.IsPlaceholder || !(m_settings.RemoveFunctionExpressionNames && m_settings.IsModificationAllowed(TreeModifications.RemoveFunctionExpressionNames)))) { localField.CrunchedName = crunchEnum.NextName(); } } } } // then traverse through our children foreach (ActivationObject scope in ChildScopes) { scope.AutoRenameFields(); } }
internal virtual void ValidateGeneratedNames() { // check all the variables defined within this scope. // we're looking for uncrunched generated fields. foreach (JSVariableField variableField in NameTable.Values) { if (variableField.IsGenerated && variableField.CrunchedName == null) { // we need to rename this field. // first we need to walk all the child scopes depth-first // looking for references to this field. Once we find a reference, // we then need to add all the other variables referenced in those // scopes and all above them (from here) so we know what names we // can't use. var avoidTable = new HashSet<string>(); GenerateAvoidList(avoidTable, variableField.Name); // now that we have our avoid list, create a crunch enumerator from it CrunchEnumerator crunchEnum = new CrunchEnumerator(avoidTable); // and use it to generate a new name variableField.CrunchedName = crunchEnum.NextName(); } } // recursively traverse through our children foreach (ActivationObject scope in ChildScopes) { scope.ValidateGeneratedNames(); } }
internal virtual void HyperCrunch() { // if we're not known at compile time, then we can't crunch // the local variables in this scope, because we can't know if // something will reference any of it at runtime. // eval is something that will make the scope unknown because we // don't know what eval will evaluate to until runtime if (m_isKnownAtCompileTime) { // get an array of all the uncrunched local variables defined in this scope JSVariableField[] localFields = GetUncrunchedLocals(); if (localFields.Length > 0) { // create a crunch-name enumerator, taking into account our verboten set var crunchEnum = new CrunchEnumerator(Verboten); for (int ndx = 0; ndx < localFields.Length; ++ndx) { JSVariableField localField = localFields[ndx]; // if we are an unambiguous reference to a named function expression and we are not // referenced by anyone else, then we can just skip this variable because the // name will be stripped from the output anyway. // we also always want to crunch "placeholder" fields. if (localField.CanCrunch && (localField.RefCount > 0 || localField.IsDeclared || localField.IsPlaceholder || !(Parser.Settings.RemoveFunctionExpressionNames && Parser.Settings.IsModificationAllowed(TreeModifications.RemoveFunctionExpressionNames)))) { localFields[ndx].CrunchedName = crunchEnum.NextName(); } } } } // then traverse through our children foreach (ActivationObject scope in m_childScopes) { scope.HyperCrunch(); } }