示例#1
0
        private void DefineField(ResolutionVisitor resolutionVisitor, INameDeclaration nameDecl)
        {
            if (nameDecl == null)
            {
                // malformed code, for example catch w/o a variable.
                return;
            }
            var field = this[nameDecl.Name];

            if (nameDecl is ParameterDeclaration)
            {
                // function parameters are handled separately, so if this is a parameter declaration,
                // then it must be a catch variable.
                if (field == null)
                {
                    // no collision - create the catch-error field
                    field = new JSVariableField(FieldType.CatchError, nameDecl.Name);

                    this.AddField(field);
                }
                else
                {
                    // it's an error to declare anything in the catch scope with the same name as the
                    // error variable

                    ErrorSink.HandleError(JSError.DuplicateCatch, nameDecl.GetNameSpan(GlobalScope.Node.LocationResolver), resolutionVisitor._locationResolver, true);
                }
            }
            else
            {
                if (field == null)
                {
                    // could be global or local depending on the scope, so let the scope create it.
                    field = this.CreateField(nameDecl.Name);

                    // if this field is a constant, mark it now
                    var lexDeclaration = nameDecl.Parent as LexicalDeclaration;

                    this.AddField(field);
                }
                else
                {
                    // already defined!
                    // if this is a lexical declaration, then it's an error because we have two
                    // lexical declarations with the same name in the same scope.
                    if (nameDecl.Parent is LexicalDeclaration)
                    {
                        _errorSink.HandleError(
                            JSError.DuplicateLexicalDeclaration,
                            nameDecl.GetNameSpan(GlobalScope.Node.LocationResolver),
                            resolutionVisitor._locationResolver,
                            true
                            );
                    }
                }
            }

            nameDecl.VariableField = field;
        }
示例#2
0
        private void ResolveGhostedCatchParameter(ActivationObject scope, ParameterDeclaration catchParameter)
        {
            // check to see if the name exists in the outer variable scope.
            var ghostField = scope[catchParameter.Name];

            if (ghostField == null)
            {
                // set up a ghost field to keep track of the relationship
                ghostField = new JSVariableField(FieldType.GhostCatch, catchParameter.Name);

                scope.AddField(ghostField);
            }
            else if (ghostField.FieldType == FieldType.GhostCatch)
            {
                // there is, but it's another ghost catch variable. That's fine; just use it.
                // don't even flag it as ambiguous because if someone is later referencing the error variable
                // used in a couple catch variables, we'll say something then because other browsers will have that
                // variable undefined or from an outer scope.
            }
            else
            {
                // there is, and it's NOT another ghosted catch variable. Possible naming
                // collision in IE -- if an error happens, it will clobber the existing field's value,
                // although that MAY be the intention; we don't know for sure. But it IS a cross-
                // browser behavior difference.

                if (ghostField.OuterField != null)
                {
                    // and to make matters worse, it's actually bound to an OUTER field
                    // in modern browsers, but will bind to this catch variable in older
                    // versions of IE! Definitely a cross-browser difference!
                    // throw a cross-browser issue error.
                    _errorSink.HandleError(JSError.AmbiguousCatchVar, catchParameter.GetSpan(_locationResolver), _locationResolver);
                }
            }

            // link them so they all keep the same name going forward
            // (since they are named the same in the sources)
            catchParameter.VariableField.OuterField = ghostField;
        }