Example #1
0
        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();
            }
        }
Example #4
0
        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();
            }
        }