internal FunctionDeclaration(Context context, AST ifaceId, IdentifierLiteral id, ParameterDeclaration[] formal_parameters, TypeExpression return_type, Block body, FunctionScope own_scope, FieldAttributes attributes, bool isMethod, bool isGetter, bool isSetter, bool isAbstract, bool isFinal, CustomAttributeList customAttributes) : base(context) { MethodAttributes methodAttributes = (MethodAttributes)0; if ((attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) { methodAttributes = MethodAttributes.Public; } else if ((attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Private) { methodAttributes = MethodAttributes.Private; } else if ((attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Assembly) { methodAttributes = MethodAttributes.Assembly; } else if ((attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Family) { methodAttributes = MethodAttributes.Family; } else if ((attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamORAssem) { methodAttributes = MethodAttributes.FamORAssem; } else { methodAttributes = MethodAttributes.Public; } if ((attributes & FieldAttributes.Static) != 0 || !isMethod) { methodAttributes |= MethodAttributes.Static; } else { methodAttributes |= MethodAttributes.Virtual | MethodAttributes.NewSlot; } if (isAbstract) { methodAttributes |= MethodAttributes.Abstract; } if (isFinal) { methodAttributes |= MethodAttributes.Final; } this.name = id.ToString(); this.isMethod = isMethod; if (ifaceId != null) { if (isMethod) { this.ifaceId = new TypeExpression(ifaceId); methodAttributes &= ~MethodAttributes.MemberAccessMask; methodAttributes |= MethodAttributes.Private | MethodAttributes.Final; } else { this.declaringObject = new Member(ifaceId.context, ifaceId, id); this.name = this.declaringObject.ToString(); } } ScriptObject enclosingScope = Globals.ScopeStack.Peek(); if (attributes == 0 && !isAbstract && !isFinal) { if (enclosingScope is ClassScope) { attributes |= FieldAttributes.Public; } } else { if (!(enclosingScope is ClassScope)) { this.context.HandleError(JSError.NotInsideClass); attributes = (FieldAttributes)0; methodAttributes = MethodAttributes.Public; } } if (enclosingScope is ActivationObject) { this.inFastScope = ((ActivationObject)enclosingScope).fast; // if later on originalName != this.name this is a property getter/setter String originalName = this.name; // mangle the name if (isGetter) { methodAttributes |= MethodAttributes.SpecialName; this.name = "get_" + this.name; if (return_type == null) { return_type = new TypeExpression(new ConstantWrapper(Typeob.Object, context)); } } else if (isSetter) { methodAttributes |= MethodAttributes.SpecialName; this.name = "set_" + this.name; return_type = new TypeExpression(new ConstantWrapper(Typeob.Void, context)); } attributes &= FieldAttributes.FieldAccessMask; // create the function object this.func = new FunctionObject(this.name, formal_parameters, return_type, body, own_scope, enclosingScope, this.context, methodAttributes, customAttributes, this.isMethod); if (this.declaringObject != null) { return; } // check whether the function name (possibly mangled) is in use already String fieldName = this.name; if (this.ifaceId != null) { fieldName = ifaceId.ToString() + "." + fieldName; } JSVariableField localField = (JSVariableField)((ActivationObject)enclosingScope).name_table[fieldName]; if (localField != null && (!(localField is JSMemberField) || !(((JSMemberField)localField).value is FunctionObject) || this.func.isExpandoMethod)) { if (originalName != this.name) { localField.originalContext.HandleError(JSError.ClashWithProperty); } else { id.context.HandleError(JSError.DuplicateName, this.func.isExpandoMethod); if (localField.value is FunctionObject) { ((FunctionObject)localField.value).suppressIL = true; } } } // create or update the proper field if (this.isMethod) { if (!(localField is JSMemberField) || !(((JSMemberField)localField).value is FunctionObject) || originalName != this.name) { this.field = ((ActivationObject)enclosingScope).AddNewField(fieldName, this.func, attributes | FieldAttributes.Literal); if (originalName == this.name) // if it is a property do not assign the type { ((JSVariableField)this.field).type = new TypeExpression(new ConstantWrapper(Typeob.FunctionWrapper, this.context)); } } else { this.field = ((JSMemberField)localField).AddOverload(this.func, attributes | FieldAttributes.Literal); } } else if (enclosingScope is FunctionScope) { if (this.inFastScope) { attributes |= FieldAttributes.Literal; } this.field = ((FunctionScope)enclosingScope).AddNewField(this.name, attributes, this.func); if (this.field is JSLocalField) { JSLocalField locField = (JSLocalField)this.field; if (this.inFastScope) { locField.type = new TypeExpression(new ConstantWrapper(Typeob.ScriptFunction, this.context)); locField.attributeFlags |= FieldAttributes.Literal; } locField.debugOn = this.context.document.debugOn; locField.isDefined = true; } } else if (this.inFastScope) { this.field = ((ActivationObject)enclosingScope).AddNewField(this.name, this.func, attributes | FieldAttributes.Literal); ((JSVariableField)this.field).type = new TypeExpression(new ConstantWrapper(Typeob.ScriptFunction, this.context)); //Do not use typeof(Closure) for the field, since that has the arguments and callee properties, which are not //accessible in fast mode } else //enclosingScope is GlobalObject { this.field = ((ActivationObject)enclosingScope).AddNewField(this.name, this.func, attributes | FieldAttributes.Static); } ((JSVariableField)this.field).originalContext = context; // if it is a property create/update the PropertyInfo and assign the getter/setter if (originalName != this.name) { String propertyFieldName = originalName; if (this.ifaceId != null) { propertyFieldName = ifaceId.ToString() + "." + originalName; } FieldInfo prop = (FieldInfo)((ClassScope)enclosingScope).name_table[propertyFieldName]; if (prop != null) { // check whether a property was defined already if (prop.IsLiteral) { Object val = ((JSVariableField)prop).value; if (val is JSProperty) { this.enclosingProperty = (JSProperty)val; } } if (this.enclosingProperty == null) { id.context.HandleError(JSError.DuplicateName, true); // the matching name was not a property } } if (this.enclosingProperty == null) { this.enclosingProperty = new JSProperty(originalName); prop = ((ActivationObject)enclosingScope).AddNewField(propertyFieldName, this.enclosingProperty, attributes | FieldAttributes.Literal); ((JSMemberField)prop).originalContext = this.context; } else { if ((isGetter && this.enclosingProperty.getter != null) || (isSetter && this.enclosingProperty.setter != null)) { id.context.HandleError(JSError.DuplicateName, true); // duplicated setter or getter } } if (isGetter) { this.enclosingProperty.getter = new JSFieldMethod(this.field, enclosingScope); } else { this.enclosingProperty.setter = new JSFieldMethod(this.field, enclosingScope); } } } else //Might get here if function declaration is inside of an eval. { this.inFastScope = false; this.func = new FunctionObject(this.name, formal_parameters, return_type, body, own_scope, enclosingScope, this.context, MethodAttributes.Public, null, false); this.field = ((StackFrame)enclosingScope).AddNewField(this.name, new Closure(this.func), attributes | FieldAttributes.Static); } }
internal FunctionDeclaration(Context context, AST ifaceId, IdentifierLiteral id, ParameterDeclaration[] formal_parameters, TypeExpression return_type, Block body, FunctionScope own_scope, FieldAttributes attributes, bool isMethod, bool isGetter, bool isSetter, bool isAbstract, bool isFinal, CustomAttributeList customAttributes) : base(context) { this.completion = new Completion(); MethodAttributes privateScope = MethodAttributes.PrivateScope; if ((attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) { privateScope = MethodAttributes.Public; } else if ((attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Private) { privateScope = MethodAttributes.Private; } else if ((attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Assembly) { privateScope = MethodAttributes.Assembly; } else if ((attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Family) { privateScope = MethodAttributes.Family; } else if ((attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamORAssem) { privateScope = MethodAttributes.FamORAssem; } else { privateScope = MethodAttributes.Public; } if (((attributes & FieldAttributes.Static) != FieldAttributes.PrivateScope) || !isMethod) { privateScope |= MethodAttributes.Static; } else { privateScope |= MethodAttributes.NewSlot | MethodAttributes.Virtual; } if (isAbstract) { privateScope |= MethodAttributes.Abstract; } if (isFinal) { privateScope |= MethodAttributes.Final; } this.name = id.ToString(); this.isMethod = isMethod; if (ifaceId != null) { if (isMethod) { this.ifaceId = new TypeExpression(ifaceId); privateScope &= ~MethodAttributes.MemberAccessMask; privateScope |= MethodAttributes.Final | MethodAttributes.Private; } else { this.declaringObject = new Member(ifaceId.context, ifaceId, id); this.name = this.declaringObject.ToString(); } } ScriptObject obj2 = base.Globals.ScopeStack.Peek(); if (((attributes == FieldAttributes.PrivateScope) && !isAbstract) && !isFinal) { if (obj2 is ClassScope) { attributes |= FieldAttributes.Public; } } else if (!(obj2 is ClassScope)) { base.context.HandleError(JSError.NotInsideClass); attributes = FieldAttributes.PrivateScope; privateScope = MethodAttributes.Public; } if (obj2 is ActivationObject) { this.inFastScope = ((ActivationObject)obj2).fast; string name = this.name; if (isGetter) { privateScope |= MethodAttributes.SpecialName; this.name = "get_" + this.name; if (return_type == null) { return_type = new TypeExpression(new ConstantWrapper(Typeob.Object, context)); } } else if (isSetter) { privateScope |= MethodAttributes.SpecialName; this.name = "set_" + this.name; return_type = new TypeExpression(new ConstantWrapper(Typeob.Void, context)); } attributes &= FieldAttributes.FieldAccessMask; MethodAttributes attributes3 = privateScope & MethodAttributes.MemberAccessMask; if ((((privateScope & MethodAttributes.Virtual) != MethodAttributes.PrivateScope) && ((privateScope & MethodAttributes.Final) == MethodAttributes.PrivateScope)) && (((attributes3 == MethodAttributes.Private) || (attributes3 == MethodAttributes.Assembly)) || (attributes3 == MethodAttributes.FamANDAssem))) { privateScope |= MethodAttributes.CheckAccessOnOverride; } this.func = new FunctionObject(this.name, formal_parameters, return_type, body, own_scope, obj2, base.context, privateScope, customAttributes, this.isMethod); if (this.declaringObject == null) { string str2 = this.name; if (this.ifaceId != null) { str2 = ifaceId.ToString() + "." + str2; } JSVariableField field = (JSVariableField)((ActivationObject)obj2).name_table[str2]; if ((field != null) && ((!(field is JSMemberField) || !(((JSMemberField)field).value is FunctionObject)) || this.func.isExpandoMethod)) { if (name != this.name) { field.originalContext.HandleError(JSError.ClashWithProperty); } else { id.context.HandleError(JSError.DuplicateName, this.func.isExpandoMethod); if (field.value is FunctionObject) { ((FunctionObject)field.value).suppressIL = true; } } } if (this.isMethod) { if ((!(field is JSMemberField) || !(((JSMemberField)field).value is FunctionObject)) || (name != this.name)) { this.field = ((ActivationObject)obj2).AddNewField(str2, this.func, attributes | FieldAttributes.Literal); if (name == this.name) { this.field.type = new TypeExpression(new ConstantWrapper(Typeob.FunctionWrapper, base.context)); } } else { this.field = ((JSMemberField)field).AddOverload(this.func, attributes | FieldAttributes.Literal); } } else if (obj2 is FunctionScope) { if (this.inFastScope) { attributes |= FieldAttributes.Literal; } this.field = ((FunctionScope)obj2).AddNewField(this.name, attributes, this.func); if (this.field is JSLocalField) { JSLocalField field2 = (JSLocalField)this.field; if (this.inFastScope) { field2.type = new TypeExpression(new ConstantWrapper(Typeob.ScriptFunction, base.context)); field2.attributeFlags |= FieldAttributes.Literal; } field2.debugOn = base.context.document.debugOn; field2.isDefined = true; } } else if (this.inFastScope) { this.field = ((ActivationObject)obj2).AddNewField(this.name, this.func, attributes | FieldAttributes.Literal); this.field.type = new TypeExpression(new ConstantWrapper(Typeob.ScriptFunction, base.context)); } else { this.field = ((ActivationObject)obj2).AddNewField(this.name, this.func, attributes | FieldAttributes.Static); } this.field.originalContext = context; if (name != this.name) { string str3 = name; if (this.ifaceId != null) { str3 = ifaceId.ToString() + "." + name; } FieldInfo info = (FieldInfo)((ClassScope)obj2).name_table[str3]; if (info != null) { if (info.IsLiteral) { object obj3 = ((JSVariableField)info).value; if (obj3 is JSProperty) { this.enclosingProperty = (JSProperty)obj3; } } if (this.enclosingProperty == null) { id.context.HandleError(JSError.DuplicateName, true); } } if (this.enclosingProperty == null) { this.enclosingProperty = new JSProperty(name); ((JSMemberField)((ActivationObject)obj2).AddNewField(str3, this.enclosingProperty, attributes | FieldAttributes.Literal)).originalContext = base.context; } else if ((isGetter && (this.enclosingProperty.getter != null)) || (isSetter && (this.enclosingProperty.setter != null))) { id.context.HandleError(JSError.DuplicateName, true); } if (isGetter) { this.enclosingProperty.getter = new JSFieldMethod(this.field, obj2); } else { this.enclosingProperty.setter = new JSFieldMethod(this.field, obj2); } } } } else { this.inFastScope = false; this.func = new FunctionObject(this.name, formal_parameters, return_type, body, own_scope, obj2, base.context, MethodAttributes.Public, null, false); this.field = ((StackFrame)obj2).AddNewField(this.name, new Closure(this.func), attributes | FieldAttributes.Static); } }