internal override void SetPartialValue(AST partial_value) { //ResolveLHValue has already been called and has already checked if the target is accessible and assignable if (this.members == null || this.members.Length == 0) { return; //Assignment to an undeclared variable. Nothing further to do. } if (this.member is JSLocalField) { //If we are dealing with an assignment to an untyped local variable, we need to tell the type inferencer about the assignment JSLocalField lfield = (JSLocalField)this.member; if (lfield.type == null) { IReflect ir = partial_value.InferType(lfield); if (ir == Typeob.String && partial_value is Plus) { lfield.SetInferredType(Typeob.Object, partial_value); } else { lfield.SetInferredType(ir, partial_value); } //but then we are done return; } lfield.isDefined = true; } Binding.AssignmentCompatible(this.InferType(null), partial_value, partial_value.InferType(null), this.isFullyResolved); }
internal CallableExpression(AST expression) : base(expression.context, ""){ this.expression = expression; JSLocalField field = new JSLocalField("", null, 0, Missing.Value); this.expressionInferredType = expression.InferType(field); field.inferred_type = this.expressionInferredType; this.member = field; this.members = new MemberInfo[]{field}; }
internal CallableExpression(AST expression) : base(expression.context, "") { this.expression = expression; JSLocalField field = new JSLocalField("", null, 0, Microsoft.JScript.Missing.Value); this.expressionInferredType = expression.InferType(field); field.inferred_type = this.expressionInferredType; base.member = field; base.members = new MemberInfo[] { field }; }
internal override void SetPartialValue(AST partial_value) { if ((base.members != null) && (base.members.Length != 0)) { if (base.member is JSLocalField) { JSLocalField member = (JSLocalField)base.member; if (member.type == null) { IReflect ir = partial_value.InferType(member); if ((ir == Typeob.String) && (partial_value is Plus)) { member.SetInferredType(Typeob.Object, partial_value); return; } member.SetInferredType(ir, partial_value); return; } member.isDefined = true; } Binding.AssignmentCompatible(this.InferType(null), partial_value, partial_value.InferType(null), base.isFullyResolved); } }
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); } }
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); } }
private IReflect[] ArgIRs() { int count = this.args.count; IReflect[] reflectArray = new IReflect[count]; for (int i = 0; i < count; i++) { AST ast = this.args[i]; IReflect ir = reflectArray[i] = ast.InferType(null); if (ast is AddressOf) { if (ir is ClassScope) { ir = ((ClassScope)ir).GetBakedSuperType(); } reflectArray[i] = Microsoft.JScript.Convert.ToType("&", Microsoft.JScript.Convert.ToType(ir)); } } return(reflectArray); }
private IReflect[] ArgIRs() { int n = this.args.count; IReflect[] argIRs = new IReflect[n]; for (int i = 0; i < n; i++) { AST arg = this.args[i]; IReflect ir = argIRs[i] = arg.InferType(null); if (arg is AddressOf) { if (ir is ClassScope) { ir = ((ClassScope)ir).GetBakedSuperType(); //this should change if ever JS can declare out params } argIRs[i] = Convert.ToType("&", Convert.ToType(ir)); } } return(argIRs); }
internal override void SetPartialValue(AST partial_value){ //ResolveLHValue has already been called and has already checked if the target is accessible and assignable if (this.members == null || this.members.Length == 0) return; //Assignment to an undeclared variable. Nothing further to do. if (this.member is JSLocalField){ //If we are dealing with an assignment to an untyped local variable, we need to tell the type inferencer about the assignment JSLocalField lfield = (JSLocalField)this.member; if (lfield.type == null){ IReflect ir = partial_value.InferType(lfield); if (ir == Typeob.String && partial_value is Plus) lfield.SetInferredType(Typeob.Object, partial_value); else lfield.SetInferredType(ir, partial_value); //but then we are done return; } lfield.isDefined = true; } Binding.AssignmentCompatible(this.InferType(null), partial_value, partial_value.InferType(null), this.isFullyResolved); }
internal void SetPartialValue(ASTList argList, IReflect[] argIRs, AST partial_value, bool inBrackets){ if (this.members == null || this.members.Length == 0){ this.HandleNoSuchMemberError(); this.isAssignmentToDefaultIndexedProperty = true; return; //Have to do a runtime lookup } this.PartiallyEvaluate(); //The rhside value of the binding delivers the object with the default indexed property we are assigning to IReflect ir = this.InferType(null); this.isAssignmentToDefaultIndexedProperty = true; if (ir == Typeob.Object){ JSVariableField jsvf = this.member as JSVariableField; if (jsvf == null || !jsvf.IsLiteral || !(jsvf.value is ClassScope)) return; //Not enough is known at compile time to give an error ir = Typeob.Type; goto giveError; } //Might be an assignment to an array element if ((ir is TypedArray || (ir is Type && ((Type)ir).IsArray))){ bool gaveAnError = false; //Check dimension int n = argIRs.Length; int m = ir is TypedArray ? ((TypedArray)ir).rank : ((Type)ir).GetArrayRank(); if (n != m){ this.context.HandleError(JSError.IncorrectNumberOfIndices, this.isFullyResolved); gaveAnError = true; } //Check type of indices for (int i = 0; i < m; i++){ if (!gaveAnError && i < n && argIRs[i] != Typeob.Object && (!Convert.IsPrimitiveNumericType(argIRs[i]) || Convert.IsBadIndex(argList[i]))){ argList[i].context.HandleError(JSError.TypeMismatch, this.isFullyResolved); gaveAnError = true; } } this.isArrayElementAccess = true; this.isAssignmentToDefaultIndexedProperty = false; this.defaultMember = member; this.defaultMemberReturnIR = ir; IReflect elemIR = ir is TypedArray ? ((TypedArray)ir).elementType : ((Type)ir).GetElementType(); Binding.AssignmentCompatible(elemIR, partial_value, partial_value.InferType(null), this.isFullyResolved); return; } MemberInfo[] defaultMembers = JSBinder.GetDefaultMembers(ir); if (defaultMembers != null && defaultMembers.Length > 0 && this.member != null){ try{ PropertyInfo prop = JSBinder.SelectProperty(defaultMembers, argIRs); if (prop == null){ this.context.HandleError(JSError.NotIndexable, Convert.ToTypeName(ir)); return; } if (JSProperty.GetSetMethod(prop, true) == null){ if (ir == Typeob.String) this.context.HandleError(JSError.UselessAssignment); else this.context.HandleError(JSError.AssignmentToReadOnly, this.isFullyResolved&&this.Engine.doFast); return; } if (!Binding.CheckParameters(prop.GetIndexParameters(), argIRs, argList, this.context, 0, false, true)){ return; } this.defaultMember = this.member; this.defaultMemberReturnIR = ir; this.members = defaultMembers; this.member = prop; }catch(AmbiguousMatchException){ this.context.HandleError(JSError.AmbiguousMatch, this.isFullyResolved); this.member = null; } return; } giveError: this.member = null; if (!inBrackets) this.context.HandleError(JSError.IllegalAssignment); else this.context.HandleError(JSError.NotIndexable, Convert.ToTypeName(ir)); }
internal override void SetPartialValue(AST partial_value){ Binding.AssignmentCompatible(this.InferType(null), partial_value, partial_value.InferType(null), this.isFullyResolved); }