public void Visit(ParameterDeclaration node) { // shoudn't get here DebugEx.Fail("shouldn't get here"); }
public void Visit(ParameterDeclaration node) { // we're good }
public void Visit(ParameterDeclaration node) { // invalid! ignore IsValid = false; }
public void Visit(ParameterDeclaration node) { // add the names from the binding, but ignore any initializers node.IfNotNull(n => n.Binding.IfNotNull(b => b.Accept(this))); }
public FunctionObject(Lookup identifier, JSParser parser, FunctionType functionType, ParameterDeclaration[] parameterDeclarations, Block bodyBlock, Context functionContext, FunctionScope functionScope) : base(functionContext, parser) { FunctionType = functionType; m_functionScope = functionScope; if (functionScope != null) { functionScope.FunctionObject = this; } m_name = string.Empty; Identifier = identifier; if (Identifier != null) { Identifier.Parent = this; } m_parameterDeclarations = parameterDeclarations; Body = bodyBlock; if (bodyBlock != null) { bodyBlock.Parent = this; } // now we need to make sure that the enclosing scope has the name of this function defined // so that any references get properly resolved once we start analyzing the parent scope // see if this is not anonymnous AND not a getter/setter bool isGetterSetter = (FunctionType == FunctionType.Getter || FunctionType == FunctionType.Setter); if (Identifier != null && !isGetterSetter) { // yes -- add the function name to the current enclosing // check whether the function name is in use already // shouldn't be any duplicate names ActivationObject enclosingScope = m_functionScope.Parent; // functions aren't owned by block scopes while (enclosingScope is BlockScope) { enclosingScope = enclosingScope.Parent; } // if the enclosing scope already contains this name, then we know we have a dup string functionName = Identifier.Name; m_variableField = enclosingScope[functionName]; if (m_variableField != null) { // it's pointing to a function m_variableField.IsFunction = true; if (FunctionType == FunctionType.Expression) { // if the containing scope is itself a named function expression, then just // continue on as if everything is fine. It will chain and be good. if (!(m_variableField is JSNamedFunctionExpressionField)) { if (m_variableField.NamedFunctionExpression != null) { // we have a second named function expression in the same scope // with the same name. Not an error unless someone actually references // it. // we are now ambiguous. m_variableField.IsAmbiguous = true; // BUT because this field now points to multiple function object, we // need to break the connection. We'll leave the inner NFEs pointing // to this field as the outer field so the names all align, however. DetachFromOuterField(true); // create a new NFE pointing to the existing field as the outer so // the names stay in sync, and with a value of our function object. JSNamedFunctionExpressionField namedExpressionField = new JSNamedFunctionExpressionField(m_variableField); namedExpressionField.FieldValue = this; m_functionScope.AddField(namedExpressionField); // hook our function object up to the named field m_variableField = namedExpressionField; Identifier.VariableField = namedExpressionField; // we're done; quit. return; } else if (m_variableField.IsAmbiguous) { // we're pointing to a field that is already marked as ambiguous. // just create our own NFE pointing to this one, and hook us up. JSNamedFunctionExpressionField namedExpressionField = new JSNamedFunctionExpressionField(m_variableField); namedExpressionField.FieldValue = this; m_functionScope.AddField(namedExpressionField); // hook our function object up to the named field m_variableField = namedExpressionField; Identifier.VariableField = namedExpressionField; // we're done; quit. return; } else { // we are a named function expression in a scope that has already // defined a local variable of the same name. Not good. Throw the // error but keep them attached because the names have to be synced // to keep the same meaning in all browsers. Identifier.Context.HandleError(JSError.AmbiguousNamedFunctionExpression, false); // if we are preserving function names, then we need to mark this field // as not crunchable if (Parser.Settings.PreserveFunctionNames) { m_variableField.CanCrunch = false; } } } /*else { // it's okay; just chain the NFEs as normal and everything will work out // and the names will be properly synced. }*/ } else { // function declaration -- duplicate name Identifier.Context.HandleError(JSError.DuplicateName, false); } } else { // doesn't exist -- create it now m_variableField = enclosingScope.DeclareField(functionName, this, 0); // and it's a pointing to a function object m_variableField.IsFunction = true; } // set the identifier variable field now. We *know* what the field is now, and during // Analyze mode we aren't going to recurse into the identifier because that would add // a reference to it. Identifier.VariableField = m_variableField; // if we're here, we have a name. if this is a function expression, then we have // a named function expression and we need to do a little more work to prepare for // the ambiguities of named function expressions in various browsers. if (FunctionType == FunctionType.Expression) { // now add a field within the function scope that indicates that it's okay to reference // this named function expression from WITHIN the function itself. // the inner field points to the outer field since we're going to want to catch ambiguous // references in the future JSNamedFunctionExpressionField namedExpressionField = new JSNamedFunctionExpressionField(m_variableField); m_functionScope.AddField(namedExpressionField); m_variableField.NamedFunctionExpression = namedExpressionField; } else { // function declarations are declared by definition m_variableField.IsDeclared = true; } } }