コード例 #1
0
        internal JSLocalField(JSVariableField outerField)
            : base(outerField)
        {
            JSLocalField outerLocalField = outerField as JSLocalField;

            if (outerLocalField != null)
            {
                // copy some properties
                m_isDefined   = outerLocalField.m_isDefined;
                m_isGenerated = outerLocalField.m_isGenerated;
            }
        }
コード例 #2
0
        // NAME [SCOPE TYPE] [crunched to CRUNCH]
        //
        // SCOPE: global, local, outer, ''
        // TYPE: var, function, argument, arguments array, possibly undefined
        private void WriteMemberReport(JSVariableField variableField, ActivationObject immediateScope)
        {
            // skip any *unreferenced* named-function-expression fields
            JSNamedFunctionExpressionField namedFuncExpr = variableField as JSNamedFunctionExpressionField;

            if (namedFuncExpr == null || namedFuncExpr.RefCount > 0 || !m_removeFunctionExpressionNames)
            {
                string scope    = string.Empty;
                string type     = string.Empty;
                string crunched = string.Empty;
                string name     = variableField.Name;
                if (variableField.IsLiteral)
                {
                    name = variableField.FieldValue.ToString();
                }

                // calculate the crunched label
                JSLocalField localField = variableField as JSLocalField;
                if (localField != null)
                {
                    if (localField.CrunchedName != null)
                    {
                        crunched = StringMgr.GetString("CrunchedTo", localField.CrunchedName, localField.RefCount);
                    }
                }

                // get the field's default scope and type
                GetFieldScopeType(variableField, immediateScope, out scope, out type);
                if (variableField is JSWithField)
                {
                    // if the field is a with field, we won't be using the crunched field (since
                    // those fields can't be crunched), so let's overload it with what the field
                    // could POSSIBLY be if the with object doesn't have a property of that name
                    string outerScope;
                    string outerType;
                    GetFieldScopeType(variableField.OuterField, immediateScope, out outerScope, out outerType);
                    crunched = StringMgr.GetString("MemberInfoWithPossibly", outerScope, outerType);
                }

                // format the entire string
                WriteProgress(StringMgr.GetString(
                                  "MemberInfoFormat",
                                  name,
                                  scope,
                                  type,
                                  crunched
                                  ));
            }
        }
コード例 #3
0
            private static FieldOrder GetOrderIndex(JSVariableField obj)
            {
                if (obj is JSArgumentField)
                {
                    return(FieldOrder.Argument);
                }
                if (obj is JSArgumentsField)
                {
                    return(FieldOrder.ArgumentsArray);
                }

                JSGlobalField globalField = obj as JSGlobalField;

                if (globalField != null)
                {
                    return(
                        globalField.FieldValue is FunctionObject
                      ? FieldOrder.GlobalFunctionReferenced
                      : FieldOrder.GlobalFieldReferenced
                        );
                }

                JSLocalField localField = obj as JSLocalField;

                if (localField != null)
                {
                    if (localField.OuterField != null)
                    {
                        return(
                            localField.FieldValue is FunctionObject
                         ? FieldOrder.OuterFunctionReferenced
                         : FieldOrder.OuterFieldReferenced
                            );
                    }
                    else
                    {
                        return(
                            localField.FieldValue is FunctionObject
                        ? FieldOrder.FunctionDefined
                        : FieldOrder.FieldDefined
                            );
                    }
                }
                return(FieldOrder.Other);
            }
コード例 #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
                JSLocalField[] localFields = GetUncrunchedLocals();
                if (localFields.Length > 0)
                {
                    // create a crunch-name enumerator, taking into account our verboten set
                    CrunchEnumerator crunchEnum = new CrunchEnumerator(Verboten);
                    for (int ndx = 0; ndx < localFields.Length; ++ndx)
                    {
                        JSLocalField 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();
            }
        }
コード例 #5
0
        internal JSLocalField[] GetUncrunchedLocals()
        {
            // there can't be more uncrunched fields than total fields
            List <JSLocalField> list = new List <JSLocalField>(m_nameTable.Count);

            foreach (JSVariableField variableField in m_nameTable.Values)
            {
                // we're only interested in local fields
                JSLocalField localField = variableField as JSLocalField;

                // if the local field is defined in this scope and hasn't been crunched
                // AND can still be crunched
                if (localField != null && localField.OuterField == null && localField.CrunchedName == null &&
                    localField.CanCrunch)
                {
                    // if local renaming is not crunch all, then it must be crunch all but localization
                    // (we don't get called if we aren't crunching anything).
                    // SO for the first clause:
                    // IF we are crunch all, we're good; but if we aren't crunch all, then we're only good if
                    //    the name doesn't start with "L_".
                    // The second clause is only computed IF we already think we're good to go.
                    // IF we aren't preserving function names, then we're good. BUT if we are, we're
                    // only good to go if this field doesn't represent a function object.
                    if ((m_parser.Settings.LocalRenaming == LocalRenaming.CrunchAll ||
                         !localField.Name.StartsWith("L_", StringComparison.Ordinal)) &&
                        !(m_parser.Settings.PreserveFunctionNames && localField.IsFunction))
                    {
                        // add to our list
                        list.Add(localField);
                    }
                }
            }
            // sort the array by reference count, descending
            list.Sort(ReferenceComparer.Instance);
            // return as an array
            return(list.ToArray());
        }
コード例 #6
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;
                    }
                }
            }
        }
コード例 #7
0
        internal virtual void AnalyzeScope()
        {
            // check for unused local fields or arguments
            foreach (JSVariableField variableField in m_nameTable.Values)
            {
                JSLocalField locField = variableField as JSLocalField;
                if (locField != null && !locField.IsReferenced && locField.OriginalContext != null)
                {
                    if (locField.FieldValue is FunctionObject)
                    {
                        Context ctx = ((FunctionObject)locField.FieldValue).IdContext;
                        if (ctx == null)
                        {
                            ctx = locField.OriginalContext;
                        }
                        ctx.HandleError(JSError.FunctionNotReferenced, false);
                    }
                    else if (!locField.IsGenerated)
                    {
                        JSArgumentField argumentField = locField as JSArgumentField;
                        if (argumentField != null)
                        {
                            // we only want to throw this error if it's possible to remove it
                            // from the argument list. And that will only happen if there are
                            // no REFERENCED arguments after this one in the formal parameter list.
                            // Assertion: because this is a JSArgumentField, this should be a function scope,
                            // let's walk up to the first function scope we find, just in case.
                            FunctionScope functionScope = this as FunctionScope;
                            if (functionScope == null)
                            {
                                ActivationObject scope = this.Parent;
                                while (scope != null)
                                {
                                    functionScope = scope as FunctionScope;
                                    if (scope != null)
                                    {
                                        break;
                                    }
                                }
                            }
                            if (functionScope == null || functionScope.IsArgumentTrimmable(argumentField))
                            {
                                locField.OriginalContext.HandleError(
                                    JSError.ArgumentNotReferenced,
                                    false
                                    );
                            }
                        }
                        else if (locField.OuterField == null || !locField.OuterField.IsReferenced)
                        {
                            locField.OriginalContext.HandleError(
                                JSError.VariableDefinedNotReferenced,
                                false
                                );
                        }
                    }
                }
            }

            // rename fields if we need to
            RenameFields();

            // recurse
            foreach (ActivationObject activationObject in m_childScopes)
            {
                try
                {
                    Parser.ScopeStack.Push(activationObject);
                    activationObject.AnalyzeScope();
                }
                finally
                {
                    Parser.ScopeStack.Pop();
                }
            }
        }
コード例 #8
0
        private static void GetFieldScopeType(JSVariableField variableField, ActivationObject immediateScope, out string scope, out string type)
        {
            JSLocalField      localField                 = variableField as JSLocalField;
            JSPredefinedField predefinedField            = variableField as JSPredefinedField;
            JSNamedFunctionExpressionField namedFuncExpr = variableField as JSNamedFunctionExpressionField;

            // default scope is blank
            scope = string.Empty;

            if (variableField is JSArgumentField)
            {
                type = StringMgr.GetString("MemberInfoTypeArgument");
            }
            else if (variableField is JSArgumentsField)
            {
                type = StringMgr.GetString("MemberInfoTypeArguments");
            }
            else if (predefinedField != null)
            {
                switch (predefinedField.GlobalObject)
                {
                case GlobalObjectInstance.GlobalObject:
                    scope = StringMgr.GetString("MemberInfoScopeGlobalObject");
                    break;

                case GlobalObjectInstance.WindowObject:
                    scope = StringMgr.GetString("MemberInfoScopeWindowObject");
                    break;

                case GlobalObjectInstance.Other:
                    scope = StringMgr.GetString("MemberInfoScopeOtherObject");
                    break;
                }
                switch (predefinedField.MemberType)
                {
                case MemberTypes.Method:
                    type = StringMgr.GetString("MemberInfoBuiltInMethod");
                    break;

                case MemberTypes.Property:
                    type = StringMgr.GetString("MemberInfoBuiltInProperty");
                    break;

                default:
                    type = StringMgr.GetString("MemberInfoBuiltInObject");
                    break;
                }
            }
            else if (variableField is JSGlobalField)
            {
                if ((variableField.Attributes & FieldAttributes.RTSpecialName) == FieldAttributes.RTSpecialName)
                {
                    // this is a special "global." It might not be a global, but something referenced
                    // in a with scope somewhere down the line.
                    type = StringMgr.GetString("MemberInfoPossiblyUndefined");
                }
                else if (variableField.FieldValue is FunctionObject)
                {
                    if (variableField.NamedFunctionExpression == null)
                    {
                        type = StringMgr.GetString("MemberInfoGlobalFunction");
                    }
                    else
                    {
                        type = StringMgr.GetString("MemberInfoFunctionExpression");
                    }
                }
                else
                {
                    type = StringMgr.GetString("MemberInfoGlobalVar");
                }
            }
            else if (variableField is JSWithField)
            {
                type = StringMgr.GetString("MemberInfoWithField");
            }
            else if (namedFuncExpr != null)
            {
                type = StringMgr.GetString("MemberInfoSelfFuncExpr");
            }
            else if (localField != null)
            {
                // type string
                if (localField.FieldValue is FunctionObject)
                {
                    if (localField.NamedFunctionExpression == null)
                    {
                        type = StringMgr.GetString("MemberInfoLocalFunction");
                    }
                    else
                    {
                        type = StringMgr.GetString("MemberInfoFunctionExpression");
                    }
                }
                else if (localField.IsLiteral)
                {
                    type = StringMgr.GetString("MemberInfoLocalLiteral");
                }
                else
                {
                    type = StringMgr.GetString("MemberInfoLocalVar");
                }

                // scope string
                // this is a local variable, so there MUST be a non-null function scope passed
                // to us. That function scope will be the scope we are expecting local variables
                // to be defined in. If the field is defined in that scope, it's local -- otherwise
                // it must be an outer variable.
                JSVariableField scopeField = immediateScope[variableField.Name];
                if (scopeField == null || scopeField.OuterField != null)
                {
                    scope = StringMgr.GetString("MemberInfoScopeOuter");
                }
                else
                {
                    scope = StringMgr.GetString("MemberInfoScopeLocal");
                }
            }
            else
            {
                type = StringMgr.GetString("MemberInfoBuiltInObject");
            }
        }
コード例 #9
0
        //TYPE "NAME" - Starts at line LINE, col COLUMN STATUS [crunched to CRUNCH]
        //
        //TYPE: Function, Function getter, Function setter
        //STATUS: '', Unknown, Unreachable
        private void WriteFunctionHeader(FunctionObject funcObj, bool isKnown)
        {
            // get the crunched value (if any)
            string       crunched   = string.Empty;
            JSLocalField localField = funcObj.LocalField as JSLocalField;

            if (localField != null && localField.CrunchedName != null)
            {
                crunched = StringMgr.GetString("CrunchedTo", localField.CrunchedName, localField.RefCount);
            }

            // get the status if the function
            StringBuilder statusBuilder = new StringBuilder();

            if (!isKnown)
            {
                statusBuilder.Append('[');
                statusBuilder.Append(StringMgr.GetString("NotKnown"));
            }
            if (funcObj.FunctionScope.Parent is GlobalScope)
            {
                // global function.
                // if this is a named function expression, we still want to know if it's
                // referenced by anyone
                if (funcObj.FunctionType == FunctionType.Expression &&
                    !string.IsNullOrEmpty(funcObj.Name))
                {
                    // output a comma separator if not the first item, otherwise
                    // open the square bracket
                    if (statusBuilder.Length > 0)
                    {
                        statusBuilder.Append(", ");
                    }
                    else
                    {
                        statusBuilder.Append('[');
                    }
                    statusBuilder.Append(StringMgr.GetString(
                                             "FunctionInfoReferences",
                                             funcObj.RefCount
                                             ));
                }
            }
            else if (!funcObj.FunctionScope.IsReferenced(null))
            {
                // local function that isn't referenced -- unreachable!
                // output a comma separator if not the first item, otherwise
                // open the square bracket
                if (statusBuilder.Length > 0)
                {
                    statusBuilder.Append(", ");
                }
                else
                {
                    statusBuilder.Append('[');
                }
                statusBuilder.Append(StringMgr.GetString("Unreachable"));
            }
            if (statusBuilder.Length > 0)
            {
                statusBuilder.Append(']');
            }
            string status = statusBuilder.ToString();

            string functionType;

            switch (funcObj.FunctionType)
            {
            case FunctionType.Getter:
                functionType = "FunctionTypePropGet";
                break;

            case FunctionType.Setter:
                functionType = "FunctionTypePropSet";
                break;

            case FunctionType.Expression:
                functionType = "FunctionTypeExpression";
                break;

            default:
                functionType = "FunctionTypeFunction";
                break;
            }

            // output
            WriteProgress();
            WriteProgress(StringMgr.GetString(
                              "FunctionHeader",
                              StringMgr.GetString(functionType),
                              funcObj.Name,
                              funcObj.Context.StartLineNumber,
                              funcObj.Context.StartColumn,
                              status,
                              crunched
                              ));
        }
コード例 #10
0
ファイル: functionscope.cs プロジェクト: formist/LinkMe
 internal void Remove(JSLocalField localField)
 {
     NameTable.Remove(localField.Name);
     FieldTable.Remove(localField);
 }