internal override void TranslateToILDelete(ILGenerator il, Type rtype) { IReflect ir = this.func.InferType(null); Type obType = Convert.ToType(ir); this.func.TranslateToIL(il, obType); this.args.TranslateToIL(il, typeof(Object[])); if (this.func is Binding) { MethodInfo deleteOp; if (ir is ClassScope) { deleteOp = ((ClassScope)ir).owner.deleteOpMethod; } else { deleteOp = ir.GetMethod("op_Delete", BindingFlags.ExactBinding | BindingFlags.Public | BindingFlags.Static, null, new Type[] { obType, typeof(Object[]) }, null); } if (deleteOp != null && (deleteOp.Attributes & MethodAttributes.SpecialName) != 0 && deleteOp.ReturnType == Typeob.Boolean) { il.Emit(OpCodes.Call, deleteOp); Convert.Emit(this, il, Typeob.Boolean, rtype); return; } } ConstantWrapper.TranslateToILInt(il, this.args.count - 1); il.Emit(OpCodes.Ldelem_Ref); Convert.Emit(this, il, Typeob.Object, Typeob.String); il.Emit(OpCodes.Call, CompilerGlobals.deleteMemberMethod); Convert.Emit(this, il, Typeob.Boolean, rtype); }
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 override void TranslateToILPreSetPlusGet(ILGenerator il) { if (base.isFullyResolved) { base.TranslateToILPreSetPlusGet(il); } else { Label label = il.DefineLabel(); Label label2 = il.DefineLabel(); LocalBuilder local = this.fieldLoc = il.DeclareLocal(Typeob.FieldInfo); base.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.scriptObjectStackTopMethod); il.Emit(OpCodes.Castclass, Typeob.IActivationObject); il.Emit(OpCodes.Ldstr, base.name); ConstantWrapper.TranslateToILInt(il, this.lexLevel); il.Emit(OpCodes.Callvirt, CompilerGlobals.getFieldMethod); il.Emit(OpCodes.Stloc, local); il.Emit(OpCodes.Ldloc, local); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Bne_Un_S, label2); base.TranslateToILPreSetPlusGet(il); il.Emit(OpCodes.Br_S, label); il.MarkLabel(label2); if (this.thereIsAnObjectOnTheStack) { il.Emit(OpCodes.Ldnull); } il.Emit(OpCodes.Ldloc, this.fieldLoc); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Callvirt, CompilerGlobals.getFieldValueMethod); il.MarkLabel(label); } }
internal static void TranslateToBitCountMask(ILGenerator il, Type type, AST operand2) { int arg = 0; switch (Type.GetTypeCode(type)) { case TypeCode.SByte: case TypeCode.Byte: arg = 7; break; case TypeCode.Int16: case TypeCode.UInt16: arg = 15; break; case TypeCode.Int32: case TypeCode.UInt32: arg = 0x1f; break; case TypeCode.Int64: case TypeCode.UInt64: arg = 0x3f; break; } ConstantWrapper wrapper = operand2 as ConstantWrapper; if ((wrapper == null) || (Microsoft.JScript.Convert.ToInt32(wrapper.value) > arg)) { il.Emit(OpCodes.Ldc_I4_S, arg); il.Emit(OpCodes.And); } }
internal override void TranslateToILDelete(ILGenerator il, Type rtype) { IReflect ir = this.func.InferType(null); Type type = Microsoft.JScript.Convert.ToType(ir); this.func.TranslateToIL(il, type); this.args.TranslateToIL(il, Typeob.ArrayOfObject); if (this.func is Binding) { MethodInfo deleteOpMethod; if (ir is ClassScope) { deleteOpMethod = ((ClassScope)ir).owner.deleteOpMethod; } else { deleteOpMethod = ir.GetMethod("op_Delete", BindingFlags.ExactBinding | BindingFlags.Public | BindingFlags.Static, null, new Type[] { type, Typeob.ArrayOfObject }, null); } if (((deleteOpMethod != null) && ((deleteOpMethod.Attributes & MethodAttributes.SpecialName) != MethodAttributes.PrivateScope)) && (deleteOpMethod.ReturnType == Typeob.Boolean)) { il.Emit(OpCodes.Call, deleteOpMethod); Microsoft.JScript.Convert.Emit(this, il, Typeob.Boolean, rtype); return; } } ConstantWrapper.TranslateToILInt(il, this.args.count - 1); il.Emit(OpCodes.Ldelem_Ref); Microsoft.JScript.Convert.Emit(this, il, Typeob.Object, Typeob.String); il.Emit(OpCodes.Call, CompilerGlobals.deleteMemberMethod); Microsoft.JScript.Convert.Emit(this, il, Typeob.Boolean, rtype); }
internal static void TranslateToBitCountMask(ILGenerator il, Type type, AST operand2) { int mask = 0; switch (Type.GetTypeCode(type)) { case TypeCode.SByte: case TypeCode.Byte: mask = 7; break; case TypeCode.UInt16: case TypeCode.Int16: mask = 15; break; case TypeCode.Int32: case TypeCode.UInt32: mask = 31; break; case TypeCode.Int64: case TypeCode.UInt64: mask = 63; break; } ConstantWrapper cw = operand2 as ConstantWrapper; if (cw != null) { int m = Convert.ToInt32(cw.value); if (m <= mask) { return; } } il.Emit(OpCodes.Ldc_I4_S, mask); il.Emit(OpCodes.And); }
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 override void TranslateToILPreSetPlusGet(ILGenerator il) { if (this.isFullyResolved) { base.TranslateToILPreSetPlusGet(il); return; } //Need to do a dynamic lookup to see if there is a dynamically introduced (by eval or with) hiding definition. //Leave a FieldInfo on the stack if there is such a member, otherwise leave null on the stack Label done = il.DefineLabel(); Label latebound = il.DefineLabel(); LocalBuilder fieldTok = this.fieldLoc = il.DeclareLocal(Typeob.FieldInfo); this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.scriptObjectStackTopMethod); il.Emit(OpCodes.Castclass, Typeob.IActivationObject); il.Emit(OpCodes.Ldstr, this.name); ConstantWrapper.TranslateToILInt(il, this.lexLevel); il.Emit(OpCodes.Callvirt, CompilerGlobals.getFieldMethod); il.Emit(OpCodes.Stloc, fieldTok); il.Emit(OpCodes.Ldloc, fieldTok); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Bne_Un_S, latebound); base.TranslateToILPreSetPlusGet(il); il.Emit(OpCodes.Br_S, done); il.MarkLabel(latebound); if (this.thereIsAnObjectOnTheStack) { il.Emit(OpCodes.Ldnull); //Push a dummy object so that both latebound and early bound code paths leave an object on the stack } il.Emit(OpCodes.Ldloc, this.fieldLoc); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Callvirt, CompilerGlobals.getFieldValueMethod); il.MarkLabel(done); }
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 object EvaluateAsType() { object memberValue = this.rootObject.EvaluateAsWrappedNamespace(false).GetMemberValue(base.name); if ((memberValue != null) && !(memberValue is Microsoft.JScript.Missing)) { return(memberValue); } object obj3 = null; Member rootObject = this.rootObject as Member; if (rootObject == null) { Lookup lookup = this.rootObject as Lookup; if (lookup == null) { return(null); } ConstantWrapper wrapper = lookup.PartiallyEvaluate() as ConstantWrapper; if (wrapper == null) { JSGlobalField member = lookup.member as JSGlobalField; if ((member == null) || !member.IsLiteral) { return(null); } obj3 = member.value; } else { obj3 = wrapper.value; } } else { obj3 = rootObject.EvaluateAsType(); } ClassScope scope = obj3 as ClassScope; if (scope != null) { MemberInfo[] infoArray = scope.GetMember(base.name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance); if (infoArray.Length != 0) { JSMemberField field2 = infoArray[0] as JSMemberField; if (((field2 != null) && field2.IsLiteral) && ((field2.value is ClassScope) && (field2.IsPublic || field2.IsAccessibleFrom(base.Engine.ScriptObjectStackTop())))) { return(field2.value); } } return(null); } Type type = obj3 as Type; if (type != null) { return(type.GetNestedType(base.name)); } return(null); }
internal override void TranslateToILInitializer(ILGenerator il) { //This is executed only once for a given scope. It creates a FunctionObject and stores it in a private local. //The FunctionObject is then used to construct a new closure every time the function expression is evaluated. //This way, what is a method to IL, ends up as a ScriptFunction object that behaves just like an ECMAScript function. this.func.TranslateToIL(compilerGlobals); this.func_local = il.DeclareLocal(Typeob.FunctionObject); il.Emit(OpCodes.Ldtoken, this.func.classwriter); il.Emit(OpCodes.Ldstr, this.name); il.Emit(OpCodes.Ldstr, this.func.GetName()); int n = this.func.formal_parameters.Length; ConstantWrapper.TranslateToILInt(il, n); il.Emit(OpCodes.Newarr, Typeob.String); for (int i = 0; i < n; i++) { il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, i); il.Emit(OpCodes.Ldstr, this.func.formal_parameters[i]); il.Emit(OpCodes.Stelem_Ref); } n = this.func.fields.Length; ConstantWrapper.TranslateToILInt(il, n); il.Emit(OpCodes.Newarr, Typeob.JSLocalField); for (int i = 0; i < n; i++) { JSLocalField field = this.func.fields[i]; il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, i); il.Emit(OpCodes.Ldstr, field.Name); il.Emit(OpCodes.Ldtoken, field.FieldType); ConstantWrapper.TranslateToILInt(il, field.slotNumber); il.Emit(OpCodes.Newobj, CompilerGlobals.jsLocalFieldConstructor); il.Emit(OpCodes.Stelem_Ref); } if (this.func.must_save_stack_locals) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } if (this.func.hasArgumentsObject) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } il.Emit(OpCodes.Ldstr, this.func.ToString()); this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.jScriptFunctionExpressionMethod); il.Emit(OpCodes.Stloc, this.func_local); }
internal override void TranslateToILInitializer(ILGenerator il) { this.func.TranslateToIL(base.compilerGlobals); this.func_local = il.DeclareLocal(Typeob.FunctionObject); il.Emit(OpCodes.Ldtoken, this.func.classwriter); il.Emit(OpCodes.Ldstr, this.name); il.Emit(OpCodes.Ldstr, this.func.GetName()); int length = this.func.formal_parameters.Length; ConstantWrapper.TranslateToILInt(il, length); il.Emit(OpCodes.Newarr, Typeob.String); for (int i = 0; i < length; i++) { il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, i); il.Emit(OpCodes.Ldstr, this.func.formal_parameters[i]); il.Emit(OpCodes.Stelem_Ref); } length = this.func.fields.Length; ConstantWrapper.TranslateToILInt(il, length); il.Emit(OpCodes.Newarr, Typeob.JSLocalField); for (int j = 0; j < length; j++) { JSLocalField field = this.func.fields[j]; il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, j); il.Emit(OpCodes.Ldstr, field.Name); il.Emit(OpCodes.Ldtoken, field.FieldType); ConstantWrapper.TranslateToILInt(il, field.slotNumber); il.Emit(OpCodes.Newobj, CompilerGlobals.jsLocalFieldConstructor); il.Emit(OpCodes.Stelem_Ref); } if (this.func.must_save_stack_locals) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } if (this.func.hasArgumentsObject) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } il.Emit(OpCodes.Ldstr, this.func.ToString()); base.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.jScriptFunctionExpressionMethod); il.Emit(OpCodes.Stloc, this.func_local); }
internal override void TranslateToILInitializer(ILGenerator il) { IReflect reflect = this.InferType(null); base.operand.TranslateToILInitializer(il); if (reflect == Typeob.Object) { this.metaData = il.DeclareLocal(Typeob.NumericUnary); ConstantWrapper.TranslateToILInt(il, (int)this.operatorTok); il.Emit(OpCodes.Newobj, CompilerGlobals.numericUnaryConstructor); il.Emit(OpCodes.Stloc, (LocalBuilder)this.metaData); } }
internal override void TranslateToILInitializer(ILGenerator il) { IReflect rtype = this.InferType(null); this.operand.TranslateToILInitializer(il); if (rtype != Typeob.Object) { return; } this.metaData = il.DeclareLocal(typeof(PostOrPrefixOperator)); ConstantWrapper.TranslateToILInt(il, (int)this.operatorTok); il.Emit(OpCodes.Newobj, CompilerGlobals.postOrPrefixConstructor); il.Emit(OpCodes.Stloc, (LocalBuilder)this.metaData); }
internal void EmitLocalInfoForFields(ILGenerator il) { foreach (JSLocalField field in this.localFieldsForDebugInfo) { ((LocalBuilder)field.metaData).SetLocalSymInfo(field.debuggerName); } if (this.parent is GlobalScope) { LocalBuilder loc = il.DeclareLocal(Typeob.Int32); loc.SetLocalSymInfo("scopeId for catch block"); ConstantWrapper.TranslateToILInt(il, this.scopeId); il.Emit(OpCodes.Stloc, loc); } }
internal override void TranslateToILInitializer(ILGenerator il) { this.operand1.TranslateToILInitializer(il); this.operand2.TranslateToILInitializer(il); MethodInfo oper = this.GetOperator(this.operand1.InferType(null), this.operand2.InferType(null)); if (oper != null) { this.metaData = oper; return; } if (this.operand1 is ConstantWrapper) { Object val = this.operand1.Evaluate(); if (val == null) { this.type1 = Typeob.Empty; } else if (val is DBNull) { this.type1 = Typeob.Null; } } if (this.operand2 is ConstantWrapper) { Object val = this.operand2.Evaluate(); if (val == null) { this.type2 = Typeob.Empty; } else if (val is DBNull) { this.type2 = Typeob.Null; } } if (this.type1 == Typeob.Empty || this.type1 == Typeob.Null || this.type2 == Typeob.Empty || this.type2 == Typeob.Null) { return; } if ((this.type1.IsPrimitive || this.type1 == Typeob.String || Typeob.JSObject.IsAssignableFrom(this.type1)) && (this.type2.IsPrimitive || this.type2 == Typeob.String || Typeob.JSObject.IsAssignableFrom(this.type2))) { return; } this.metaData = il.DeclareLocal(Typeob.Equality); ConstantWrapper.TranslateToILInt(il, (int)this.operatorTok); il.Emit(OpCodes.Newobj, CompilerGlobals.equalityConstructor); il.Emit(OpCodes.Stloc, (LocalBuilder)this.metaData); }
internal override void TranslateToILCall(ILGenerator il, Type rtype, ASTList argList, bool construct, bool brackets) { if (base.isFullyResolved) { base.TranslateToILCall(il, rtype, argList, construct, brackets); } else { Label label = il.DefineLabel(); Label label2 = il.DefineLabel(); base.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.scriptObjectStackTopMethod); il.Emit(OpCodes.Castclass, Typeob.IActivationObject); il.Emit(OpCodes.Ldstr, base.name); ConstantWrapper.TranslateToILInt(il, this.lexLevel); il.Emit(OpCodes.Callvirt, CompilerGlobals.getMemberValueMethod); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Call, CompilerGlobals.isMissingMethod); il.Emit(OpCodes.Brfalse, label); il.Emit(OpCodes.Pop); base.TranslateToILCall(il, Typeob.Object, argList, construct, brackets); il.Emit(OpCodes.Br, label2); il.MarkLabel(label); this.TranslateToILDefaultThisObject(il); argList.TranslateToIL(il, Typeob.ArrayOfObject); if (construct) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } if (brackets) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } base.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.callValue2Method); il.MarkLabel(label2); Microsoft.JScript.Convert.Emit(this, il, Typeob.Object, rtype); } }
internal override void TranslateToILCall(ILGenerator il, Type rtype, ASTList argList, bool construct, bool brackets) { if (this.isFullyResolved) { base.TranslateToILCall(il, rtype, argList, construct, brackets); return; } //Need to do a dynamic lookup to see if there is a dynamically introduced (by eval or with) hiding definition. Label lateBoundCall = il.DefineLabel(); Label done = il.DefineLabel(); this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.scriptObjectStackTopMethod); il.Emit(OpCodes.Castclass, Typeob.IActivationObject); il.Emit(OpCodes.Ldstr, this.name); ConstantWrapper.TranslateToILInt(il, this.lexLevel); il.Emit(OpCodes.Callvirt, CompilerGlobals.getMemberValueMethod); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Call, CompilerGlobals.isMissingMethod); il.Emit(OpCodes.Brfalse, lateBoundCall); //dynamic lookup succeeded, do not call early bound method il.Emit(OpCodes.Pop); //The dynamic lookup returned Missing.Value, discard it and go on to use the value from the early bound location. base.TranslateToILCall(il, Typeob.Object, argList, construct, brackets); il.Emit(OpCodes.Br, done); //Skip over the latebound call sequence il.MarkLabel(lateBoundCall); this.TranslateToILDefaultThisObject(il); argList.TranslateToIL(il, Typeob.ArrayOfObject); if (construct) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } if (brackets) { il.Emit(OpCodes.Ldc_I4_1); } else { il.Emit(OpCodes.Ldc_I4_0); } this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, CompilerGlobals.callValue2Method); il.MarkLabel(done); Convert.Emit(this, il, Typeob.Object, rtype); }
internal override void TranslateToILInitializer(ILGenerator il) { base.operand1.TranslateToILInitializer(il); base.operand2.TranslateToILInitializer(il); MethodInfo @operator = base.GetOperator(base.operand1.InferType(null), base.operand2.InferType(null)); if (@operator != null) { this.metaData = @operator; } else { if (base.operand1 is ConstantWrapper) { object obj2 = base.operand1.Evaluate(); if (obj2 == null) { base.type1 = Typeob.Empty; } else if (obj2 is DBNull) { base.type1 = Typeob.Null; } } if (base.operand2 is ConstantWrapper) { object obj3 = base.operand2.Evaluate(); if (obj3 == null) { base.type2 = Typeob.Empty; } else if (obj3 is DBNull) { base.type2 = Typeob.Null; } } if ((((base.type1 != Typeob.Empty) && (base.type1 != Typeob.Null)) && ((base.type2 != Typeob.Empty) && (base.type2 != Typeob.Null))) && (((!base.type1.IsPrimitive && (base.type1 != Typeob.String)) && !Typeob.JSObject.IsAssignableFrom(base.type1)) || ((!base.type2.IsPrimitive && (base.type2 != Typeob.String)) && !Typeob.JSObject.IsAssignableFrom(base.type2)))) { this.metaData = il.DeclareLocal(Typeob.Equality); ConstantWrapper.TranslateToILInt(il, (int)base.operatorTok); il.Emit(OpCodes.Newobj, CompilerGlobals.equalityConstructor); il.Emit(OpCodes.Stloc, (LocalBuilder)this.metaData); } } }
internal override void TranslateToILInitializer(ILGenerator il) { base.operand1.TranslateToILInitializer(il); base.operand2.TranslateToILInitializer(il); MethodInfo @operator = base.GetOperator(base.operand1.InferType(null), base.operand2.InferType(null)); if (@operator != null) { this.metaData = @operator; } else if ((!base.type1.IsPrimitive && !Typeob.JSObject.IsAssignableFrom(base.type1)) || (!base.type2.IsPrimitive && !Typeob.JSObject.IsAssignableFrom(base.type2))) { this.metaData = il.DeclareLocal(Typeob.Relational); ConstantWrapper.TranslateToILInt(il, (int)base.operatorTok); il.Emit(OpCodes.Newobj, CompilerGlobals.relationalConstructor); il.Emit(OpCodes.Stloc, (LocalBuilder)this.metaData); } }
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 override void TranslateToIL(ILGenerator il, Type rtype) { if (this.context.document.debugOn) { il.Emit(OpCodes.Nop); } ASTList astList = this.operand; int n = astList.count; for (int i = 0; i < n; i++) { AST ast = astList[i]; IReflect ir = ast.InferType(null); if (ir == Typeob.String) { ast.TranslateToIL(il, Typeob.String); } else { ast.TranslateToIL(il, Typeob.Object); ConstantWrapper.TranslateToILInt(il, 1); il.Emit(OpCodes.Call, CompilerGlobals.toStringMethod); } if (i == n - 1) { il.Emit(OpCodes.Call, CompilerGlobals.writeLineMethod); } else { il.Emit(OpCodes.Call, CompilerGlobals.writeMethod); } } if (n == 0) { il.Emit(OpCodes.Ldstr, ""); il.Emit(OpCodes.Call, CompilerGlobals.writeLineMethod); } if (rtype != Typeob.Void) { il.Emit(OpCodes.Ldsfld, CompilerGlobals.undefinedField); Convert.Emit(this, il, Typeob.Object, rtype); } }
private void TranslateToILArray(ILGenerator il, Type etype) { int count = this.elements.count; ConstantWrapper.TranslateToILInt(il, count); Type.GetTypeCode(etype); il.Emit(OpCodes.Newarr, etype); for (int i = 0; i < count; i++) { il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, i); if (etype.IsValueType && !etype.IsPrimitive) { il.Emit(OpCodes.Ldelema, etype); } this.elements[i].TranslateToIL(il, etype); Binding.TranslateToStelem(il, etype); } }
internal override void TranslateToIL(ILGenerator il, Type rtype) { if (base.context.document.debugOn) { il.Emit(OpCodes.Nop); } ASTList operand = this.operand; int count = operand.count; for (int i = 0; i < count; i++) { AST ast = operand[i]; if (ast.InferType(null) == Typeob.String) { ast.TranslateToIL(il, Typeob.String); } else { ast.TranslateToIL(il, Typeob.Object); ConstantWrapper.TranslateToILInt(il, 1); il.Emit(OpCodes.Call, CompilerGlobals.toStringMethod); } if (i == (count - 1)) { il.Emit(OpCodes.Call, CompilerGlobals.writeLineMethod); } else { il.Emit(OpCodes.Call, CompilerGlobals.writeMethod); } } if (count == 0) { il.Emit(OpCodes.Ldstr, ""); il.Emit(OpCodes.Call, CompilerGlobals.writeLineMethod); } if (rtype != Typeob.Void) { il.Emit(OpCodes.Ldsfld, CompilerGlobals.undefinedField); Microsoft.JScript.Convert.Emit(this, il, Typeob.Object, rtype); } }
internal override void TranslateToIL(ILGenerator il, Type rtype) { Label label = (Label)base.compilerGlobals.BreakLabelStack.Peek(this.completion.Exit - 1); base.context.EmitLineInfo(il); if (this.leavesFinally) { ConstantWrapper.TranslateToILInt(il, base.compilerGlobals.BreakLabelStack.Size() - this.completion.Exit); il.Emit(OpCodes.Newobj, CompilerGlobals.breakOutOfFinallyConstructor); il.Emit(OpCodes.Throw); } else if (base.compilerGlobals.InsideProtectedRegion) { il.Emit(OpCodes.Leave, label); } else { il.Emit(OpCodes.Br, label); } }
internal override void TranslateToIL(ILGenerator il, Type rtype) { Label break_label = (Label)compilerGlobals.BreakLabelStack.Peek(this.completion.Exit - 1); this.context.EmitLineInfo(il); if (this.leavesFinally) { ConstantWrapper.TranslateToILInt(il, compilerGlobals.BreakLabelStack.Size() - this.completion.Exit); il.Emit(OpCodes.Newobj, CompilerGlobals.breakOutOfFinallyConstructor); il.Emit(OpCodes.Throw); } else if (compilerGlobals.InsideProtectedRegion) { il.Emit(OpCodes.Leave, break_label); } else { il.Emit(OpCodes.Br, break_label); } //Do not leave anything on the stack, even if rtype != Void.class }
internal override void TranslateToILInitializer(ILGenerator il) { this.operand1.TranslateToILInitializer(il); this.operand2.TranslateToILInitializer(il); MethodInfo oper = this.GetOperator(this.operand1.InferType(null), this.operand2.InferType(null)); if (oper != null) { this.metaData = oper; return; } if ((this.type1.IsPrimitive || Typeob.JSObject.IsAssignableFrom(this.type1)) && (this.type2.IsPrimitive || Typeob.JSObject.IsAssignableFrom(this.type2))) { return; } this.metaData = il.DeclareLocal(Typeob.Relational); ConstantWrapper.TranslateToILInt(il, (int)this.operatorTok); il.Emit(OpCodes.Newobj, CompilerGlobals.relationalConstructor); il.Emit(OpCodes.Stloc, (LocalBuilder)this.metaData); }
internal override void TranslateToIL(ILGenerator il, Type rtype) { Type elementType = rtype.GetElementType(); int count = this.count; ConstantWrapper.TranslateToILInt(il, count); il.Emit(OpCodes.Newarr, elementType); bool flag = elementType.IsValueType && !elementType.IsPrimitive; AST[] list = this.list; for (int i = 0; i < count; i++) { il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, i); list[i].TranslateToIL(il, elementType); if (flag) { il.Emit(OpCodes.Ldelema, elementType); } Binding.TranslateToStelem(il, elementType); } }
internal override void TranslateToIL(ILGenerator il, Type rtype) { if ((this.enclosingFunctionScope != null) && (this.enclosingFunctionScope.owner != null)) { this.enclosingFunctionScope.owner.TranslateToILToSaveLocals(il); } this.operand.TranslateToIL(il, Typeob.Object); MethodInfo meth = null; ConstantWrapper unsafeOption = this.unsafeOption as ConstantWrapper; if (unsafeOption != null) { string str = unsafeOption.value as string; if ((str != null) && (str == "unsafe")) { meth = CompilerGlobals.jScriptEvaluateMethod1; } } if (meth == null) { meth = CompilerGlobals.jScriptEvaluateMethod2; if (this.unsafeOption == null) { il.Emit(OpCodes.Ldnull); } else { this.unsafeOption.TranslateToIL(il, Typeob.Object); } } base.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, meth); Microsoft.JScript.Convert.Emit(this, il, Typeob.Object, rtype); if ((this.enclosingFunctionScope != null) && (this.enclosingFunctionScope.owner != null)) { this.enclosingFunctionScope.owner.TranslateToILToRestoreLocals(il); } }
internal override void TranslateToIL(ILGenerator il, Type rtype) { if (this.enclosingFunctionScope != null && this.enclosingFunctionScope.owner != null) { this.enclosingFunctionScope.owner.TranslateToILToSaveLocals(il); } this.operand.TranslateToIL(il, Typeob.Object); MethodInfo evaluateMethod = null; ConstantWrapper cw = this.unsafeOption as ConstantWrapper; if (cw != null) { string s = cw.value as string; if (s != null && s == "unsafe") { evaluateMethod = CompilerGlobals.jScriptEvaluateMethod1; } } if (evaluateMethod == null) { evaluateMethod = CompilerGlobals.jScriptEvaluateMethod2; if (this.unsafeOption == null) { il.Emit(OpCodes.Ldnull); } else { this.unsafeOption.TranslateToIL(il, Typeob.Object); } } this.EmitILToLoadEngine(il); il.Emit(OpCodes.Call, evaluateMethod); Convert.Emit(this, il, Typeob.Object, rtype); if (this.enclosingFunctionScope != null && this.enclosingFunctionScope.owner != null) { this.enclosingFunctionScope.owner.TranslateToILToRestoreLocals(il); } }
internal override void TranslateToIL(ILGenerator il, Type rtype) { Debug.Assert(rtype.IsArray); Type etype = rtype.GetElementType(); int n = this.count; ConstantWrapper.TranslateToILInt(il, n); il.Emit(OpCodes.Newarr, etype); bool doLdelema = etype.IsValueType && !etype.IsPrimitive; AST[] list = this.list; for (int i = 0; i < n; i++) { il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, i); list[i].TranslateToIL(il, etype); if (doLdelema) { il.Emit(OpCodes.Ldelema, etype); } Binding.TranslateToStelem(il, etype); } }
private int TranslateToILArrayOfStrings(ILGenerator il, int n) { int len = n + 2; if (this.operand1 is Plus && this.type1 == Typeob.String) { len = ((Plus)this.operand1).TranslateToILArrayOfStrings(il, n + 1); } else { ConstantWrapper.TranslateToILInt(il, len); il.Emit(OpCodes.Newarr, Typeob.String); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldc_I4_0); Plus.TranslateToStringWithSpecialCaseForNull(il, this.operand1); il.Emit(OpCodes.Stelem_Ref); } il.Emit(OpCodes.Dup); ConstantWrapper.TranslateToILInt(il, len - 1 - n); Plus.TranslateToStringWithSpecialCaseForNull(il, this.operand2); il.Emit(OpCodes.Stelem_Ref); return(len); }
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 MemberExpression(AST expression, ArrayList newContexts, out bool canBeQualid, ref bool canBeAttribute) { AST ast; bool flag = false; canBeQualid = true; Label_0005: this.noSkipTokenSet.Add(NoSkipTokenSet.s_MemberExprNoSkipTokenSet); try { try { ASTList list; ConstantWrapper wrapper; switch (this.currentToken.token) { case JSToken.LeftParen: if (!flag) { break; } canBeAttribute = false; goto Label_0048; case JSToken.LeftBracket: canBeQualid = false; canBeAttribute = false; this.noSkipTokenSet.Add(NoSkipTokenSet.s_BracketToken); try { list = this.ParseExpressionList(JSToken.RightBracket); } catch (RecoveryTokenException exception3) { if (this.IndexOfToken(NoSkipTokenSet.s_BracketToken, exception3) == -1) { if (exception3._partiallyComputedNode != null) { exception3._partiallyComputedNode = new Call(expression.context.CombineWith(this.currentToken.Clone()), expression, (ASTList) exception3._partiallyComputedNode, true); } else { exception3._partiallyComputedNode = expression; } throw exception3; } list = (ASTList) exception3._partiallyComputedNode; } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BracketToken); } expression = new Call(expression.context.CombineWith(this.currentToken.Clone()), expression, list, true); if ((newContexts != null) && (newContexts.Count > 0)) { ((Context) newContexts[newContexts.Count - 1]).UpdateWith(expression.context); expression.context = (Context) newContexts[newContexts.Count - 1]; ((Call) expression).isConstructor = true; newContexts.RemoveAt(newContexts.Count - 1); } this.GetNextToken(); goto Label_0005; case JSToken.AccessField: { if (flag) { canBeAttribute = false; } wrapper = null; this.GetNextToken(); if (JSToken.Identifier == this.currentToken.token) { goto Label_03EF; } string str2 = JSKeyword.CanBeIdentifier(this.currentToken.token); if (str2 != null) { this.ForceReportInfo(JSError.KeywordUsedAsIdentifier); wrapper = new ConstantWrapper(str2, this.currentToken.Clone()); } else { this.ReportError(JSError.NoIdentifier); this.SkipTokensAndThrow(expression); } goto Label_040C; } default: if (newContexts != null) { while (newContexts.Count > 0) { ((Context) newContexts[newContexts.Count - 1]).UpdateWith(expression.context); expression = new Call((Context) newContexts[newContexts.Count - 1], expression, new ASTList(this.CurrentPositionContext()), false); ((Call) expression).isConstructor = true; newContexts.RemoveAt(newContexts.Count - 1); } } return expression; } flag = true; Label_0048: canBeQualid = false; list = null; RecoveryTokenException exception = null; this.noSkipTokenSet.Add(NoSkipTokenSet.s_ParenToken); try { list = this.ParseExpressionList(JSToken.RightParen); } catch (RecoveryTokenException exception2) { list = (ASTList) exception2._partiallyComputedNode; if (this.IndexOfToken(NoSkipTokenSet.s_ParenToken, exception2) == -1) { exception = exception2; } } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ParenToken); } if (expression is Lookup) { string str = expression.ToString(); if (str.Equals("eval")) { expression.context.UpdateWith(list.context); if (list.count == 1) { expression = new Eval(expression.context, list[0], null); } else if (list.count > 1) { expression = new Eval(expression.context, list[0], list[1]); } else { expression = new Eval(expression.context, new ConstantWrapper("", this.CurrentPositionContext()), null); } canBeAttribute = false; } else if (this.Globals.engine.doPrint && str.Equals("print")) { expression.context.UpdateWith(list.context); expression = new Print(expression.context, list); canBeAttribute = false; } else { expression = new Call(expression.context.CombineWith(list.context), expression, list, false); } } else { expression = new Call(expression.context.CombineWith(list.context), expression, list, false); } if ((newContexts != null) && (newContexts.Count > 0)) { ((Context) newContexts[newContexts.Count - 1]).UpdateWith(expression.context); if (expression is Call) { expression.context = (Context) newContexts[newContexts.Count - 1]; } else { expression = new Call((Context) newContexts[newContexts.Count - 1], expression, new ASTList(this.CurrentPositionContext()), false); } ((Call) expression).isConstructor = true; newContexts.RemoveAt(newContexts.Count - 1); } if (exception != null) { exception._partiallyComputedNode = expression; throw exception; } this.GetNextToken(); goto Label_0005; Label_03EF: wrapper = new ConstantWrapper(this.scanner.GetIdentifier(), this.currentToken.Clone()); Label_040C: this.GetNextToken(); expression = new Member(expression.context.CombineWith(wrapper.context), expression, wrapper); } catch (RecoveryTokenException exception4) { if (this.IndexOfToken(NoSkipTokenSet.s_MemberExprNoSkipTokenSet, exception4) == -1) { throw exception4; } expression = exception4._partiallyComputedNode; } goto Label_0005; } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_MemberExprNoSkipTokenSet); } return ast; }
private AST ParseScopeSequence(AST qualid, JSError error) { ConstantWrapper memberName = null; string str = null; do { this.GetNextToken(); if (JSToken.Identifier != this.currentToken.token) { str = JSKeyword.CanBeIdentifier(this.currentToken.token); if (str != null) { this.ForceReportInfo(JSError.KeywordUsedAsIdentifier); memberName = new ConstantWrapper(str, this.currentToken.Clone()); } else { this.ReportError(error, true); this.SkipTokensAndThrow(qualid); } } else { memberName = new ConstantWrapper(this.scanner.GetIdentifier(), this.currentToken.Clone()); } qualid = new Member(qualid.context.CombineWith(this.currentToken), qualid, memberName); this.GetNextToken(); } while (JSToken.AccessField == this.currentToken.token); return qualid; }
private AST ParseSwitchStatement() { Context context = this.currentToken.Clone(); AST expression = null; ASTList cases = null; this.blockType.Add(BlockType.Switch); try { this.GetNextToken(); if (JSToken.LeftParen != this.currentToken.token) { this.ReportError(JSError.NoLeftParen); } this.GetNextToken(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); this.noSkipTokenSet.Add(NoSkipTokenSet.s_SwitchNoSkipTokenSet); try { expression = this.ParseExpression(); if (JSToken.RightParen != this.currentToken.token) { this.ReportError(JSError.NoRightParen); } this.GetNextToken(); if (JSToken.LeftCurly != this.currentToken.token) { this.ReportError(JSError.NoLeftCurly); } this.GetNextToken(); } catch (RecoveryTokenException exception) { if ((this.IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exception) == -1) && (this.IndexOfToken(NoSkipTokenSet.s_SwitchNoSkipTokenSet, exception) == -1)) { exception._partiallyComputedNode = null; throw exception; } if (exception._partiallyComputedNode == null) { expression = new ConstantWrapper(true, this.CurrentPositionContext()); } else { expression = exception._partiallyComputedNode; } if (this.IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exception) != -1) { if (exception._token == JSToken.RightParen) { this.GetNextToken(); } if (JSToken.LeftCurly != this.currentToken.token) { this.ReportError(JSError.NoLeftCurly); } this.GetNextToken(); } } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_SwitchNoSkipTokenSet); this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); } cases = new ASTList(this.currentToken.Clone()); bool flag = false; this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockNoSkipTokenSet); try { while (JSToken.RightCurly != this.currentToken.token) { SwitchCase elem = null; AST ast2 = null; Context context2 = this.currentToken.Clone(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_CaseNoSkipTokenSet); try { if (JSToken.Case == this.currentToken.token) { this.GetNextToken(); ast2 = this.ParseExpression(); } else if (JSToken.Default == this.currentToken.token) { if (flag) { this.ReportError(JSError.DupDefault, true); } else { flag = true; } this.GetNextToken(); } else { flag = true; this.ReportError(JSError.BadSwitch); } if (JSToken.Colon != this.currentToken.token) { this.ReportError(JSError.NoColon); } this.GetNextToken(); } catch (RecoveryTokenException exception2) { if (this.IndexOfToken(NoSkipTokenSet.s_CaseNoSkipTokenSet, exception2) == -1) { exception2._partiallyComputedNode = null; throw exception2; } ast2 = exception2._partiallyComputedNode; if (exception2._token == JSToken.Colon) { this.GetNextToken(); } } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_CaseNoSkipTokenSet); } this.blockType.Add(BlockType.Block); try { Block statements = new Block(this.currentToken.Clone()); this.noSkipTokenSet.Add(NoSkipTokenSet.s_SwitchNoSkipTokenSet); this.noSkipTokenSet.Add(NoSkipTokenSet.s_StartStatementNoSkipTokenSet); try { while (((JSToken.RightCurly != this.currentToken.token) && (JSToken.Case != this.currentToken.token)) && (JSToken.Default != this.currentToken.token)) { try { statements.Append(this.ParseStatement()); continue; } catch (RecoveryTokenException exception3) { if (exception3._partiallyComputedNode != null) { statements.Append(exception3._partiallyComputedNode); exception3._partiallyComputedNode = null; } if (this.IndexOfToken(NoSkipTokenSet.s_StartStatementNoSkipTokenSet, exception3) == -1) { throw exception3; } continue; } } } catch (RecoveryTokenException exception4) { if (this.IndexOfToken(NoSkipTokenSet.s_SwitchNoSkipTokenSet, exception4) == -1) { if (ast2 == null) { elem = new SwitchCase(context2, statements); } else { elem = new SwitchCase(context2, ast2, statements); } cases.Append(elem); throw exception4; } } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_StartStatementNoSkipTokenSet); this.noSkipTokenSet.Remove(NoSkipTokenSet.s_SwitchNoSkipTokenSet); } if (JSToken.RightCurly == this.currentToken.token) { statements.context.UpdateWith(this.currentToken); } if (ast2 == null) { context2.UpdateWith(statements.context); elem = new SwitchCase(context2, statements); } else { context2.UpdateWith(statements.context); elem = new SwitchCase(context2, ast2, statements); } cases.Append(elem); continue; } finally { this.blockType.RemoveAt(this.blockType.Count - 1); } } } catch (RecoveryTokenException exception5) { if (this.IndexOfToken(NoSkipTokenSet.s_BlockNoSkipTokenSet, exception5) == -1) { context.UpdateWith(this.CurrentPositionContext()); exception5._partiallyComputedNode = new Switch(context, expression, cases); throw exception5; } } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockNoSkipTokenSet); } context.UpdateWith(this.currentToken); this.GetNextToken(); } finally { this.blockType.RemoveAt(this.blockType.Count - 1); } return new Switch(context, expression, cases); }
private With ParseWithStatement() { Context context = this.currentToken.Clone(); AST ast = null; AST block = null; this.blockType.Add(BlockType.Block); try { this.GetNextToken(); if (JSToken.LeftParen != this.currentToken.token) { this.ReportError(JSError.NoLeftParen); } this.GetNextToken(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); try { ast = this.ParseExpression(); if (JSToken.RightParen != this.currentToken.token) { context.UpdateWith(ast.context); this.ReportError(JSError.NoRightParen); } else { context.UpdateWith(this.currentToken); } this.GetNextToken(); } catch (RecoveryTokenException exception) { if (this.IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exception) == -1) { exception._partiallyComputedNode = null; throw exception; } if (exception._partiallyComputedNode == null) { ast = new ConstantWrapper(true, this.CurrentPositionContext()); } else { ast = exception._partiallyComputedNode; } context.UpdateWith(ast.context); if (exception._token == JSToken.RightParen) { this.GetNextToken(); } } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); } try { block = this.ParseStatement(); } catch (RecoveryTokenException exception2) { if (exception2._partiallyComputedNode == null) { block = new Block(this.CurrentPositionContext()); } else { block = exception2._partiallyComputedNode; } exception2._partiallyComputedNode = new With(context, ast, block); } } finally { this.blockType.RemoveAt(this.blockType.Count - 1); } return new With(context, ast, block); }
//--------------------------------------------------------------------------------------- // ParseScopeSequence // // Scope // <empty> | // Identifier '.' Scope // // The argument error is passed by the caller and it is used in error situation // to provide better error information. The caller knows in which context this // qualified identifier is parsed (i.e. var x : QualifiedIdentifier vs. // import QualifiedIdentifier) // This function is called after a 'JSToken.Identifier JSToken.AccessField' sequence // has been processed and the whole scope production has to be returned //--------------------------------------------------------------------------------------- private AST ParseScopeSequence(AST qualid, JSError error){ ConstantWrapper id = null; string identifier = null; do{ GetNextToken(); // move after '.' if (JSToken.Identifier != this.currentToken.token){ identifier = JSKeyword.CanBeIdentifier(this.currentToken.token); if (null != identifier){ ForceReportInfo(JSError.KeywordUsedAsIdentifier); id = new ConstantWrapper(identifier, this.currentToken.Clone()); }else{ ReportError(error, true); SkipTokensAndThrow(qualid); // this will always throw } }else id = new ConstantWrapper(this.scanner.GetIdentifier(), this.currentToken.Clone()); qualid = new Member(qualid.context.CombineWith(this.currentToken), qualid, id); GetNextToken(); } while (JSToken.AccessField == this.currentToken.token); return qualid; }
//--------------------------------------------------------------------------------------- // ParseIfStatement // // IfStatement : // 'if' '(' Expression ')' Statement ElseStatement // // ElseStatement : // <empty> | // 'else' Statement //--------------------------------------------------------------------------------------- private If ParseIfStatement(){ Context ifCtx = this.currentToken.Clone(); AST condition = null; AST trueBranch = null; AST falseBranch = null; this.blockType.Add(BlockType.Block); try{ // parse condition GetNextToken(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); try{ if (JSToken.LeftParen != this.currentToken.token) ReportError(JSError.NoLeftParen); GetNextToken(); condition = ParseExpression(); // parse statements if (JSToken.RightParen != this.currentToken.token){ ifCtx.UpdateWith(condition.context); ReportError(JSError.NoRightParen); }else ifCtx.UpdateWith(this.currentToken); GetNextToken(); }catch(RecoveryTokenException exc){ // make up an if condition if (exc._partiallyComputedNode != null) condition = exc._partiallyComputedNode; else condition = new ConstantWrapper(true, CurrentPositionContext()); if (IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exc) == -1){ exc._partiallyComputedNode = null; // really not much to pass up // the if condition was so bogus we do not have a chance to make an If node, give up throw exc; }else{ if (exc._token == JSToken.RightParen) GetNextToken(); } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); } if (condition is Assign) condition.context.HandleError(JSError.SuspectAssignment); if (JSToken.Semicolon == this.currentToken.token) ForceReportInfo(JSError.SuspectSemicolon); this.noSkipTokenSet.Add(NoSkipTokenSet.s_IfBodyNoSkipTokenSet); try{ trueBranch = ParseStatement(); }catch(RecoveryTokenException exc){ // make up a block for the if part if (exc._partiallyComputedNode != null) trueBranch = exc._partiallyComputedNode; else trueBranch = new Block(CurrentPositionContext()); if (IndexOfToken(NoSkipTokenSet.s_IfBodyNoSkipTokenSet, exc) == -1){ // we have to pass the exception to someone else, make as much as you can from the if exc._partiallyComputedNode = new If(ifCtx, condition, trueBranch, falseBranch); throw exc; } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_IfBodyNoSkipTokenSet); } // parse else, if any if (JSToken.Else == this.currentToken.token){ GetNextToken(); if (JSToken.Semicolon == this.currentToken.token) ForceReportInfo(JSError.SuspectSemicolon); try{ falseBranch = ParseStatement(); }catch(RecoveryTokenException exc){ // make up a block for the else part if (exc._partiallyComputedNode != null) falseBranch = exc._partiallyComputedNode; else falseBranch = new Block(CurrentPositionContext()); exc._partiallyComputedNode = new If(ifCtx, condition, trueBranch, falseBranch); throw exc; } } }finally{ this.blockType.RemoveAt(this.blockType.Count - 1); } return new If(ifCtx, condition, trueBranch, falseBranch); }
//--------------------------------------------------------------------------------------- // ParseForStatement // // ForStatement : // 'for' '(' OptionalExpressionNoIn ';' OptionalExpression ';' OptionalExpression ')' // 'for' '(' 'var' VariableDeclarationListNoIn ';' OptionalExpression ';' OptionalExpression ')' // 'for' '(' LeftHandSideExpression 'in' Expression')' // 'for' '(' 'var' Identifier OptionalInitializerNoIn 'in' Expression')' // // OptionalExpressionNoIn : // <empty> | // ExpressionNoIn // same as Expression but does not process 'in' as an operator // // OptionalInitializerNoIn : // <empty> | // InitializerNoIn // same as initializer but does not process 'in' as an operator //--------------------------------------------------------------------------------------- private AST ParseForStatement(){ this.blockType.Add(BlockType.Loop); AST forNode = null; try{ Context forCtx = this.currentToken.Clone(); GetNextToken(); if (JSToken.LeftParen != this.currentToken.token) ReportError(JSError.NoLeftParen); GetNextToken(); bool isForIn = false, recoveryInForIn = false; AST lhs = null, initializer = null, condOrColl = null, increment = null; try{ if (JSToken.Var == this.currentToken.token){ isForIn = true; initializer = ParseIdentifierInitializer(JSToken.In, (FieldAttributes)0, null, JSToken.Var); // a list of variable initializers is allowed only in a for(;;) AST var = null; while (JSToken.Comma == this.currentToken.token){ isForIn = false; var = ParseIdentifierInitializer(JSToken.In, (FieldAttributes)0, null, JSToken.Var); initializer = new Comma(initializer.context.CombineWith(var.context), initializer, var); } // if it could still be a for..in, now it's time to get the 'in' if (isForIn){ if (JSToken.In == this.currentToken.token){ GetNextToken(); condOrColl = ParseExpression(); }else isForIn = false; } }else{ if (JSToken.Semicolon != this.currentToken.token){ bool isLHS; initializer = ParseUnaryExpression(out isLHS, false); if (isLHS && JSToken.In == this.currentToken.token){ isForIn = true; lhs = initializer; initializer = null; GetNextToken(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); try{ condOrColl = ParseExpression(); }catch(RecoveryTokenException exc){ if (IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exc) == -1){ exc._partiallyComputedNode = null; throw exc; }else{ if (exc._partiallyComputedNode == null) condOrColl = new ConstantWrapper(true, CurrentPositionContext()); // what could we put here? else condOrColl = exc._partiallyComputedNode; } if (exc._token == JSToken.RightParen){ GetNextToken(); recoveryInForIn = true; } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); } }else initializer = ParseExpression(initializer, false, isLHS, JSToken.In); }else initializer = new EmptyLiteral(CurrentPositionContext()); } }catch(RecoveryTokenException exc){ // error is too early abort for exc._partiallyComputedNode = null; throw exc; } // at this point we know whether or not is a for..in if (isForIn){ if (!recoveryInForIn){ if (JSToken.RightParen != this.currentToken.token) ReportError(JSError.NoRightParen); forCtx.UpdateWith(this.currentToken); GetNextToken(); } AST body = null; try{ body = ParseStatement(); }catch(RecoveryTokenException exc){ if (exc._partiallyComputedNode == null) body = new Block(CurrentPositionContext()); else body = exc._partiallyComputedNode; exc._partiallyComputedNode = new ForIn(forCtx, lhs, initializer, condOrColl, body); throw exc; } forNode = new ForIn(forCtx, lhs, initializer, condOrColl, body); }else{ this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); try{ if (JSToken.Semicolon != this.currentToken.token){ ReportError(JSError.NoSemicolon); if (JSToken.Colon == this.currentToken.token){ this.noSkipTokenSet.Add(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet); try{ SkipTokensAndThrow(); }catch(RecoveryTokenException exc){ if (JSToken.Semicolon == this.currentToken.token) this.errorToken = null; else throw exc; }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet); } } } GetNextToken(); if (JSToken.Semicolon != this.currentToken.token){ condOrColl = ParseExpression(); if (JSToken.Semicolon != this.currentToken.token) ReportError(JSError.NoSemicolon); }else condOrColl = new ConstantWrapper(true, CurrentPositionContext()); GetNextToken(); if (JSToken.RightParen != this.currentToken.token) increment = ParseExpression(); else increment = new EmptyLiteral(CurrentPositionContext()); if (JSToken.RightParen != this.currentToken.token) ReportError(JSError.NoRightParen); forCtx.UpdateWith(this.currentToken); GetNextToken(); }catch(RecoveryTokenException exc){ if (IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exc) == -1){ exc._partiallyComputedNode = null; throw exc; }else{ // discard any partial info, just genrate empty condition and increment and keep going exc._partiallyComputedNode = null; if (condOrColl == null) condOrColl = new ConstantWrapper(true, CurrentPositionContext()); if (increment == null) increment = new EmptyLiteral(CurrentPositionContext()); } if (exc._token == JSToken.RightParen){ GetNextToken(); } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); } AST body = null; try{ body = ParseStatement(); }catch(RecoveryTokenException exc){ if (exc._partiallyComputedNode == null) body = new Block(CurrentPositionContext()); else body = exc._partiallyComputedNode; exc._partiallyComputedNode = new For(forCtx, initializer, condOrColl, increment, body); throw exc; } forNode = new For(forCtx, initializer, condOrColl, increment, body); } }finally{ this.blockType.RemoveAt(this.blockType.Count - 1); } return forNode; }
//--------------------------------------------------------------------------------------- // ParseDoStatement // // DoStatement: // 'do' Statement 'while' '(' Expression ')' //--------------------------------------------------------------------------------------- private DoWhile ParseDoStatement(){ Context doCtx = null; // this.currentToken.Clone(); AST body = null; AST condition = null; this.blockType.Add(BlockType.Loop); try{ GetNextToken(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_DoWhileBodyNoSkipTokenSet); try{ body = ParseStatement(); }catch(RecoveryTokenException exc){ // make up a block for the do while if (exc._partiallyComputedNode != null) body = exc._partiallyComputedNode; else body = new Block(CurrentPositionContext()); if (IndexOfToken(NoSkipTokenSet.s_DoWhileBodyNoSkipTokenSet, exc) == -1){ // we have to pass the exception to someone else, make as much as you can from the 'do while' exc._partiallyComputedNode = new DoWhile(CurrentPositionContext(), body, new ConstantWrapper(false, CurrentPositionContext())); throw exc; } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_DoWhileBodyNoSkipTokenSet); } if (JSToken.While != this.currentToken.token){ ReportError(JSError.NoWhile); } doCtx = this.currentToken.Clone(); GetNextToken(); if (JSToken.LeftParen != this.currentToken.token){ ReportError(JSError.NoLeftParen); } GetNextToken(); // catch here so the body of the do_while is not thrown away this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); try{ condition = ParseExpression(); if (JSToken.RightParen != this.currentToken.token){ ReportError(JSError.NoRightParen); doCtx.UpdateWith(condition.context); }else doCtx.UpdateWith(this.currentToken); GetNextToken(); }catch(RecoveryTokenException exc){ // make up a condition if (exc._partiallyComputedNode != null) condition = exc._partiallyComputedNode; else condition = new ConstantWrapper(false, CurrentPositionContext()); if (IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exc) == -1){ exc._partiallyComputedNode = new DoWhile(doCtx, body, condition); throw exc; }else{ if (JSToken.RightParen == this.currentToken.token) GetNextToken(); } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); } if (JSToken.Semicolon == this.currentToken.token){ // JScript 5 allowed statements like // do{print(++x)}while(x<10) print(0) // even though that does not strictly follow the automatic semicolon insertion // rules for the required semi after the while(). For backwards compatibility // we should continue to support this. doCtx.UpdateWith(this.currentToken); GetNextToken(); } }finally{ this.blockType.RemoveAt(this.blockType.Count - 1); } return new DoWhile(doCtx, body, condition); }
private AST ParseForStatement() { this.blockType.Add(BlockType.Loop); AST ast = null; try { Context context = this.currentToken.Clone(); this.GetNextToken(); if (JSToken.LeftParen != this.currentToken.token) { this.ReportError(JSError.NoLeftParen); } this.GetNextToken(); bool flag = false; bool flag2 = false; AST var = null; AST ast3 = null; AST collection = null; AST incrementer = null; try { if (JSToken.Var == this.currentToken.token) { flag = true; ast3 = this.ParseIdentifierInitializer(JSToken.In, FieldAttributes.PrivateScope, null, JSToken.Var); AST ast6 = null; while (JSToken.Comma == this.currentToken.token) { flag = false; ast6 = this.ParseIdentifierInitializer(JSToken.In, FieldAttributes.PrivateScope, null, JSToken.Var); ast3 = new Comma(ast3.context.CombineWith(ast6.context), ast3, ast6); } if (flag) { if (JSToken.In == this.currentToken.token) { this.GetNextToken(); collection = this.ParseExpression(); } else { flag = false; } } } else if (JSToken.Semicolon != this.currentToken.token) { bool flag3; ast3 = this.ParseUnaryExpression(out flag3, false); if (flag3 && (JSToken.In == this.currentToken.token)) { flag = true; var = ast3; ast3 = null; this.GetNextToken(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); try { try { collection = this.ParseExpression(); } catch (RecoveryTokenException exception) { if (this.IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exception) == -1) { exception._partiallyComputedNode = null; throw exception; } if (exception._partiallyComputedNode == null) { collection = new ConstantWrapper(true, this.CurrentPositionContext()); } else { collection = exception._partiallyComputedNode; } if (exception._token == JSToken.RightParen) { this.GetNextToken(); flag2 = true; } } goto Label_01E1; } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); } } ast3 = this.ParseExpression(ast3, false, flag3, JSToken.In); } else { ast3 = new EmptyLiteral(this.CurrentPositionContext()); } } catch (RecoveryTokenException exception2) { exception2._partiallyComputedNode = null; throw exception2; } Label_01E1: if (flag) { if (!flag2) { if (JSToken.RightParen != this.currentToken.token) { this.ReportError(JSError.NoRightParen); } context.UpdateWith(this.currentToken); this.GetNextToken(); } AST ast7 = null; try { ast7 = this.ParseStatement(); } catch (RecoveryTokenException exception3) { if (exception3._partiallyComputedNode == null) { ast7 = new Block(this.CurrentPositionContext()); } else { ast7 = exception3._partiallyComputedNode; } exception3._partiallyComputedNode = new ForIn(context, var, ast3, collection, ast7); throw exception3; } return new ForIn(context, var, ast3, collection, ast7); } this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); try { if (JSToken.Semicolon != this.currentToken.token) { this.ReportError(JSError.NoSemicolon); if (JSToken.Colon == this.currentToken.token) { this.noSkipTokenSet.Add(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet); try { this.SkipTokensAndThrow(); } catch (RecoveryTokenException exception4) { if (JSToken.Semicolon != this.currentToken.token) { throw exception4; } this.errorToken = null; } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet); } } } this.GetNextToken(); if (JSToken.Semicolon != this.currentToken.token) { collection = this.ParseExpression(); if (JSToken.Semicolon != this.currentToken.token) { this.ReportError(JSError.NoSemicolon); } } else { collection = new ConstantWrapper(true, this.CurrentPositionContext()); } this.GetNextToken(); if (JSToken.RightParen != this.currentToken.token) { incrementer = this.ParseExpression(); } else { incrementer = new EmptyLiteral(this.CurrentPositionContext()); } if (JSToken.RightParen != this.currentToken.token) { this.ReportError(JSError.NoRightParen); } context.UpdateWith(this.currentToken); this.GetNextToken(); } catch (RecoveryTokenException exception5) { if (this.IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exception5) == -1) { exception5._partiallyComputedNode = null; throw exception5; } exception5._partiallyComputedNode = null; if (collection == null) { collection = new ConstantWrapper(true, this.CurrentPositionContext()); } if (incrementer == null) { incrementer = new EmptyLiteral(this.CurrentPositionContext()); } if (exception5._token == JSToken.RightParen) { this.GetNextToken(); } } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); } AST body = null; try { body = this.ParseStatement(); } catch (RecoveryTokenException exception6) { if (exception6._partiallyComputedNode == null) { body = new Block(this.CurrentPositionContext()); } else { body = exception6._partiallyComputedNode; } exception6._partiallyComputedNode = new For(context, ast3, collection, incrementer, body); throw exception6; } ast = new For(context, ast3, collection, incrementer, body); } finally { this.blockType.RemoveAt(this.blockType.Count - 1); } return ast; }
private If ParseIfStatement() { Context context = this.currentToken.Clone(); AST condition = null; AST ast2 = null; AST ast3 = null; this.blockType.Add(BlockType.Block); try { this.GetNextToken(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); try { if (JSToken.LeftParen != this.currentToken.token) { this.ReportError(JSError.NoLeftParen); } this.GetNextToken(); condition = this.ParseExpression(); if (JSToken.RightParen != this.currentToken.token) { context.UpdateWith(condition.context); this.ReportError(JSError.NoRightParen); } else { context.UpdateWith(this.currentToken); } this.GetNextToken(); } catch (RecoveryTokenException exception) { if (exception._partiallyComputedNode != null) { condition = exception._partiallyComputedNode; } else { condition = new ConstantWrapper(true, this.CurrentPositionContext()); } if (this.IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exception) == -1) { exception._partiallyComputedNode = null; throw exception; } if (exception._token == JSToken.RightParen) { this.GetNextToken(); } } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); } if (condition is Assign) { condition.context.HandleError(JSError.SuspectAssignment); } if (JSToken.Semicolon == this.currentToken.token) { this.ForceReportInfo(JSError.SuspectSemicolon); } this.noSkipTokenSet.Add(NoSkipTokenSet.s_IfBodyNoSkipTokenSet); try { ast2 = this.ParseStatement(); } catch (RecoveryTokenException exception2) { if (exception2._partiallyComputedNode != null) { ast2 = exception2._partiallyComputedNode; } else { ast2 = new Block(this.CurrentPositionContext()); } if (this.IndexOfToken(NoSkipTokenSet.s_IfBodyNoSkipTokenSet, exception2) == -1) { exception2._partiallyComputedNode = new If(context, condition, ast2, ast3); throw exception2; } } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_IfBodyNoSkipTokenSet); } if (JSToken.Else == this.currentToken.token) { this.GetNextToken(); if (JSToken.Semicolon == this.currentToken.token) { this.ForceReportInfo(JSError.SuspectSemicolon); } try { ast3 = this.ParseStatement(); } catch (RecoveryTokenException exception3) { if (exception3._partiallyComputedNode != null) { ast3 = exception3._partiallyComputedNode; } else { ast3 = new Block(this.CurrentPositionContext()); } exception3._partiallyComputedNode = new If(context, condition, ast2, ast3); throw exception3; } } } finally { this.blockType.RemoveAt(this.blockType.Count - 1); } return new If(context, condition, ast2, ast3); }
private AST MemberExpression(AST expression, ArrayList newContexts, out bool canBeQualid, ref bool canBeAttribute){ bool noMoreForAttr = false; canBeQualid = true; for(;;){ this.noSkipTokenSet.Add(NoSkipTokenSet.s_MemberExprNoSkipTokenSet); try{ switch (this.currentToken.token){ case JSToken.LeftParen: if (noMoreForAttr) canBeAttribute = false; else noMoreForAttr = true; canBeQualid = false; ASTList args = null; RecoveryTokenException callError = null; this.noSkipTokenSet.Add(NoSkipTokenSet.s_ParenToken); try{ args = ParseExpressionList(JSToken.RightParen); }catch(RecoveryTokenException exc){ args = (ASTList)exc._partiallyComputedNode; if (IndexOfToken(NoSkipTokenSet.s_ParenToken, exc) == -1) callError = exc; // thrown later on }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ParenToken); } //treat eval and print specially if (expression is Lookup){ String name = expression.ToString(); if (name.Equals("eval")){ expression.context.UpdateWith(args.context); if (args.count > 0) expression = new Eval(expression.context, args[0]); else expression = new Eval(expression.context, new ConstantWrapper("", CurrentPositionContext())); }else if (this.Globals.engine.doPrint && name.Equals("print")){ expression.context.UpdateWith(args.context); expression = new Print(expression.context, args); }else{ if (name == "GetObject") this.ForceReportInfo(JSError.GetObjectNotSupportedOnRotor); expression = new Call(expression.context.CombineWith(args.context), expression, args, false); } }else expression = new Call(expression.context.CombineWith(args.context), expression, args, false); if (null != newContexts && newContexts.Count > 0){ ((Context)newContexts[newContexts.Count - 1]).UpdateWith(expression.context); if (!(expression is Call)) expression = new Call((Context)newContexts[newContexts.Count - 1], expression, new ASTList(CurrentPositionContext()), false); else expression.context = (Context)newContexts[newContexts.Count - 1]; ((Call)expression).isConstructor = true; newContexts.RemoveAt(newContexts.Count - 1); } if (callError != null){ callError._partiallyComputedNode = expression; throw callError; } GetNextToken(); break; case JSToken.LeftBracket: canBeQualid = false; canBeAttribute = false; this.noSkipTokenSet.Add(NoSkipTokenSet.s_BracketToken); try{ args = ParseExpressionList(JSToken.RightBracket); }catch(RecoveryTokenException exc){ if(IndexOfToken(NoSkipTokenSet.s_BracketToken, exc) == -1){ if (exc._partiallyComputedNode != null){ exc._partiallyComputedNode = new Call(expression.context.CombineWith(this.currentToken.Clone()), expression, (ASTList)exc._partiallyComputedNode, true); }else{ exc._partiallyComputedNode = expression; } throw exc; }else args = (ASTList)exc._partiallyComputedNode; }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BracketToken); } expression = new Call(expression.context.CombineWith(this.currentToken.Clone()), expression, args, true); if (null != newContexts && newContexts.Count > 0){ ((Context)newContexts[newContexts.Count - 1]).UpdateWith(expression.context); expression.context = (Context)newContexts[newContexts.Count - 1]; ((Call)expression).isConstructor = true; newContexts.RemoveAt(newContexts.Count - 1); } GetNextToken(); break; case JSToken.AccessField: if (noMoreForAttr) canBeAttribute = false; ConstantWrapper id = null; GetNextToken(); if (JSToken.Identifier != this.currentToken.token){ string identifier = JSKeyword.CanBeIdentifier(this.currentToken.token); if (null != identifier){ ForceReportInfo(JSError.KeywordUsedAsIdentifier); id = new ConstantWrapper(identifier, this.currentToken.Clone()); }else{ ReportError(JSError.NoIdentifier); SkipTokensAndThrow(expression); } }else id = new ConstantWrapper(this.scanner.GetIdentifier(), this.currentToken.Clone()); GetNextToken(); expression = new Member(expression.context.CombineWith(id.context), expression, id); break; default: if (null != newContexts){ while (newContexts.Count > 0){ ((Context)newContexts[newContexts.Count - 1]).UpdateWith(expression.context); expression = new Call((Context)newContexts[newContexts.Count - 1], expression, new ASTList(CurrentPositionContext()), false); ((Call)expression).isConstructor = true; newContexts.RemoveAt(newContexts.Count - 1); } } return expression; } }catch(RecoveryTokenException exc){ if (IndexOfToken(NoSkipTokenSet.s_MemberExprNoSkipTokenSet, exc) != -1) expression = exc._partiallyComputedNode; else{ Debug.Assert(exc._partiallyComputedNode == expression); throw exc; } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_MemberExprNoSkipTokenSet); } } }
//--------------------------------------------------------------------------------------- // ParseSwitchStatement // // SwitchStatement : // 'switch' '(' Expression ')' '{' CaseBlock '}' // // CaseBlock : // CaseList DefaultCaseClause CaseList // // CaseList : // <empty> | // CaseClause CaseList // // CaseClause : // 'case' Expression ':' OptionalStatements // // DefaultCaseClause : // <empty> | // 'default' ':' OptionalStatements //--------------------------------------------------------------------------------------- private AST ParseSwitchStatement(){ Context switchCtx = this.currentToken.Clone(); AST expr = null; ASTList cases = null; this.blockType.Add(BlockType.Switch); try{ // read switch(expr) GetNextToken(); if (JSToken.LeftParen != this.currentToken.token) ReportError(JSError.NoLeftParen); GetNextToken(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); this.noSkipTokenSet.Add(NoSkipTokenSet.s_SwitchNoSkipTokenSet); try{ expr = ParseExpression(); if (JSToken.RightParen != this.currentToken.token){ ReportError(JSError.NoRightParen); } GetNextToken(); if (JSToken.LeftCurly != this.currentToken.token){ ReportError(JSError.NoLeftCurly); } GetNextToken(); }catch(RecoveryTokenException exc){ if (IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exc) == -1 && IndexOfToken(NoSkipTokenSet.s_SwitchNoSkipTokenSet, exc) == -1 ){ // give up exc._partiallyComputedNode = null; throw exc; }else{ if (exc._partiallyComputedNode == null) expr = new ConstantWrapper(true, CurrentPositionContext()); else expr = exc._partiallyComputedNode; if (IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exc) != -1){ if (exc._token == JSToken.RightParen) GetNextToken(); if (JSToken.LeftCurly != this.currentToken.token){ ReportError(JSError.NoLeftCurly); } GetNextToken(); } } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_SwitchNoSkipTokenSet); this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); } // parse the switch body cases = new ASTList(this.currentToken.Clone()); bool defaultStatement = false; this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockNoSkipTokenSet); try{ while (JSToken.RightCurly != this.currentToken.token){ SwitchCase caseClause = null; AST caseValue = null; Context caseCtx = this.currentToken.Clone(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_CaseNoSkipTokenSet); try{ if (JSToken.Case == this.currentToken.token){ // get the case GetNextToken(); caseValue = ParseExpression(); }else if (JSToken.Default == this.currentToken.token){ // get the default if (defaultStatement) // we report an error but we still accept the default ReportError(JSError.DupDefault, true); else defaultStatement = true; GetNextToken(); }else{ // This is an error, there is no case or default. Assume a default was missing and keep going defaultStatement = true; ReportError(JSError.BadSwitch); } if (JSToken.Colon != this.currentToken.token) ReportError(JSError.NoColon); // read the statements inside the case or default GetNextToken(); }catch(RecoveryTokenException exc){ // right now we can only get here for the 'case' statement if (IndexOfToken(NoSkipTokenSet.s_CaseNoSkipTokenSet, exc) == -1){ // ignore the current case or default exc._partiallyComputedNode = null; throw exc; }else{ caseValue = exc._partiallyComputedNode; if (exc._token == JSToken.Colon) GetNextToken(); } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_CaseNoSkipTokenSet); } this.blockType.Add(BlockType.Block); try{ Block statements = new Block(this.currentToken.Clone()); this.noSkipTokenSet.Add(NoSkipTokenSet.s_SwitchNoSkipTokenSet); this.noSkipTokenSet.Add(NoSkipTokenSet.s_StartStatementNoSkipTokenSet); try{ while (JSToken.RightCurly != this.currentToken.token && JSToken.Case != this.currentToken.token && JSToken.Default != this.currentToken.token){ try{ statements.Append(ParseStatement()); }catch(RecoveryTokenException exc){ if (exc._partiallyComputedNode != null){ statements.Append(exc._partiallyComputedNode); exc._partiallyComputedNode = null; } if (IndexOfToken(NoSkipTokenSet.s_StartStatementNoSkipTokenSet, exc) == -1) throw exc; } } }catch(RecoveryTokenException exc){ if (IndexOfToken(NoSkipTokenSet.s_SwitchNoSkipTokenSet, exc) == -1){ if (null == caseValue) caseClause = new SwitchCase(caseCtx, statements); else caseClause = new SwitchCase(caseCtx, caseValue, statements); cases.Append(caseClause); throw exc; } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_StartStatementNoSkipTokenSet); this.noSkipTokenSet.Remove(NoSkipTokenSet.s_SwitchNoSkipTokenSet); } if (JSToken.RightCurly == this.currentToken.token) statements.context.UpdateWith(this.currentToken); if (null == caseValue){ caseCtx.UpdateWith(statements.context); caseClause = new SwitchCase(caseCtx, statements); }else{ caseCtx.UpdateWith(statements.context); caseClause = new SwitchCase(caseCtx, caseValue, statements); } cases.Append(caseClause); }finally{ this.blockType.RemoveAt(this.blockType.Count - 1); } } }catch(RecoveryTokenException exc){ if (IndexOfToken(NoSkipTokenSet.s_BlockNoSkipTokenSet, exc) == -1){ //save what you can a rethrow switchCtx.UpdateWith(CurrentPositionContext()); exc._partiallyComputedNode = new Switch(switchCtx, expr, cases); throw exc; } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockNoSkipTokenSet); } switchCtx.UpdateWith(this.currentToken); GetNextToken(); }finally{ this.blockType.RemoveAt(this.blockType.Count - 1); } return new Switch(switchCtx, expr, cases); }
//--------------------------------------------------------------------------------------- // ParseWhileStatement // // WhileStatement : // 'while' '(' Expression ')' Statement //--------------------------------------------------------------------------------------- private While ParseWhileStatement(){ Context whileCtx = this.currentToken.Clone(); AST condition = null; AST body = null; this.blockType.Add(BlockType.Loop); try{ GetNextToken(); if (JSToken.LeftParen != this.currentToken.token){ ReportError(JSError.NoLeftParen); } GetNextToken(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); try{ condition = ParseExpression(); if (JSToken.RightParen != this.currentToken.token){ ReportError(JSError.NoRightParen); whileCtx.UpdateWith(condition.context); }else whileCtx.UpdateWith(this.currentToken); GetNextToken(); }catch(RecoveryTokenException exc){ if (IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exc) == -1){ // abort the while there is really no much to do here exc._partiallyComputedNode = null; throw exc; }else{ // make up a condition if (exc._partiallyComputedNode != null) condition = exc._partiallyComputedNode; else condition = new ConstantWrapper(false, CurrentPositionContext()); if (JSToken.RightParen == this.currentToken.token) GetNextToken(); } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); } try{ body = ParseStatement(); }catch(RecoveryTokenException exc){ if (exc._partiallyComputedNode != null) body = exc._partiallyComputedNode; else body = new Block(CurrentPositionContext()); exc._partiallyComputedNode = new While(whileCtx, condition, body); throw exc; } }finally{ this.blockType.RemoveAt(this.blockType.Count - 1); } return new While(whileCtx, condition, body); }
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); }
//--------------------------------------------------------------------------------------- // ParseWithStatement // // WithStatement : // 'with' '(' Expression ')' Statement //--------------------------------------------------------------------------------------- private With ParseWithStatement(){ Context withCtx = this.currentToken.Clone(); AST obj = null; AST block = null; this.blockType.Add(BlockType.Block); try{ GetNextToken(); if (JSToken.LeftParen != this.currentToken.token) ReportError(JSError.NoLeftParen); GetNextToken(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); try{ obj = ParseExpression(); if (JSToken.RightParen != this.currentToken.token){ withCtx.UpdateWith(obj.context); ReportError(JSError.NoRightParen); }else withCtx.UpdateWith(this.currentToken); GetNextToken(); }catch(RecoveryTokenException exc){ if (IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exc) == -1){ // give up exc._partiallyComputedNode = null; throw exc; }else{ if (exc._partiallyComputedNode == null) obj = new ConstantWrapper(true, CurrentPositionContext()); else obj = exc._partiallyComputedNode; withCtx.UpdateWith(obj.context); if (exc._token == JSToken.RightParen) GetNextToken(); } }finally{ this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); } try{ block = ParseStatement(); }catch(RecoveryTokenException exc){ if (exc._partiallyComputedNode == null) block = new Block(CurrentPositionContext()); else block = exc._partiallyComputedNode; exc._partiallyComputedNode = new With(withCtx, obj, block); } }finally{ this.blockType.RemoveAt(this.blockType.Count - 1); } return new With(withCtx, obj, block); }
private DoWhile ParseDoStatement() { Context context = null; AST body = null; AST condition = null; this.blockType.Add(BlockType.Loop); try { this.GetNextToken(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_DoWhileBodyNoSkipTokenSet); try { body = this.ParseStatement(); } catch (RecoveryTokenException exception) { if (exception._partiallyComputedNode != null) { body = exception._partiallyComputedNode; } else { body = new Block(this.CurrentPositionContext()); } if (this.IndexOfToken(NoSkipTokenSet.s_DoWhileBodyNoSkipTokenSet, exception) == -1) { exception._partiallyComputedNode = new DoWhile(this.CurrentPositionContext(), body, new ConstantWrapper(false, this.CurrentPositionContext())); throw exception; } } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_DoWhileBodyNoSkipTokenSet); } if (JSToken.While != this.currentToken.token) { this.ReportError(JSError.NoWhile); } context = this.currentToken.Clone(); this.GetNextToken(); if (JSToken.LeftParen != this.currentToken.token) { this.ReportError(JSError.NoLeftParen); } this.GetNextToken(); this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); try { condition = this.ParseExpression(); if (JSToken.RightParen != this.currentToken.token) { this.ReportError(JSError.NoRightParen); context.UpdateWith(condition.context); } else { context.UpdateWith(this.currentToken); } this.GetNextToken(); } catch (RecoveryTokenException exception2) { if (exception2._partiallyComputedNode != null) { condition = exception2._partiallyComputedNode; } else { condition = new ConstantWrapper(false, this.CurrentPositionContext()); } if (this.IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exception2) == -1) { exception2._partiallyComputedNode = new DoWhile(context, body, condition); throw exception2; } if (JSToken.RightParen == this.currentToken.token) { this.GetNextToken(); } } finally { this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet); } if (JSToken.Semicolon == this.currentToken.token) { context.UpdateWith(this.currentToken); this.GetNextToken(); } } finally { this.blockType.RemoveAt(this.blockType.Count - 1); } return new DoWhile(context, body, condition); }