internal EnumDeclaration(Context context, IdentifierLiteral id, TypeExpression baseType, Block body, FieldAttributes attributes, CustomAttributeList customAttributes) : base(context, id, new TypeExpression(new ConstantWrapper(typeof(Enum), null)), new TypeExpression[0], body, attributes, false, false, true, false, customAttributes) { this.baseType = baseType != null ? baseType : new TypeExpression(new ConstantWrapper(Typeob.Int32, null)); this.needsEngine = false; this.attributes &= TypeAttributes.VisibilityMask; TypeExpression thisType = new TypeExpression(new ConstantWrapper(this.classob, this.context)); AST currentValue = new ConstantWrapper(-1, null); AST one = new ConstantWrapper(1, null); foreach (FieldInfo f in this.fields) { JSVariableField field = (JSVariableField)f; field.attributeFlags = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal; field.type = thisType; if (field.value == null) { field.value = currentValue = new Plus(currentValue.context, currentValue, one); } else { currentValue = (AST)field.value; } field.value = new EnumWrapper(field.value, field.Name, this.classob); } }
internal EnumDeclaration(Context context, IdentifierLiteral id, TypeExpression baseType, Block body, FieldAttributes attributes, CustomAttributeList customAttributes) : base(context, id, new TypeExpression(new ConstantWrapper(Typeob.Enum, null)), new TypeExpression[0], body, attributes, false, false, true, false, customAttributes) { this.baseType = (baseType != null) ? baseType : new TypeExpression(new ConstantWrapper(Typeob.Int32, null)); base.needsEngine = false; base.attributes &= TypeAttributes.NestedFamORAssem; TypeExpression expression = new TypeExpression(new ConstantWrapper(base.classob, base.context)); AST ast = new ConstantWrapper(-1, null); AST ast2 = new ConstantWrapper(1, null); JSMemberField[] fields = base.fields; for (int i = 0; i < fields.Length; i++) { FieldInfo info = fields[i]; JSVariableField field = (JSVariableField) info; field.attributeFlags = FieldAttributes.Literal | FieldAttributes.Static | FieldAttributes.Public; field.type = expression; if (field.value == null) { field.value = ast = new Plus(ast.context, ast, ast2); } else { ast = (AST) field.value; } field.value = new DeclaredEnumValue(field.value, field.Name, base.classob); } }
internal EnumDeclaration(Context context, IdentifierLiteral id, TypeExpression baseType, Block body, FieldAttributes attributes, CustomAttributeList customAttributes) : base(context, id, new TypeExpression(new ConstantWrapper(Typeob.Enum, null)), new TypeExpression[0], body, attributes, false, false, true, false, customAttributes) { this.baseType = (baseType != null) ? baseType : new TypeExpression(new ConstantWrapper(Typeob.Int32, null)); base.needsEngine = false; base.attributes &= TypeAttributes.NestedFamORAssem; TypeExpression expression = new TypeExpression(new ConstantWrapper(base.classob, base.context)); AST ast = new ConstantWrapper(-1, null); AST ast2 = new ConstantWrapper(1, null); JSMemberField[] fields = base.fields; for (int i = 0; i < fields.Length; i++) { FieldInfo info = fields[i]; JSVariableField field = (JSVariableField)info; field.attributeFlags = FieldAttributes.Literal | FieldAttributes.Static | FieldAttributes.Public; field.type = expression; if (field.value == null) { field.value = ast = new Plus(ast.context, ast, ast2); } else { ast = (AST)field.value; } field.value = new DeclaredEnumValue(field.value, field.Name, base.classob); } }
internal EnumDeclaration(Context context, IdentifierLiteral id, TypeExpression baseType, Block body, FieldAttributes attributes, CustomAttributeList customAttributes) : base(context, id, new TypeExpression(new ConstantWrapper(typeof(Enum), null)), new TypeExpression[0], body, attributes, false, false, true, false, customAttributes){ this.baseType = baseType != null ? baseType : new TypeExpression(new ConstantWrapper(Typeob.Int32, null)); this.needsEngine = false; this.attributes &= TypeAttributes.VisibilityMask; TypeExpression thisType = new TypeExpression(new ConstantWrapper(this.classob, this.context)); AST currentValue = new ConstantWrapper(-1, null); AST one = new ConstantWrapper(1, null); foreach (FieldInfo f in this.fields){ JSVariableField field = (JSVariableField)f; field.attributeFlags = FieldAttributes.Public|FieldAttributes.Static|FieldAttributes.Literal; field.type = thisType; if (field.value == null) field.value = currentValue = new Plus(currentValue.context, currentValue, one); else currentValue = (AST)field.value; field.value = new EnumWrapper(field.value, field.Name, this.classob); } }
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) { 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); } }
private AST ParseLeftHandSideExpression(bool isMinus, ref bool canBeAttribute, bool warnForKeyword){ AST ast = null; bool isFunction = false; ArrayList newContexts = null; // new expression while (JSToken.New == this.currentToken.token){ if (null == newContexts) newContexts = new ArrayList(4); newContexts.Add(this.currentToken.Clone()); GetNextToken(); } JSToken token = this.currentToken.token; switch (token){ // primary expression case JSToken.Identifier: ast = new Lookup(this.scanner.GetIdentifier(), this.currentToken.Clone()); break; case JSToken.This: canBeAttribute = false; ast = new ThisLiteral(this.currentToken.Clone(), false); break; case JSToken.Super: canBeAttribute = false; ast = new ThisLiteral(this.currentToken.Clone(), true); break; case JSToken.StringLiteral: canBeAttribute = false; ast = new ConstantWrapper(this.scanner.GetStringLiteral(), this.currentToken.Clone()); break; case JSToken.IntegerLiteral: {canBeAttribute = false; String number = this.currentToken.GetCode(); Object n = Convert.LiteralToNumber(number, this.currentToken); if (n == null) n = 0; ast = new ConstantWrapper(n, this.currentToken.Clone()); ((ConstantWrapper)ast).isNumericLiteral = true; break;} case JSToken.NumericLiteral: {canBeAttribute = false; String number = (isMinus) ? "-" + this.currentToken.GetCode() : this.currentToken.GetCode(); double d = Convert.ToNumber(number, false, false, Missing.Value); ast = new ConstantWrapper(d, this.currentToken.Clone()); ((ConstantWrapper)ast).isNumericLiteral = true; break;} case JSToken.True: canBeAttribute = false; ast = new ConstantWrapper(true, this.currentToken.Clone()); break; case JSToken.False: canBeAttribute = false; ast = new ConstantWrapper(false, this.currentToken.Clone()); break; case JSToken.Null: canBeAttribute = false; ast = new NullLiteral(this.currentToken.Clone()); break; case JSToken.PreProcessorConstant: canBeAttribute = false; ast = new ConstantWrapper(this.scanner.GetPreProcessorValue(), this.currentToken.Clone()); break; case JSToken.Divide: canBeAttribute = false; // could it be a regexp? String source = this.scanner.ScanRegExp(); if (source != null){ bool badRegExp = false; try { new Regex(source, RegexOptions.ECMAScript); } catch (System.ArgumentException) { // Replace the invalid source with the trivial regular expression. source = ""; badRegExp = true; } String flags = this.scanner.ScanRegExpFlags(); if (flags == null) ast = new RegExpLiteral(source, null, this.currentToken.Clone()); else try{ ast = new RegExpLiteral(source, flags, this.currentToken.Clone()); }catch (JScriptException){ // The flags are invalid, so use null instead. ast = new RegExpLiteral(source, null, this.currentToken.Clone()); badRegExp = true; } if (badRegExp){ ReportError(JSError.RegExpSyntax, true); } break; } goto default; // expression case JSToken.LeftParen: canBeAttribute = false; GetNextToken(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_ParenExpressionNoSkipToken); try{ ast = ParseExpression(); if (JSToken.RightParen != this.currentToken.token) ReportError(JSError.NoRightParen); }catch(RecoveryTokenException exc){ if (IndexOfToken(NoSkipTokenSet.s_ParenExpressionNoSkipToken, exc) == -1) throw exc; else ast = exc._partiallyComputedNode; }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ParenExpressionNoSkipToken); } if (ast == null) //this can only happen when catching the exception and nothing was sent up by the caller SkipTokensAndThrow(); break; // array initializer case JSToken.LeftBracket: canBeAttribute = false; Context listCtx = this.currentToken.Clone(); ASTList list = new ASTList(this.currentToken.Clone()); GetNextToken(); if (this.currentToken.token == JSToken.Identifier && this.scanner.PeekToken() == JSToken.Colon){ this.noSkipTokenSet.Add(NoSkipTokenSet.s_BracketToken); try{ if (this.currentToken.GetCode() == "assembly"){ GetNextToken(); GetNextToken(); return new AssemblyCustomAttributeList(this.ParseCustomAttributeList()); }else{ ReportError(JSError.ExpectedAssembly); SkipTokensAndThrow(); } }catch(RecoveryTokenException exc){ exc._partiallyComputedNode = new Block(listCtx); return exc._partiallyComputedNode; }finally{ if (this.currentToken.token == JSToken.RightBracket){ this.errorToken = null; GetNextToken(); } this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BracketToken); } } while (JSToken.RightBracket != this.currentToken.token){ if (JSToken.Comma != this.currentToken.token){ this.noSkipTokenSet.Add(NoSkipTokenSet.s_ArrayInitNoSkipTokenSet); try{ list.Append(ParseExpression(true)); if (JSToken.Comma != this.currentToken.token){ if (JSToken.RightBracket != this.currentToken.token) ReportError(JSError.NoRightBracket); break; } }catch(RecoveryTokenException exc){ if (exc._partiallyComputedNode != null) list.Append(exc._partiallyComputedNode); if (IndexOfToken(NoSkipTokenSet.s_ArrayInitNoSkipTokenSet, exc) == -1){ listCtx.UpdateWith(CurrentPositionContext()); exc._partiallyComputedNode = new ArrayLiteral(listCtx, list); throw exc; }else{ if (JSToken.RightBracket == this.currentToken.token) break; } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ArrayInitNoSkipTokenSet); } }else{ list.Append(new ConstantWrapper(Missing.Value, this.currentToken.Clone())); } GetNextToken(); } listCtx.UpdateWith(this.currentToken); ast = new ArrayLiteral(listCtx, list); break; // object initializer case JSToken.LeftCurly: canBeAttribute = false; Context objCtx = this.currentToken.Clone(); GetNextToken(); ASTList fields = new ASTList(this.currentToken.Clone()); if (JSToken.RightCurly != this.currentToken.token){ for (;;){ AST field = null; AST value = null; if (JSToken.Identifier == this.currentToken.token) field = new ConstantWrapper(this.scanner.GetIdentifier(), this.currentToken.Clone()); else if (JSToken.StringLiteral == this.currentToken.token) field = new ConstantWrapper(this.scanner.GetStringLiteral(), this.currentToken.Clone()); else if (JSToken.IntegerLiteral == this.currentToken.token || JSToken.NumericLiteral == this.currentToken.token ){ String numberString = this.currentToken.GetCode(); double dValue = Convert.ToNumber(numberString, true, true, Missing.Value); field = new ConstantWrapper(dValue, this.currentToken.Clone()); ((ConstantWrapper)field).isNumericLiteral = true; }else{ ReportError(JSError.NoMemberIdentifier); field = new IdentifierLiteral("_#Missing_Field#_" + s_cDummyName++, CurrentPositionContext()); } ASTList pair = new ASTList(field.context.Clone()); GetNextToken(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_ObjectInitNoSkipTokenSet); try{ // get the value if (JSToken.Colon != this.currentToken.token){ ReportError(JSError.NoColon, true); value = ParseExpression(true); }else{ GetNextToken(); value = ParseExpression(true); } // put the pair into the list of fields pair.Append(field); pair.Append(value); fields.Append(pair); if (JSToken.RightCurly == this.currentToken.token) break; else{ if (JSToken.Comma == this.currentToken.token) GetNextToken(); else{ if (this.scanner.GotEndOfLine()){ ReportError(JSError.NoRightCurly); }else ReportError(JSError.NoComma, true); SkipTokensAndThrow(); } } }catch(RecoveryTokenException exc){ if (exc._partiallyComputedNode != null){ // the problem was in ParseExpression trying to determine value value = exc._partiallyComputedNode; pair.Append(field); pair.Append(value); fields.Append(pair); } if (IndexOfToken(NoSkipTokenSet.s_ObjectInitNoSkipTokenSet, exc) == -1){ exc._partiallyComputedNode = new ObjectLiteral(objCtx, fields); throw exc; }else{ if (JSToken.Comma == this.currentToken.token) GetNextToken(); if (JSToken.RightCurly == this.currentToken.token) break; } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ObjectInitNoSkipTokenSet); } } } fields.context.UpdateWith(this.currentToken); objCtx.UpdateWith(this.currentToken); ast = new ObjectLiteral(objCtx, fields); break; // function expression case JSToken.Function: canBeAttribute = false; ast = ParseFunction((FieldAttributes)0, true, this.currentToken.Clone(), false, false, false, false, null); isFunction = true; break; default: string identifier = JSKeyword.CanBeIdentifier(this.currentToken.token); if (null != identifier){ if (warnForKeyword){ switch (this.currentToken.token){ case JSToken.Boolean : case JSToken.Byte : case JSToken.Char : case JSToken.Double : case JSToken.Float : case JSToken.Int : case JSToken.Long : case JSToken.Short : case JSToken.Void : break; default: ForceReportInfo(JSError.KeywordUsedAsIdentifier); break; } } canBeAttribute = false; ast = new Lookup(identifier, this.currentToken.Clone()); }else if (this.currentToken.token == JSToken.BitwiseAnd){ //& expr used outside of a parameter list ReportError(JSError.WrongUseOfAddressOf); this.errorToken = null; GetNextToken(); return this.ParseLeftHandSideExpression(isMinus, ref canBeAttribute, warnForKeyword); }else{ ReportError(JSError.ExpressionExpected); SkipTokensAndThrow(); } break; } // can be a CallExpression, that is, followed by '.' or '(' or '[' if (!isFunction) GetNextToken(); return MemberExpression(ast, newContexts, ref canBeAttribute); }
private AST ParseFunction(FieldAttributes visibilitySpec, bool inExpression, Context fncCtx, bool isMethod, bool isAbstract, bool isFinal, bool isInterface, CustomAttributeList customAttributes, Call function){ IdentifierLiteral name = null; AST interfaceName = null; ArrayList formalParameters = null; TypeExpression returnType = null; Block body = null; bool isGetter = false; bool isSetter = false; if (function == null){ GetNextToken(); if (isMethod) if (JSToken.Get == this.currentToken.token){ isGetter = true; GetNextToken(); }else if (JSToken.Set == this.currentToken.token){ isSetter = true; GetNextToken(); } // get the function name or make an anonymous function if in expression "position" if (JSToken.Identifier == this.currentToken.token){ name = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone()); GetNextToken(); if (JSToken.AccessField == this.currentToken.token){ if (isInterface) // "function IBar.foo()" is illegal in an interface declaration ReportError(JSError.SyntaxError, true); GetNextToken(); if (JSToken.Identifier == this.currentToken.token){ interfaceName = new Lookup(name.context); name = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone()); GetNextToken(); while (JSToken.AccessField == this.currentToken.token){ GetNextToken(); if (JSToken.Identifier == this.currentToken.token){ interfaceName = new Member(interfaceName.context.CombineWith(this.currentToken), interfaceName, new ConstantWrapper(name.ToString(), name.context)); name = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone()); GetNextToken(); }else ReportError(JSError.NoIdentifier, true); } }else ReportError(JSError.NoIdentifier, true); } }else{ string identifier = JSKeyword.CanBeIdentifier(this.currentToken.token); if (null != identifier){ ForceReportInfo(JSError.KeywordUsedAsIdentifier, isMethod); name = new IdentifierLiteral(identifier, this.currentToken.Clone()); GetNextToken(); }else{ if (!inExpression){ identifier = this.currentToken.GetCode(); ReportError(JSError.NoIdentifier, true); GetNextToken(); }else identifier = ""; name = new IdentifierLiteral(identifier, CurrentPositionContext()); } } }else{ // function was passed in, this is an error condition name = function.GetName(); } // make a new state and save the old one ArrayList blockType = this.blockType; this.blockType = new ArrayList(16); SimpleHashtable labelTable = this.labelTable; this.labelTable = new SimpleHashtable(16); FunctionScope fscope = new FunctionScope(Globals.ScopeStack.Peek(), isMethod); Globals.ScopeStack.Push(fscope); //Give declarations a place to go while building AST try{ formalParameters = new ArrayList(); Context paramArrayContext = null; if (function == null){ // get the formal parameters if (JSToken.LeftParen != this.currentToken.token) ReportError(JSError.NoLeftParen); GetNextToken(); // create the list of arguments and update the context while (JSToken.RightParen != this.currentToken.token){ if (paramArrayContext != null){ ReportError(JSError.ParamListNotLast, paramArrayContext, true); paramArrayContext = null; } String id = null; TypeExpression typeExpr = null; this.noSkipTokenSet.Add(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet); try{ if (JSToken.ParamArray == this.currentToken.token){ paramArrayContext = this.currentToken.Clone(); GetNextToken(); } if (JSToken.Identifier != this.currentToken.token && (id = JSKeyword.CanBeIdentifier(this.currentToken.token)) == null){ if (JSToken.LeftCurly == this.currentToken.token){ ReportError(JSError.NoRightParen); break; }else if (JSToken.Comma == this.currentToken.token){ // We're missing an argument (or previous argument was malformed and // we skipped to the comma.) Keep trying to parse the argument list -- // we will skip the comma below. ReportError(JSError.SyntaxError, true); }else{ ReportError(JSError.SyntaxError, true); SkipTokensAndThrow(); } }else{ if (null == id) id = this.scanner.GetIdentifier(); else ForceReportInfo(JSError.KeywordUsedAsIdentifier); Context paramCtx = this.currentToken.Clone(); GetNextToken(); if (JSToken.Colon == this.currentToken.token){ typeExpr = ParseTypeExpression(); if (null != typeExpr) paramCtx.UpdateWith(typeExpr.context); } CustomAttributeList custAttrs = null; if (paramArrayContext != null){ custAttrs = new CustomAttributeList(paramArrayContext); custAttrs.Append(new CustomAttribute(paramArrayContext, new Lookup("...", paramArrayContext), new ASTList(null))); } formalParameters.Add(new ParameterDeclaration(paramCtx, id, typeExpr, custAttrs)); } // got an arg, it should be either a ',' or ')' if (JSToken.RightParen == this.currentToken.token) break; else if (JSToken.Comma != this.currentToken.token){ // deal with error in some "intelligent" way if (JSToken.LeftCurly == this.currentToken.token){ ReportError(JSError.NoRightParen); break; }else{ if (JSToken.Identifier == this.currentToken.token && typeExpr == null){ // it's possible that the guy was writing the type in C/C++ style (i.e. int x) ReportError(JSError.NoCommaOrTypeDefinitionError); }else ReportError(JSError.NoComma); } } GetNextToken(); }catch(RecoveryTokenException exc){ if (IndexOfToken(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet, exc) == -1) throw exc; }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet); } } fncCtx.UpdateWith(this.currentToken); // if it is a getter/setter must have 0/1 arg only if (isGetter && formalParameters.Count != 0){ ReportError(JSError.BadPropertyDeclaration, true); isGetter = false; }else if (isSetter && formalParameters.Count != 1){ ReportError(JSError.BadPropertyDeclaration, true); isSetter = false; } GetNextToken(); // check the return type if (JSToken.Colon == this.currentToken.token){ if (isSetter) ReportError(JSError.SyntaxError); this.noSkipTokenSet.Add(NoSkipTokenSet.s_StartBlockNoSkipTokenSet); try{ returnType = ParseTypeExpression(); }catch(RecoveryTokenException exc){ if (IndexOfToken(NoSkipTokenSet.s_StartBlockNoSkipTokenSet, exc) == -1){ exc._partiallyComputedNode = null; throw exc; }else{ if (exc._partiallyComputedNode != null) returnType = (TypeExpression)exc._partiallyComputedNode; } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_StartBlockNoSkipTokenSet); } if (isSetter) returnType = null; } }else{ // function was passed in, this is an error condition function.GetParameters(formalParameters); } // read the function body of non-abstract functions. if (JSToken.LeftCurly != this.currentToken.token && (isAbstract || (isMethod && GuessIfAbstract()))){ if (!isAbstract){ isAbstract = true; ReportError(JSError.ShouldBeAbstract, fncCtx, true); } body = new Block(this.currentToken.Clone()); }else{ if (JSToken.LeftCurly != this.currentToken.token) ReportError(JSError.NoLeftCurly, true); else if (isAbstract) ReportError(JSError.AbstractWithBody, fncCtx, true); this.blockType.Add(BlockType.Block); this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockNoSkipTokenSet); this.noSkipTokenSet.Add(NoSkipTokenSet.s_StartStatementNoSkipTokenSet); try{ // parse the block locally to get the exact end of function body = new Block(this.currentToken.Clone()); GetNextToken(); while (JSToken.RightCurly != this.currentToken.token){ try{ body.Append(ParseStatement()); }catch(RecoveryTokenException exc){ if (exc._partiallyComputedNode != null){ body.Append(exc._partiallyComputedNode); } if (IndexOfToken(NoSkipTokenSet.s_StartStatementNoSkipTokenSet, exc) == -1) throw exc; } } body.context.UpdateWith(this.currentToken); fncCtx.UpdateWith(this.currentToken); }catch(RecoveryTokenException exc){ if (IndexOfToken(NoSkipTokenSet.s_BlockNoSkipTokenSet, exc) == -1){ Globals.ScopeStack.Pop(); //Pop current scope so that FunctionDeclaration sees proper scope stack try{ ParameterDeclaration[] foParameters = new ParameterDeclaration[formalParameters.Count]; formalParameters.CopyTo(foParameters); if (inExpression) exc._partiallyComputedNode = new FunctionExpression(fncCtx, name, foParameters, returnType, body, fscope, visibilitySpec); else exc._partiallyComputedNode = new FunctionDeclaration(fncCtx, interfaceName, name, foParameters, returnType, body, fscope, visibilitySpec, isMethod, isGetter, isSetter, isAbstract, isFinal, customAttributes); if (customAttributes != null) customAttributes.SetTarget(exc._partiallyComputedNode); }finally{ Globals.ScopeStack.Push(fscope); //Push it back so that the next finally can pop it } throw exc; } }finally{ this.blockType.RemoveAt(this.blockType.Count - 1); this.noSkipTokenSet.Remove(NoSkipTokenSet.s_StartStatementNoSkipTokenSet); this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockNoSkipTokenSet); } GetNextToken(); } }finally{ // restore state this.blockType = blockType; this.labelTable = labelTable; Globals.ScopeStack.Pop(); } ParameterDeclaration[] fParameters = new ParameterDeclaration[formalParameters.Count]; formalParameters.CopyTo(fParameters); AST func; if (inExpression) func = new FunctionExpression(fncCtx, name, fParameters, returnType, body, fscope, visibilitySpec); else func = new FunctionDeclaration(fncCtx, interfaceName, name, fParameters, returnType, body, fscope, visibilitySpec, isMethod, isGetter, isSetter, isAbstract, isFinal, customAttributes); if (customAttributes != null) customAttributes.SetTarget(func); return func; }
//--------------------------------------------------------------------------------------- // ParseEnum // // Enum : // 'enum' identifier [':' baseType] EnumBody (in the guise of ClassBody with a param) // //--------------------------------------------------------------------------------------- private AST ParseEnum(FieldAttributes visibilitySpec, Context enumCtx, CustomAttributeList customAttributes){ IdentifierLiteral name = null; AST baseId = null; TypeExpression baseType = null; Block body = null; GetNextToken(); if (JSToken.Identifier == this.currentToken.token){ name = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone()); }else{ ReportError(JSError.NoIdentifier); if (JSToken.Colon != this.currentToken.token && JSToken.LeftCurly != this.currentToken.token) SkipTokensAndThrow(); // what the is this? name = new IdentifierLiteral("##Missing Enum Name##" + s_cDummyName++, CurrentPositionContext()); } GetNextToken(); if (JSToken.Colon == this.currentToken.token){ this.noSkipTokenSet.Add(NoSkipTokenSet.s_EnumBaseTypeNoSkipTokenSet); try{ baseId = ParseQualifiedIdentifier(JSError.NeedType); }catch(RecoveryTokenException exc){ if (IndexOfToken(NoSkipTokenSet.s_ClassExtendsNoSkipTokenSet, exc) == -1){ exc._partiallyComputedNode = null; throw exc; }else{ baseId = exc._partiallyComputedNode; } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_EnumBaseTypeNoSkipTokenSet); } } if (baseId != null) baseType = new TypeExpression(baseId); if (JSToken.LeftCurly != this.currentToken.token) ReportError(JSError.NoLeftCurly); // make a new state and save the old one ArrayList blockType = this.blockType; this.blockType = new ArrayList(16); SimpleHashtable labelTable = this.labelTable; this.labelTable = new SimpleHashtable(16); Globals.ScopeStack.Push(new ClassScope(name, ((IActivationObject)Globals.ScopeStack.Peek()).GetGlobalScope())); //Give declarations a place to go while building AST try{ body = ParseClassBody(true, false); enumCtx.UpdateWith(body.context); EnumDeclaration result = new EnumDeclaration(enumCtx, name, baseType, body, visibilitySpec, customAttributes); if (customAttributes != null) customAttributes.SetTarget(result); return result; }catch(RecoveryTokenException exc){ enumCtx.UpdateWith(exc._partiallyComputedNode.context); exc._partiallyComputedNode = new EnumDeclaration(enumCtx, name, baseType, (Block)exc._partiallyComputedNode, visibilitySpec, customAttributes); if (customAttributes != null) customAttributes.SetTarget(exc._partiallyComputedNode); throw exc; }finally{ Globals.ScopeStack.Pop(); this.blockType = blockType; this.labelTable = labelTable; } }
//--------------------------------------------------------------------------------------- // ParseClass // // Class : // 'class' identifier OptionalExtends ClassBody // // Extends : // 'extends' QualifiedIdentifier // //--------------------------------------------------------------------------------------- private AST ParseClass(FieldAttributes visibilitySpec, bool isStatic, Context classCtx, bool isAbstract, bool isFinal, CustomAttributeList customAttributes){ AST name = null; AST baseId = null; TypeExpression baseType = null; Block body = null; ArrayList interfaces = new ArrayList(); bool isInterface = JSToken.Interface == this.currentToken.token; GetNextToken(); if (JSToken.Identifier == this.currentToken.token){ name = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone()); }else{ ReportError(JSError.NoIdentifier); if (JSToken.Extends != this.currentToken.token && JSToken.Implements != this.currentToken.token && JSToken.LeftCurly != this.currentToken.token) SkipTokensAndThrow(); // what the is this? name = new IdentifierLiteral("##Missing Class Name##" + s_cDummyName++, CurrentPositionContext()); } GetNextToken(); if (JSToken.Extends == this.currentToken.token || JSToken.Implements == this.currentToken.token){ if (isInterface && JSToken.Extends == this.currentToken.token) this.currentToken.token = JSToken.Implements; if (JSToken.Extends == this.currentToken.token){ this.noSkipTokenSet.Add(NoSkipTokenSet.s_ClassExtendsNoSkipTokenSet); try{ baseId = ParseQualifiedIdentifier(JSError.NeedType); }catch(RecoveryTokenException exc){ if (IndexOfToken(NoSkipTokenSet.s_ClassExtendsNoSkipTokenSet, exc) == -1){ exc._partiallyComputedNode = null; throw exc; }else{ baseId = exc._partiallyComputedNode; } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ClassExtendsNoSkipTokenSet); } } if (JSToken.Implements == this.currentToken.token){ do{ AST typeId = null; this.noSkipTokenSet.Add(NoSkipTokenSet.s_ClassImplementsNoSkipTokenSet); try{ typeId = ParseQualifiedIdentifier(JSError.NeedType); interfaces.Add(new TypeExpression(typeId)); }catch(RecoveryTokenException exc){ if (IndexOfToken(NoSkipTokenSet.s_ClassImplementsNoSkipTokenSet, exc) == -1){ exc._partiallyComputedNode = null; throw exc; }else{ if (exc._partiallyComputedNode != null) interfaces.Add(new TypeExpression(exc._partiallyComputedNode)); } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ClassImplementsNoSkipTokenSet); } }while (JSToken.Comma == this.currentToken.token); } } if (baseId != null) baseType = new TypeExpression(baseId); if (JSToken.LeftCurly != this.currentToken.token){ ReportError(JSError.NoLeftCurly); } // make a new state and save the old one ArrayList blockType = this.blockType; this.blockType = new ArrayList(16); SimpleHashtable labelTable = this.labelTable; this.labelTable = new SimpleHashtable(16); Globals.ScopeStack.Push(new ClassScope(name, ((IActivationObject)Globals.ScopeStack.Peek()).GetGlobalScope())); //Give declarations a place to go while building AST TypeExpression[] ifaces; try{ body = ParseClassBody(false, isInterface); classCtx.UpdateWith(body.context); ifaces = new TypeExpression[interfaces.Count]; interfaces.CopyTo(ifaces); Class result = new Class(classCtx, name, baseType, ifaces, body, visibilitySpec, isAbstract, isFinal, isStatic, isInterface, customAttributes); if (customAttributes != null) customAttributes.SetTarget(result); return result; }catch(RecoveryTokenException exc){ classCtx.UpdateWith(exc._partiallyComputedNode.context); ifaces = new TypeExpression[interfaces.Count]; interfaces.CopyTo(ifaces); exc._partiallyComputedNode = new Class(classCtx, name, baseType, ifaces, (Block)exc._partiallyComputedNode, visibilitySpec, isAbstract, isFinal, isStatic, isInterface, customAttributes); if (customAttributes != null) customAttributes.SetTarget(exc._partiallyComputedNode); throw exc; }finally{ Globals.ScopeStack.Pop(); this.blockType = blockType; this.labelTable = labelTable; } }
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); } }
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); } }
private AST ParseLeftHandSideExpression(bool isMinus, ref bool canBeAttribute, bool warnForKeyword) { AST expression = null; Context context; ASTList list2; Context context2; ASTList list3; string str6; bool flag = false; ArrayList newContexts = null; while (JSToken.New == this.currentToken.token) { if (newContexts == null) { newContexts = new ArrayList(4); } newContexts.Add(this.currentToken.Clone()); this.GetNextToken(); } JSToken token = this.currentToken.token; if (token <= JSToken.Divide) { switch (token) { case JSToken.Function: canBeAttribute = false; expression = this.ParseFunction(FieldAttributes.PrivateScope, true, this.currentToken.Clone(), false, false, false, false, null); flag = true; goto Label_0956; case JSToken.LeftCurly: { AST ast2; canBeAttribute = false; context2 = this.currentToken.Clone(); this.GetNextToken(); list3 = new ASTList(this.currentToken.Clone()); if (JSToken.RightCurly == this.currentToken.token) { goto Label_0830; } Label_05C9: ast2 = null; AST elem = null; if (JSToken.Identifier == this.currentToken.token) { ast2 = new ConstantWrapper(this.scanner.GetIdentifier(), this.currentToken.Clone()); } else if (JSToken.StringLiteral == this.currentToken.token) { ast2 = new ConstantWrapper(this.scanner.GetStringLiteral(), this.currentToken.Clone()); } else if ((JSToken.IntegerLiteral == this.currentToken.token) || (JSToken.NumericLiteral == this.currentToken.token)) { ast2 = new ConstantWrapper(Microsoft.JScript.Convert.ToNumber(this.currentToken.GetCode(), true, true, Microsoft.JScript.Missing.Value), this.currentToken.Clone()); ((ConstantWrapper) ast2).isNumericLiteral = true; } else { this.ReportError(JSError.NoMemberIdentifier); ast2 = new IdentifierLiteral("_#Missing_Field#_" + s_cDummyName++, this.CurrentPositionContext()); } ASTList list4 = new ASTList(ast2.context.Clone()); this.GetNextToken(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_ObjectInitNoSkipTokenSet); try { try { if (JSToken.Colon != this.currentToken.token) { this.ReportError(JSError.NoColon, true); elem = this.ParseExpression(true); } else { this.GetNextToken(); elem = this.ParseExpression(true); } list4.Append(ast2); list4.Append(elem); list3.Append(list4); if (JSToken.RightCurly == this.currentToken.token) { goto Label_0830; } if (JSToken.Comma == this.currentToken.token) { this.GetNextToken(); } else { if (this.scanner.GotEndOfLine()) { this.ReportError(JSError.NoRightCurly); } else { this.ReportError(JSError.NoComma, true); } this.SkipTokensAndThrow(); } } catch (RecoveryTokenException exception4) { if (exception4._partiallyComputedNode != null) { elem = exception4._partiallyComputedNode; list4.Append(ast2); list4.Append(elem); list3.Append(list4); } if (this.IndexOfToken(NoSkipTokenSet.s_ObjectInitNoSkipTokenSet, exception4) == -1) { exception4._partiallyComputedNode = new ObjectLiteral(context2, list3); throw exception4; } if (JSToken.Comma == this.currentToken.token) { this.GetNextToken(); } if (JSToken.RightCurly == this.currentToken.token) { goto Label_0830; } } goto Label_05C9; } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ObjectInitNoSkipTokenSet); } goto Label_0830; } case JSToken.Null: canBeAttribute = false; expression = new NullLiteral(this.currentToken.Clone()); goto Label_0956; case JSToken.True: canBeAttribute = false; expression = new ConstantWrapper(true, this.currentToken.Clone()); goto Label_0956; case JSToken.False: canBeAttribute = false; expression = new ConstantWrapper(false, this.currentToken.Clone()); goto Label_0956; case JSToken.This: canBeAttribute = false; expression = new ThisLiteral(this.currentToken.Clone(), false); goto Label_0956; case JSToken.Identifier: expression = new Lookup(this.scanner.GetIdentifier(), this.currentToken.Clone()); goto Label_0956; case JSToken.StringLiteral: canBeAttribute = false; expression = new ConstantWrapper(this.scanner.GetStringLiteral(), this.currentToken.Clone()); goto Label_0956; case JSToken.IntegerLiteral: { canBeAttribute = false; object obj2 = Microsoft.JScript.Convert.LiteralToNumber(this.currentToken.GetCode(), this.currentToken); if (obj2 == null) { obj2 = 0; } expression = new ConstantWrapper(obj2, this.currentToken.Clone()); ((ConstantWrapper) expression).isNumericLiteral = true; goto Label_0956; } case JSToken.NumericLiteral: { canBeAttribute = false; string str = isMinus ? ("-" + this.currentToken.GetCode()) : this.currentToken.GetCode(); expression = new ConstantWrapper(Microsoft.JScript.Convert.ToNumber(str, false, false, Microsoft.JScript.Missing.Value), this.currentToken.Clone()); ((ConstantWrapper) expression).isNumericLiteral = true; goto Label_0956; } case JSToken.LeftParen: canBeAttribute = false; this.GetNextToken(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_ParenExpressionNoSkipToken); try { expression = this.ParseExpression(); if (JSToken.RightParen != this.currentToken.token) { this.ReportError(JSError.NoRightParen); } } catch (RecoveryTokenException exception) { if (this.IndexOfToken(NoSkipTokenSet.s_ParenExpressionNoSkipToken, exception) == -1) { throw exception; } expression = exception._partiallyComputedNode; } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ParenExpressionNoSkipToken); } if (expression == null) { this.SkipTokensAndThrow(); } goto Label_0956; case JSToken.LeftBracket: canBeAttribute = false; context = this.currentToken.Clone(); list2 = new ASTList(this.currentToken.Clone()); this.GetNextToken(); if ((this.currentToken.token != JSToken.Identifier) || (this.scanner.PeekToken() != JSToken.Colon)) { goto Label_0561; } this.noSkipTokenSet.Add(NoSkipTokenSet.s_BracketToken); try { try { if (this.currentToken.GetCode() == "assembly") { this.GetNextToken(); this.GetNextToken(); return new AssemblyCustomAttributeList(this.ParseCustomAttributeList()); } this.ReportError(JSError.ExpectedAssembly); this.SkipTokensAndThrow(); } catch (RecoveryTokenException exception2) { exception2._partiallyComputedNode = new Block(context); return exception2._partiallyComputedNode; } goto Label_0561; } finally { if (this.currentToken.token == JSToken.RightBracket) { this.errorToken = null; this.GetNextToken(); } this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BracketToken); } goto Label_046D; case JSToken.Divide: { canBeAttribute = false; string pattern = this.scanner.ScanRegExp(); if (pattern == null) { break; } bool flag2 = false; try { new Regex(pattern, RegexOptions.ECMAScript); } catch (ArgumentException) { pattern = ""; flag2 = true; } string flags = this.scanner.ScanRegExpFlags(); if (flags == null) { expression = new RegExpLiteral(pattern, null, this.currentToken.Clone()); } else { try { expression = new RegExpLiteral(pattern, flags, this.currentToken.Clone()); } catch (JScriptException) { expression = new RegExpLiteral(pattern, null, this.currentToken.Clone()); flag2 = true; } } if (flag2) { this.ReportError(JSError.RegExpSyntax, true); } goto Label_0956; } } goto Label_0881; } if (token != JSToken.Super) { if (token == JSToken.PreProcessorConstant) { canBeAttribute = false; expression = new ConstantWrapper(this.scanner.GetPreProcessorValue(), this.currentToken.Clone()); goto Label_0956; } goto Label_0881; } canBeAttribute = false; expression = new ThisLiteral(this.currentToken.Clone(), true); goto Label_0956; Label_046D: if (JSToken.Comma != this.currentToken.token) { this.noSkipTokenSet.Add(NoSkipTokenSet.s_ArrayInitNoSkipTokenSet); try { list2.Append(this.ParseExpression(true)); if (JSToken.Comma != this.currentToken.token) { if (JSToken.RightBracket != this.currentToken.token) { this.ReportError(JSError.NoRightBracket); } goto Label_0573; } } catch (RecoveryTokenException exception3) { if (exception3._partiallyComputedNode != null) { list2.Append(exception3._partiallyComputedNode); } if (this.IndexOfToken(NoSkipTokenSet.s_ArrayInitNoSkipTokenSet, exception3) == -1) { context.UpdateWith(this.CurrentPositionContext()); exception3._partiallyComputedNode = new ArrayLiteral(context, list2); throw exception3; } if (JSToken.RightBracket == this.currentToken.token) { goto Label_0573; } } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ArrayInitNoSkipTokenSet); } } else { list2.Append(new ConstantWrapper(Microsoft.JScript.Missing.Value, this.currentToken.Clone())); } this.GetNextToken(); Label_0561: if (JSToken.RightBracket != this.currentToken.token) { goto Label_046D; } Label_0573: context.UpdateWith(this.currentToken); expression = new ArrayLiteral(context, list2); goto Label_0956; Label_0830: list3.context.UpdateWith(this.currentToken); context2.UpdateWith(this.currentToken); expression = new ObjectLiteral(context2, list3); goto Label_0956; Label_0881: str6 = JSKeyword.CanBeIdentifier(this.currentToken.token); if (str6 == null) { if (this.currentToken.token == JSToken.BitwiseAnd) { this.ReportError(JSError.WrongUseOfAddressOf); this.errorToken = null; this.GetNextToken(); return this.ParseLeftHandSideExpression(isMinus, ref canBeAttribute, warnForKeyword); } this.ReportError(JSError.ExpressionExpected); this.SkipTokensAndThrow(); goto Label_0956; } if (warnForKeyword) { switch (this.currentToken.token) { case JSToken.Boolean: case JSToken.Byte: case JSToken.Char: case JSToken.Double: case JSToken.Float: case JSToken.Int: case JSToken.Long: case JSToken.Short: case JSToken.Void: goto Label_08FC; } this.ForceReportInfo(JSError.KeywordUsedAsIdentifier); } Label_08FC: canBeAttribute = false; expression = new Lookup(str6, this.currentToken.Clone()); Label_0956: if (!flag) { this.GetNextToken(); } return this.MemberExpression(expression, newContexts, ref canBeAttribute); }
private AST ParseFunction(FieldAttributes visibilitySpec, bool inExpression, Context fncCtx, bool isMethod, bool isAbstract, bool isFinal, bool isInterface, CustomAttributeList customAttributes, Call function) { AST ast2; if (this.demandFullTrustOnFunctionCreation) { new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); } IdentifierLiteral id = null; AST rootObject = null; ArrayList parameters = null; TypeExpression expression = null; Block body = null; bool isGetter = false; bool isSetter = false; if (function == null) { this.GetNextToken(); if (isMethod) { if (JSToken.Get == this.currentToken.token) { isGetter = true; this.GetNextToken(); } else if (JSToken.Set == this.currentToken.token) { isSetter = true; this.GetNextToken(); } } if (JSToken.Identifier == this.currentToken.token) { id = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone()); this.GetNextToken(); if (JSToken.AccessField == this.currentToken.token) { if (isInterface) { this.ReportError(JSError.SyntaxError, true); } this.GetNextToken(); if (JSToken.Identifier == this.currentToken.token) { rootObject = new Lookup(id.context); id = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone()); this.GetNextToken(); while (JSToken.AccessField == this.currentToken.token) { this.GetNextToken(); if (JSToken.Identifier == this.currentToken.token) { rootObject = new Member(rootObject.context.CombineWith(this.currentToken), rootObject, new ConstantWrapper(id.ToString(), id.context)); id = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone()); this.GetNextToken(); } else { this.ReportError(JSError.NoIdentifier, true); } } } else { this.ReportError(JSError.NoIdentifier, true); } } } else { string identifier = JSKeyword.CanBeIdentifier(this.currentToken.token); if (identifier != null) { this.ForceReportInfo(JSError.KeywordUsedAsIdentifier, isMethod); id = new IdentifierLiteral(identifier, this.currentToken.Clone()); this.GetNextToken(); } else { if (!inExpression) { identifier = this.currentToken.GetCode(); this.ReportError(JSError.NoIdentifier, true); this.GetNextToken(); } else { identifier = ""; } id = new IdentifierLiteral(identifier, this.CurrentPositionContext()); } } } else { id = function.GetName(); } ArrayList blockType = this.blockType; this.blockType = new ArrayList(0x10); SimpleHashtable labelTable = this.labelTable; this.labelTable = new SimpleHashtable(0x10); FunctionScope item = new FunctionScope(this.Globals.ScopeStack.Peek(), isMethod); this.Globals.ScopeStack.Push(item); try { parameters = new ArrayList(); Context context = null; if (function == null) { if (JSToken.LeftParen != this.currentToken.token) { this.ReportError(JSError.NoLeftParen); } this.GetNextToken(); while (JSToken.RightParen != this.currentToken.token) { if (context != null) { this.ReportError(JSError.ParamListNotLast, context, true); context = null; } string str2 = null; TypeExpression type = null; this.noSkipTokenSet.Add(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet); try { try { if (JSToken.ParamArray == this.currentToken.token) { context = this.currentToken.Clone(); this.GetNextToken(); } if ((JSToken.Identifier != this.currentToken.token) && ((str2 = JSKeyword.CanBeIdentifier(this.currentToken.token)) == null)) { if (JSToken.LeftCurly == this.currentToken.token) { this.ReportError(JSError.NoRightParen); break; } if (JSToken.Comma == this.currentToken.token) { this.ReportError(JSError.SyntaxError, true); } else { this.ReportError(JSError.SyntaxError, true); this.SkipTokensAndThrow(); } } else { if (str2 == null) { str2 = this.scanner.GetIdentifier(); } else { this.ForceReportInfo(JSError.KeywordUsedAsIdentifier); } Context context2 = this.currentToken.Clone(); this.GetNextToken(); if (JSToken.Colon == this.currentToken.token) { type = this.ParseTypeExpression(); if (type != null) { context2.UpdateWith(type.context); } } CustomAttributeList list3 = null; if (context != null) { list3 = new CustomAttributeList(context); list3.Append(new Microsoft.JScript.CustomAttribute(context, new Lookup("...", context), new ASTList(null))); } parameters.Add(new ParameterDeclaration(context2, str2, type, list3)); } if (JSToken.RightParen == this.currentToken.token) { break; } if (JSToken.Comma != this.currentToken.token) { if (JSToken.LeftCurly == this.currentToken.token) { this.ReportError(JSError.NoRightParen); break; } if ((JSToken.Identifier == this.currentToken.token) && (type == null)) { this.ReportError(JSError.NoCommaOrTypeDefinitionError); } else { this.ReportError(JSError.NoComma); } } this.GetNextToken(); } catch (RecoveryTokenException exception) { if (this.IndexOfToken(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet, exception) == -1) { throw exception; } } continue; } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet); } } fncCtx.UpdateWith(this.currentToken); if (isGetter && (parameters.Count != 0)) { this.ReportError(JSError.BadPropertyDeclaration, true); isGetter = false; } else if (isSetter && (parameters.Count != 1)) { this.ReportError(JSError.BadPropertyDeclaration, true); isSetter = false; } this.GetNextToken(); if (JSToken.Colon == this.currentToken.token) { if (isSetter) { this.ReportError(JSError.SyntaxError); } this.noSkipTokenSet.Add(NoSkipTokenSet.s_StartBlockNoSkipTokenSet); try { expression = this.ParseTypeExpression(); } catch (RecoveryTokenException exception2) { if (this.IndexOfToken(NoSkipTokenSet.s_StartBlockNoSkipTokenSet, exception2) == -1) { exception2._partiallyComputedNode = null; throw exception2; } if (exception2._partiallyComputedNode != null) { expression = (TypeExpression) exception2._partiallyComputedNode; } } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_StartBlockNoSkipTokenSet); } if (isSetter) { expression = null; } } } else { function.GetParameters(parameters); } if ((JSToken.LeftCurly != this.currentToken.token) && (isAbstract || (isMethod && this.GuessIfAbstract()))) { if (!isAbstract) { isAbstract = true; this.ReportError(JSError.ShouldBeAbstract, fncCtx, true); } body = new Block(this.currentToken.Clone()); } else { if (JSToken.LeftCurly != this.currentToken.token) { this.ReportError(JSError.NoLeftCurly, true); } else if (isAbstract) { this.ReportError(JSError.AbstractWithBody, fncCtx, true); } this.blockType.Add(BlockType.Block); this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockNoSkipTokenSet); this.noSkipTokenSet.Add(NoSkipTokenSet.s_StartStatementNoSkipTokenSet); try { body = new Block(this.currentToken.Clone()); this.GetNextToken(); while (JSToken.RightCurly != this.currentToken.token) { try { body.Append(this.ParseStatement()); continue; } catch (RecoveryTokenException exception3) { if (exception3._partiallyComputedNode != null) { body.Append(exception3._partiallyComputedNode); } if (this.IndexOfToken(NoSkipTokenSet.s_StartStatementNoSkipTokenSet, exception3) == -1) { throw exception3; } continue; } } body.context.UpdateWith(this.currentToken); fncCtx.UpdateWith(this.currentToken); } catch (RecoveryTokenException exception4) { if (this.IndexOfToken(NoSkipTokenSet.s_BlockNoSkipTokenSet, exception4) == -1) { this.Globals.ScopeStack.Pop(); try { ParameterDeclaration[] declarationArray = new ParameterDeclaration[parameters.Count]; parameters.CopyTo(declarationArray); if (inExpression) { exception4._partiallyComputedNode = new FunctionExpression(fncCtx, id, declarationArray, expression, body, item, visibilitySpec); } else { exception4._partiallyComputedNode = new FunctionDeclaration(fncCtx, rootObject, id, declarationArray, expression, body, item, visibilitySpec, isMethod, isGetter, isSetter, isAbstract, isFinal, customAttributes); } if (customAttributes != null) { customAttributes.SetTarget(exception4._partiallyComputedNode); } } finally { this.Globals.ScopeStack.Push(item); } throw exception4; } } finally { this.blockType.RemoveAt(this.blockType.Count - 1); this.noSkipTokenSet.Remove(NoSkipTokenSet.s_StartStatementNoSkipTokenSet); this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockNoSkipTokenSet); } this.GetNextToken(); } } finally { this.blockType = blockType; this.labelTable = labelTable; this.Globals.ScopeStack.Pop(); } ParameterDeclaration[] array = new ParameterDeclaration[parameters.Count]; parameters.CopyTo(array); if (inExpression) { ast2 = new FunctionExpression(fncCtx, id, array, expression, body, item, visibilitySpec); } else { ast2 = new FunctionDeclaration(fncCtx, rootObject, id, array, expression, body, item, visibilitySpec, isMethod, isGetter, isSetter, isAbstract, isFinal, customAttributes); } if (customAttributes != null) { customAttributes.SetTarget(ast2); } return ast2; }
private AST ParseEnum(FieldAttributes visibilitySpec, Context enumCtx, CustomAttributeList customAttributes) { IdentifierLiteral name = null; AST ast = null; TypeExpression baseType = null; Block body = null; AST ast2; this.GetNextToken(); if (JSToken.Identifier == this.currentToken.token) { name = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone()); } else { this.ReportError(JSError.NoIdentifier); if ((JSToken.Colon != this.currentToken.token) && (JSToken.LeftCurly != this.currentToken.token)) { this.SkipTokensAndThrow(); } name = new IdentifierLiteral("##Missing Enum Name##" + s_cDummyName++, this.CurrentPositionContext()); } this.GetNextToken(); if (JSToken.Colon == this.currentToken.token) { this.noSkipTokenSet.Add(NoSkipTokenSet.s_EnumBaseTypeNoSkipTokenSet); try { ast = this.ParseQualifiedIdentifier(JSError.NeedType); } catch (RecoveryTokenException exception) { if (this.IndexOfToken(NoSkipTokenSet.s_ClassExtendsNoSkipTokenSet, exception) == -1) { exception._partiallyComputedNode = null; throw exception; } ast = exception._partiallyComputedNode; } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_EnumBaseTypeNoSkipTokenSet); } } if (ast != null) { baseType = new TypeExpression(ast); } if (JSToken.LeftCurly != this.currentToken.token) { this.ReportError(JSError.NoLeftCurly); } ArrayList blockType = this.blockType; this.blockType = new ArrayList(0x10); SimpleHashtable labelTable = this.labelTable; this.labelTable = new SimpleHashtable(0x10); this.Globals.ScopeStack.Push(new ClassScope(name, ((IActivationObject) this.Globals.ScopeStack.Peek()).GetGlobalScope())); try { body = this.ParseClassBody(true, false); enumCtx.UpdateWith(body.context); EnumDeclaration target = new EnumDeclaration(enumCtx, name, baseType, body, visibilitySpec, customAttributes); if (customAttributes != null) { customAttributes.SetTarget(target); } ast2 = target; } catch (RecoveryTokenException exception2) { enumCtx.UpdateWith(exception2._partiallyComputedNode.context); exception2._partiallyComputedNode = new EnumDeclaration(enumCtx, name, baseType, (Block) exception2._partiallyComputedNode, visibilitySpec, customAttributes); if (customAttributes != null) { customAttributes.SetTarget(exception2._partiallyComputedNode); } throw exception2; } finally { this.Globals.ScopeStack.Pop(); this.blockType = blockType; this.labelTable = labelTable; } return ast2; }
private AST ParseClass(FieldAttributes visibilitySpec, bool isStatic, Context classCtx, bool isAbstract, bool isFinal, CustomAttributeList customAttributes) { AST name = null; AST ast2 = null; TypeExpression superTypeExpression = null; Block body = null; TypeExpression[] expressionArray; AST ast4; ArrayList list = new ArrayList(); bool isInterface = JSToken.Interface == this.currentToken.token; this.GetNextToken(); if (JSToken.Identifier == this.currentToken.token) { name = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone()); } else { this.ReportError(JSError.NoIdentifier); if (((JSToken.Extends != this.currentToken.token) && (JSToken.Implements != this.currentToken.token)) && (JSToken.LeftCurly != this.currentToken.token)) { this.SkipTokensAndThrow(); } name = new IdentifierLiteral("##Missing Class Name##" + s_cDummyName++, this.CurrentPositionContext()); } this.GetNextToken(); if ((JSToken.Extends == this.currentToken.token) || (JSToken.Implements == this.currentToken.token)) { if (isInterface && (JSToken.Extends == this.currentToken.token)) { this.currentToken.token = JSToken.Implements; } if (JSToken.Extends == this.currentToken.token) { this.noSkipTokenSet.Add(NoSkipTokenSet.s_ClassExtendsNoSkipTokenSet); try { ast2 = this.ParseQualifiedIdentifier(JSError.NeedType); } catch (RecoveryTokenException exception) { if (this.IndexOfToken(NoSkipTokenSet.s_ClassExtendsNoSkipTokenSet, exception) == -1) { exception._partiallyComputedNode = null; throw exception; } ast2 = exception._partiallyComputedNode; } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ClassExtendsNoSkipTokenSet); } } if (JSToken.Implements == this.currentToken.token) { do { AST expression = null; this.noSkipTokenSet.Add(NoSkipTokenSet.s_ClassImplementsNoSkipTokenSet); try { expression = this.ParseQualifiedIdentifier(JSError.NeedType); list.Add(new TypeExpression(expression)); } catch (RecoveryTokenException exception2) { if (this.IndexOfToken(NoSkipTokenSet.s_ClassImplementsNoSkipTokenSet, exception2) == -1) { exception2._partiallyComputedNode = null; throw exception2; } if (exception2._partiallyComputedNode != null) { list.Add(new TypeExpression(exception2._partiallyComputedNode)); } } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ClassImplementsNoSkipTokenSet); } } while (JSToken.Comma == this.currentToken.token); } } if (ast2 != null) { superTypeExpression = new TypeExpression(ast2); } if (JSToken.LeftCurly != this.currentToken.token) { this.ReportError(JSError.NoLeftCurly); } ArrayList blockType = this.blockType; this.blockType = new ArrayList(0x10); SimpleHashtable labelTable = this.labelTable; this.labelTable = new SimpleHashtable(0x10); this.Globals.ScopeStack.Push(new ClassScope(name, ((IActivationObject) this.Globals.ScopeStack.Peek()).GetGlobalScope())); try { body = this.ParseClassBody(false, isInterface); classCtx.UpdateWith(body.context); expressionArray = new TypeExpression[list.Count]; list.CopyTo(expressionArray); Class target = new Class(classCtx, name, superTypeExpression, expressionArray, body, visibilitySpec, isAbstract, isFinal, isStatic, isInterface, customAttributes); if (customAttributes != null) { customAttributes.SetTarget(target); } ast4 = target; } catch (RecoveryTokenException exception3) { classCtx.UpdateWith(exception3._partiallyComputedNode.context); expressionArray = new TypeExpression[list.Count]; list.CopyTo(expressionArray); exception3._partiallyComputedNode = new Class(classCtx, name, superTypeExpression, expressionArray, (Block) exception3._partiallyComputedNode, visibilitySpec, isAbstract, isFinal, isStatic, isInterface, customAttributes); if (customAttributes != null) { customAttributes.SetTarget(exception3._partiallyComputedNode); } throw exception3; } finally { this.Globals.ScopeStack.Pop(); this.blockType = blockType; this.labelTable = labelTable; } return ast4; }