示例#1
0
        private void ResolveGhostedFunctions(ActivationObject scope, FunctionObject funcObject)
        {
            var functionField = funcObject.VariableField;

            // let's check on ghosted names in the outer variable scope
            var ghostField = scope[funcObject.Name];

            if (ghostField == null)
            {
                // nothing; good to go. Add a ghosted field to keep track of it.
                ghostField = new JSVariableField(FieldType.GhostFunction, funcObject.Name);

                scope.AddField(ghostField);
            }
            else if (ghostField.FieldType == FieldType.GhostFunction)
            {
                // there is, but it's another ghosted function expression.
                // what if a lookup is resolved to this field later? We probably still need to
                // at least flag it as ambiguous. We will only need to throw an error, though,
                // if someone actually references the outer ghost variable.
            }
            else
            {
                // something already exists. Could be a naming collision for IE or at least a
                // a cross-browser behavior difference if it's not coded properly.
                // mark this field as a function, even if it wasn't before

                if (ghostField.OuterField != null)
                {
                    // if the pre-existing field we are ghosting is a reference to
                    // an OUTER field, then we actually have a problem that creates a BIG
                    // difference between older IE browsers and everything else.
                    // modern browsers will have the link to the outer field, but older
                    // IE browsers will link to this function expression!
                    // fire a cross-browser error warning
                    _errorSink.HandleError(
                        JSError.AmbiguousNamedFunctionExpression,
                        funcObject.GetNameSpan(_locationResolver),
                        _locationResolver
                        );
                }
            }

            // link them so they all keep the same name going forward
            // (since they are named the same in the sources)
            functionField.OuterField = ghostField;
        }
示例#2
0
 public override bool Walk(FunctionObject node) { AddNode(node, node.GetNameSpan(_tree.LocationResolver).Start, node.ParameterStart, node.ParameterEnd); return true; }
示例#3
0
        public override bool Walk(FunctionObject node)
        {
            if (node != null)
            {
                // create a function scope, assign it to the function object,
                // and push it on the stack
                var parentScope = CurrentLexicalScope;
                if (node.FunctionType == FunctionType.Expression &&
                    !string.IsNullOrEmpty(node.Name))
                {
                    // add this function object to the list of function objects the variable scope
                    // will need to ghost later
                    CurrentVariableScope.GhostedFunctions.Add(node);
                }

                SetScope(
                    node,
                    new FunctionScope(node, parentScope, node.FunctionType != FunctionType.Declaration, node, _errorSink)
                {
                    IsInWithScope = m_withDepth > 0
                }
                    );
                m_lexicalStack.Push(GetScope(node));
                m_variableStack.Push(GetScope(node));

                try
                {
                    // recurse into the function to handle it after saving the current index and resetting it
                    if (node.Body != null)
                    {
                        node.Body.Walk(this);
                    }
                }
                finally
                {
                    Debug.Assert(CurrentLexicalScope == GetScope(node));
                    m_lexicalStack.Pop();
                    m_variableStack.Pop();
                }

                // nothing to add to the var-decl list.
                // but add the function name to the current lex-decl list
                // IF it is a declaration and it has a name (and it SHOULD unless there was an error)
                if (node.FunctionType == FunctionType.Declaration &&
                    !string.IsNullOrEmpty(node.Name))
                {
                    var lexicalScope = CurrentLexicalScope;
                    lexicalScope.LexicallyDeclaredNames.Add(node);

                    if (lexicalScope != CurrentVariableScope)
                    {
                        // the current lexical scope is the variable scope.
                        // this is ES6 syntax: a function declaration inside a block scope. Not allowed
                        // in ES5 code, so throw a warning and ghost this function in the outer variable scope
                        // to make sure that we don't generate any naming collisions.
                        _errorSink.HandleError(JSError.MisplacedFunctionDeclaration, node.GetNameSpan(_locationResolver), _locationResolver);
                        CurrentVariableScope.GhostedFunctions.Add(node);
                    }
                }
            }
            return(false);
        }
        public override bool Walk(FunctionObject node)
        {
            if (node != null)
            {

                // create a function scope, assign it to the function object,
                // and push it on the stack
                var parentScope = CurrentLexicalScope;
                if (node.FunctionType == FunctionType.Expression 
                    && !string.IsNullOrEmpty(node.Name))
                {                    
                    // add this function object to the list of function objects the variable scope
                    // will need to ghost later
                    CurrentVariableScope.GhostedFunctions.Add(node);
                }

                SetScope(
                    node,
                    new FunctionScope(node, parentScope, node.FunctionType != FunctionType.Declaration, node, _errorSink)
                    {
                        IsInWithScope = m_withDepth > 0
                    }
                );
                m_lexicalStack.Push(GetScope(node));
                m_variableStack.Push(GetScope(node));

                try
                {
                    // recurse into the function to handle it after saving the current index and resetting it
                    if (node.Body != null)
                    {
                        node.Body.Walk(this);
                    }
                }
                finally
                {
                    Debug.Assert(CurrentLexicalScope == GetScope(node));
                    m_lexicalStack.Pop();
                    m_variableStack.Pop();
                }

                // nothing to add to the var-decl list.
                // but add the function name to the current lex-decl list
                // IF it is a declaration and it has a name (and it SHOULD unless there was an error)
                if (node.FunctionType == FunctionType.Declaration && 
                    !string.IsNullOrEmpty(node.Name))
                {
                    var lexicalScope = CurrentLexicalScope;
                    lexicalScope.LexicallyDeclaredNames.Add(node);

                    if (lexicalScope != CurrentVariableScope)
                    {
                        // the current lexical scope is the variable scope.
                        // this is ES6 syntax: a function declaration inside a block scope. Not allowed
                        // in ES5 code, so throw a warning and ghost this function in the outer variable scope 
                        // to make sure that we don't generate any naming collisions.
                        _errorSink.HandleError(JSError.MisplacedFunctionDeclaration, node.GetNameSpan(_locationResolver), _locationResolver);
                        CurrentVariableScope.GhostedFunctions.Add(node);
                    }
                }
            }
            return false;
        }
        private void ResolveGhostedFunctions(ActivationObject scope, FunctionObject funcObject)
        {
            var functionField = funcObject.VariableField;

            // let's check on ghosted names in the outer variable scope
            var ghostField = scope[funcObject.Name];
            if (ghostField == null)
            {
                // nothing; good to go. Add a ghosted field to keep track of it.
                ghostField = new JSVariableField(FieldType.GhostFunction, funcObject.Name);

                scope.AddField(ghostField);
            }
            else if (ghostField.FieldType == FieldType.GhostFunction)
            {
                // there is, but it's another ghosted function expression.
                // what if a lookup is resolved to this field later? We probably still need to
                // at least flag it as ambiguous. We will only need to throw an error, though,
                // if someone actually references the outer ghost variable. 
            }
            else
            {
                // something already exists. Could be a naming collision for IE or at least a
                // a cross-browser behavior difference if it's not coded properly.
                // mark this field as a function, even if it wasn't before

                if (ghostField.OuterField != null)
                {
                    // if the pre-existing field we are ghosting is a reference to
                    // an OUTER field, then we actually have a problem that creates a BIG
                    // difference between older IE browsers and everything else.
                    // modern browsers will have the link to the outer field, but older
                    // IE browsers will link to this function expression!
                    // fire a cross-browser error warning
                    _errorSink.HandleError(
                        JSError.AmbiguousNamedFunctionExpression,
                        funcObject.GetNameSpan(_locationResolver), 
                        _locationResolver
                    );
                }
            }

            // link them so they all keep the same name going forward
            // (since they are named the same in the sources)
            functionField.OuterField = ghostField;
        }
示例#6
0
        public override bool Walk(FunctionObject node) {
            if (node.IsGenerator) {
                ReplaceFollowingWhiteSpace(
                    node.GetStartIndex(_tree.LocationResolver) + "function".Length,
                    ""
                );
                if (node.Name != null) {
                    ReplaceFollowingWhiteSpace(
                        node.GeneratorIndex + "*".Length,
                        " "
                    );
                }
            } else if (node.Name == null) {
                ReplaceFollowingWhiteSpace(
                    node.GetStartIndex(_tree.LocationResolver) + "function".Length,
                    _options.SpaceAfterFunctionInAnonymousFunctions ? " " : ""
                );
            } else {
                ReplaceFollowingWhiteSpace(
                    node.GetNameSpan(_tree.LocationResolver).End,
                    ""
                );
            }

            if (node.ParameterDeclarations != null && node.ParameterDeclarations.Length > 0) {
                ReplaceFollowingWhiteSpace(
                    node.ParameterStart + 1,
                    _options.SpaceAfterOpeningAndBeforeClosingNonEmptyParenthesis ? " " : ""
                );

                for (int i = 1; i < node.ParameterDeclarations.Length; i++) {
                    ReplacePreceedingWhiteSpace(node.ParameterDeclarations[i].GetStartIndex(_tree.LocationResolver), _options.SpaceAfterComma ? " " : "", _comma);
                }

                ReplacePreceedingWhiteSpace(
                    node.ParameterEnd - 1,
                    _options.SpaceAfterOpeningAndBeforeClosingNonEmptyParenthesis ? " " : ""
                );
            } else {
                ReplaceFollowingWhiteSpace(
                    node.ParameterStart + 1,
                    ""
                );
            }

            if (!_onEnter) {
                ReplacePreceedingIncludingNewLines(
                    node.Body.GetStartIndex(_tree.LocationResolver),
                    GetFlowFunctionBraceInsertion(node.ParameterEnd, false, node.Body.GetStartIndex(_tree.LocationResolver)));
            }

            WalkBlock(node.Body);

            return false;
        }