internal override AST PartiallyEvaluate() { if (!(this.classob.GetParent() is GlobalScope)) { return(this); //The class has already been partially evaluated } this.baseType.PartiallyEvaluate(); IReflect ir = this.baseType.ToIReflect(); Type bt = null; if (!(ir is Type) || !Convert.IsPrimitiveIntegerType(bt = (Type)ir)) { this.baseType.context.HandleError(JSError.InvalidBaseTypeForEnum); this.baseType = new TypeExpression(new ConstantWrapper(Typeob.Int32, null)); bt = Typeob.Int32; } if (this.customAttributes != null) { this.customAttributes.PartiallyEvaluate(); } if (this.NeedsToBeCheckedForCLSCompliance()) { if (!TypeExpression.TypeIsCLSCompliant(ir)) { this.baseType.context.HandleError(JSError.NonCLSCompliantType); } this.CheckMemberNamesForCLSCompliance(); } ScriptObject scope = this.enclosingScope; while (!(scope is GlobalScope) && !(scope is PackageScope)) { scope = scope.GetParent(); } this.classob.SetParent(new WithObject(scope, typeof(Enum), true)); Globals.ScopeStack.Push(this.classob); try{ foreach (FieldInfo f in this.fields) { JSMemberField field = (JSMemberField)f; ((EnumWrapper)field.value).CoerceToBaseType(bt, field.originalContext); } }finally{ Globals.ScopeStack.Pop(); } return(this); }
internal static Type ResultType(Type type1, Type type2, JSToken operatorTok) { switch (operatorTok) { case JSToken.LeftShift: case JSToken.RightShift: if (Convert.IsPrimitiveIntegerType(type1)) { return(type1); } else if (Typeob.JSObject.IsAssignableFrom(type1)) { return(Typeob.Int32); } else { return(Typeob.Object); } case JSToken.UnsignedRightShift: switch (Type.GetTypeCode(type1)) { case TypeCode.Byte: case TypeCode.SByte: return(Typeob.Byte); case TypeCode.UInt16: case TypeCode.Int16: return(Typeob.UInt16); case TypeCode.Int32: case TypeCode.UInt32: return(Typeob.UInt32); case TypeCode.Int64: case TypeCode.UInt64: return(Typeob.UInt64); default: if (Typeob.JSObject.IsAssignableFrom(type1)) { return(Typeob.Int32); } else { return(Typeob.Object); } } } TypeCode t1 = Type.GetTypeCode(type1); TypeCode t2 = Type.GetTypeCode(type2); switch (t1) { case TypeCode.Empty: case TypeCode.DBNull: case TypeCode.Boolean: switch (t2) { case TypeCode.SByte: return(Typeob.SByte); case TypeCode.Byte: return(Typeob.Byte); case TypeCode.Char: case TypeCode.UInt16: return(Typeob.UInt16); case TypeCode.Int16: return(Typeob.Int16); case TypeCode.Empty: case TypeCode.DBNull: case TypeCode.Boolean: case TypeCode.Int32: case TypeCode.Single: case TypeCode.Double: return(Typeob.Int32); case TypeCode.UInt32: return(Typeob.UInt32); case TypeCode.Int64: return(Typeob.Int64); case TypeCode.UInt64: return(Typeob.UInt64); case TypeCode.Object: if (Typeob.JSObject.IsAssignableFrom(type2)) { return(Typeob.Int32); } break; case TypeCode.Decimal: case TypeCode.DateTime: case TypeCode.String: break; } break; case TypeCode.SByte: switch (t2) { case TypeCode.Empty: case TypeCode.DBNull: case TypeCode.Boolean: case TypeCode.SByte: return(Typeob.SByte); case TypeCode.Byte: return(Typeob.Byte); case TypeCode.Char: case TypeCode.Int16: return(Typeob.Int16); case TypeCode.UInt16: return(Typeob.UInt16); case TypeCode.Int32: case TypeCode.Single: case TypeCode.Double: return(Typeob.Int32); case TypeCode.UInt32: return(Typeob.UInt32); case TypeCode.Int64: return(Typeob.Int64); case TypeCode.UInt64: return(Typeob.UInt64); case TypeCode.Object: if (Typeob.JSObject.IsAssignableFrom(type2)) { return(Typeob.Int32); } break; case TypeCode.Decimal: case TypeCode.DateTime: case TypeCode.String: break; } break; case TypeCode.Byte: switch (t2) { case TypeCode.Empty: case TypeCode.DBNull: case TypeCode.Boolean: case TypeCode.Byte: case TypeCode.SByte: return(Typeob.Byte); case TypeCode.Char: case TypeCode.UInt16: case TypeCode.Int16: return(Typeob.UInt16); case TypeCode.Int32: case TypeCode.Single: case TypeCode.Double: case TypeCode.UInt32: return(Typeob.UInt32); case TypeCode.Int64: case TypeCode.UInt64: return(Typeob.UInt64); case TypeCode.Object: if (Typeob.JSObject.IsAssignableFrom(type2)) { return(Typeob.UInt32); } break; case TypeCode.Decimal: case TypeCode.DateTime: case TypeCode.String: break; } break; case TypeCode.Int16: switch (t2) { case TypeCode.Empty: case TypeCode.DBNull: case TypeCode.Boolean: case TypeCode.SByte: case TypeCode.Int16: return(Typeob.Int16); case TypeCode.Byte: case TypeCode.Char: case TypeCode.UInt16: return(Typeob.UInt16); case TypeCode.Int32: case TypeCode.Single: case TypeCode.Double: return(Typeob.Int32); case TypeCode.UInt32: return(Typeob.UInt32); case TypeCode.Int64: return(Typeob.Int64); case TypeCode.UInt64: return(Typeob.UInt64); case TypeCode.Object: if (Typeob.JSObject.IsAssignableFrom(type2)) { return(Typeob.Int32); } break; case TypeCode.Decimal: case TypeCode.DateTime: case TypeCode.String: break; } break; case TypeCode.Char: case TypeCode.UInt16: switch (t2) { case TypeCode.Empty: case TypeCode.DBNull: case TypeCode.Boolean: case TypeCode.Byte: case TypeCode.Char: case TypeCode.UInt16: case TypeCode.SByte: case TypeCode.Int16: return(Typeob.UInt16); case TypeCode.Int32: case TypeCode.Single: case TypeCode.Double: case TypeCode.UInt32: return(Typeob.UInt32); case TypeCode.Int64: case TypeCode.UInt64: return(Typeob.UInt64); case TypeCode.Object: if (Typeob.JSObject.IsAssignableFrom(type2)) { return(Typeob.UInt32); } break; case TypeCode.Decimal: case TypeCode.DateTime: case TypeCode.String: break; } break; case TypeCode.Int32: case TypeCode.Single: case TypeCode.Double: switch (t2) { case TypeCode.Empty: case TypeCode.DBNull: case TypeCode.Boolean: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Single: case TypeCode.Double: return(Typeob.Int32); case TypeCode.Byte: case TypeCode.Char: case TypeCode.UInt16: case TypeCode.UInt32: return(Typeob.UInt32); case TypeCode.Int64: return(Typeob.Int64); case TypeCode.UInt64: return(Typeob.UInt64); case TypeCode.Object: if (Typeob.JSObject.IsAssignableFrom(type2)) { return(Typeob.Int32); } break; case TypeCode.Decimal: case TypeCode.DateTime: case TypeCode.String: break; } break; case TypeCode.UInt32: switch (t2) { case TypeCode.Empty: case TypeCode.DBNull: case TypeCode.Boolean: case TypeCode.Byte: case TypeCode.UInt16: case TypeCode.Char: case TypeCode.UInt32: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Single: case TypeCode.Double: return(Typeob.UInt32); case TypeCode.Int64: case TypeCode.UInt64: return(Typeob.UInt64); case TypeCode.Object: if (Typeob.JSObject.IsAssignableFrom(type2)) { return(Typeob.UInt32); } break; case TypeCode.Decimal: case TypeCode.DateTime: case TypeCode.String: break; } break; case TypeCode.Int64: switch (t2) { case TypeCode.Empty: case TypeCode.DBNull: case TypeCode.Boolean: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.Single: case TypeCode.Double: return(Typeob.Int64); case TypeCode.Byte: case TypeCode.Char: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: return(Typeob.UInt64); case TypeCode.Object: if (Typeob.JSObject.IsAssignableFrom(type2)) { return(Typeob.Int64); } break; case TypeCode.Decimal: case TypeCode.DateTime: case TypeCode.String: break; } break; case TypeCode.UInt64: switch (t2) { case TypeCode.Empty: case TypeCode.DBNull: case TypeCode.Boolean: case TypeCode.Byte: case TypeCode.Char: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Single: case TypeCode.Double: case TypeCode.Int64: return(Typeob.UInt64); case TypeCode.Object: if (Typeob.JSObject.IsAssignableFrom(type2)) { return(Typeob.UInt64); } break; case TypeCode.Decimal: case TypeCode.DateTime: case TypeCode.String: break; } break; case TypeCode.Object: if (Typeob.JSObject.IsAssignableFrom(type1)) { return(Typeob.Int32); } break; case TypeCode.Decimal: case TypeCode.DateTime: case TypeCode.String: break; } return(Typeob.Object); }
internal override void TranslateToIL(ILGenerator il, Type rtype) { if (this.metaData == null) { Type rt = this.operatorTok == JSToken.LogicalNot ? Typeob.Boolean : Typeob.Double; if (Convert.IsPrimitiveNumericType(rtype) && Convert.IsPromotableTo(this.type, rtype)) { rt = rtype; } if (this.operatorTok == JSToken.BitwiseNot && !Convert.IsPrimitiveIntegerType(rt)) { rt = this.type; if (!Convert.IsPrimitiveIntegerType(rt)) { rt = Typeob.Int32; } } this.operand.TranslateToIL(il, this.type); Convert.Emit(this, il, this.type, rt, true); switch (this.operatorTok) { case JSToken.BitwiseNot: il.Emit(OpCodes.Not); break; case JSToken.LogicalNot: Convert.Emit(this, il, rt, Typeob.Boolean, true); rt = Typeob.Boolean; il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Ceq); break; case JSToken.Minus: il.Emit(OpCodes.Neg); break; case JSToken.Plus: break; default: throw new JScriptException(JSError.InternalError, this.context); } Convert.Emit(this, il, rt, rtype); return; } if (this.metaData is MethodInfo) { MethodInfo oper = (MethodInfo)this.metaData; ParameterInfo[] pars = oper.GetParameters(); this.operand.TranslateToIL(il, pars[0].ParameterType); il.Emit(OpCodes.Call, oper); Convert.Emit(this, il, oper.ReturnType, rtype); return; } //Getting here is just too bad. We do not know until the code runs whether or not to call an overloaded operator method. //Compile operands to objects and devolve the decision making to run time thunks il.Emit(OpCodes.Ldloc, (LocalBuilder)this.metaData); this.operand.TranslateToIL(il, Typeob.Object); il.Emit(OpCodes.Call, CompilerGlobals.evaluateUnaryMethod); Convert.Emit(this, il, Typeob.Object, rtype); }