public Invocation( int[] parentNodeIndices, int statementIndex, int nodeIndex, JSVariable thisVariable, JSMethod method, object nonJSMethod, IDictionary <string, string[]> variables ) : base(parentNodeIndices, statementIndex, nodeIndex) { if (thisVariable != null) { ThisVariable = thisVariable.Identifier; } else { ThisVariable = null; } ThisType = null; Method = method; if (method == null) { NonJSMethod = nonJSMethod; } else { NonJSMethod = null; } Variables = variables; }
public ParameterTypeComment(JSType jstype, String parameterName) : base("ParameterTypeComment") { base.tagValues = new Dictionary <string, string> { { typeTag, jstype.JSTypeDef }, { nameTag, parameterName } }; }
public static bool JSEqualsExact(JSValue a, JSValue b) { JSType t1 = a.ObjectType; JSType t2 = b.ObjectType; if (t1 != t2) { return(false); } switch (t1) { case JSType.Number: return(a.NumberValue() == b.NumberValue()); case JSType.String: return(a.StringValue() == b.StringValue()); case JSType.Boolean: return(a.BoolValue() == b.BoolValue()); case JSType.Null: return(true); case JSType.Undefined: return(true); } return(a == b); }
public override void GenTyped(CompileContext compileContext) { JSType TreeType = this.TreeType; ((ExpressionNode)base.Children[0]).GenTyped(compileContext, TreeType); ((ExpressionNode)base.Children[1]).GenTyped(compileContext, TreeType); this.GenTypedOp(compileContext); }
public Invocation(int statementIndex, int nodeIndex, JSVariable thisVariable, JSMethod method, IDictionary <string, string[]> variables) : base(statementIndex, nodeIndex) { ThisVariable = thisVariable.Identifier; ThisType = null; Method = method; Variables = variables; }
public EmulateInt64(MethodTypeFactory methodTypeFactory, TypeSystem typeSystem) { TypeSystem = typeSystem; MethodTypeFactory = methodTypeFactory; int64 = new JSType(TypeSystem.Int64); uint64 = new JSType(TypeSystem.UInt64); }
internal void GenTyped(CompileContext compileContext, JSType aJType) { if (this.TreeType == aJType) { this.GenTyped(compileContext); } else { this.GenTypedBase(compileContext, aJType); } }
public Invocation( int[] parentNodeIndices, int statementIndex, int nodeIndex, JSType type, JSMethod method, IDictionary <string, string[]> variables ) : base(parentNodeIndices, statementIndex, nodeIndex) { ThisType = type; ThisVariable = null; Method = method; Variables = variables; }
public void VisitNode(JSType type) { var ct = GetCachedType(type.Type); if (ct != null) { ParentNode.ReplaceChild(type, ct); VisitReplacement(ct); } else { VisitChildren(type); } }
public void VisitNode(JSPublicInterfaceOfExpression poe) { VisitChildren(poe); // Replace foo.__Type__.__PublicInterface__ with foo var innerTypeOf = poe.Inner as ITypeOfExpression; if (innerTypeOf != null) { var replacement = new JSType(innerTypeOf.Type); ParentNode.ReplaceChild(poe, replacement); VisitReplacement(replacement); } }
public override JSExpression Translate(ILBlockTranslator translator, JSExpression[] arguments) { var thisArgument = FixupThisArgument(arguments[1], translator.TypeSystem); var returnType = ReturnType; if (returnType == null) { returnType = translator.TypeSystem.Void; } var argumentValues = arguments.Skip(2).ToArray(); var memberName = MemberName; if ((TypeArguments != null) && (TypeArguments.Length > 0)) { memberName += "`" + TypeArguments.Length; } var thisArgumentKnownType = JSType.ExtractType(thisArgument); if (thisArgumentKnownType != null) { var replacement = translator.DoJSILMethodReplacement( thisArgumentKnownType.FullName, memberName, null, // FIXME null, argumentValues ); if (replacement != null) { return(replacement); } } return(JSInvocationExpression.InvokeMethod( new JSFakeMethod( memberName, returnType, (from av in argumentValues select av.GetActualType(translator.TypeSystem)).ToArray(), translator.MethodTypes, TypeArguments, escape: true ), thisArgument, arguments.Skip(2).ToArray() )); }
public override void GenTyped(CompileContext compileContext) { ExpressionNode n1 = (ExpressionNode)base.Children[0]; JSType t1 = n1.TreeType; ExpressionNode n2 = (ExpressionNode)base.Children[1]; JSType t2 = n2.TreeType; if ((t1 == JSType.Number) && (t2 == JSType.Number)) { ((ExpressionNode)base.Children[0]).GenTyped(compileContext, JSType.Number); ((ExpressionNode)base.Children[1]).GenTyped(compileContext, JSType.Number); this.GenTypedOp(compileContext); } else { ((ExpressionNode)base.Children[0]).GenCode(compileContext); ((ExpressionNode)base.Children[1]).GenCode(compileContext); this.GenUntypedOp(compileContext); } }
public Invocation( NodeIndices parentNodeIndices, int statementIndex, int nodeIndex, JSType type, JSMethod method, object nonJSMethod, Dictionary <string, ArraySegment <string> > variables ) : base(parentNodeIndices, statementIndex, nodeIndex) { ThisType = type; ThisVariable = null; Method = method; if (method == null) { NonJSMethod = nonJSMethod; } else { NonJSMethod = null; } Variables = variables; }
private void GenTypedBase(CompileContext compileContext, JSType aJType) { this.GenCode(compileContext); switch (aJType) { case JSType.Number: compileContext.gen.EmitCallV(CompileContext.mi_JSValue_NumberValue); break; case JSType.String: compileContext.gen.EmitCallV(CompileContext.mi_JSValue_StringValue); break; case JSType.Boolean: compileContext.gen.EmitCallV(CompileContext.mi_JSValue_BoolValue); break; default: throw new Exception(); } }
public static bool JSEquals(JSValue a, JSValue b) { JSType t1 = a.ObjectType; JSType t2 = b.ObjectType; if (t1 != t2) { switch (t2) { case JSType.Boolean: return(JSEquals(a, b.ToJSNumber())); case JSType.Object: return(JSEquals(a, b.ToPrimitive())); } switch (t1) { case JSType.Number: if (t2 != JSType.String) { goto Label_016F; } return(a.NumberValue() == b.NumberValue()); case JSType.String: if (t2 != JSType.Number) { goto Label_016F; } return(a.NumberValue() == b.NumberValue()); case JSType.Boolean: return(JSEquals(a.ToJSNumber(), b)); case JSType.Object: return(JSEquals(a.ToPrimitive(), b)); case JSType.Array: case JSType.Function: goto Label_016F; case JSType.Null: return(t2 == JSType.Undefined); case JSType.Undefined: return(t2 == JSType.Null); } } else { switch (t1) { case JSType.Number: return(a.NumberValue() == b.NumberValue()); case JSType.String: return(a.StringValue() == b.StringValue()); case JSType.Boolean: return(a.BoolValue() == b.BoolValue()); case JSType.Null: return(true); case JSType.Undefined: return(true); } return(a == b); } Label_016F: return(false); }
public JSHandler(JSType type) { JSType = type; }
public JS(JSType type) { JSType = type; }
private static void Parse(Member member) { if (!member.Consolidated) { member.Consolidated = true; JSType type = null; // parse the assignments foreach (var mem in member.Assignments.Values) { if (!mem.Consolidated) { Parse(mem); } if (type == null) { type = mem.ConsolidatedType; } else { // here we must dfecide which type has priority if they are different if (mem.ConsolidatedType != null && type.GetName() != mem.ConsolidatedType.GetName()) { type = new BasicType() { Type = DataType.Dynamic }; } } } // done parsing children, lets create this type if (type == null && member.Type != MemberType.Global && member.Type != MemberType.Parameter && member.Type != MemberType.AnonymousFunction && member.Type != MemberType.Value && member.Type != MemberType.Method && member.Type != MemberType.Function) { // nothing was assigned to this type, so it IS the base type, lets create it type = new Class() { Name = member.FullNameReal }; classes.Add((Class)type); } else if (type == null && member.Type == MemberType.Value) { // nothing was assigned to this type, so it IS the base type, lets create it type = new BasicType() { Type = member.DataType }; } // and now children types if (member.Constructor != null) { Parse(member.Constructor); if (type != null && type is Class) { ((Class)type).Constructors.Add(GenerateMethod(member.Constructor)); } } foreach (var mem in member.Parameters.Values) { Parse(mem); } foreach (var mem in member.Members.Values) { Parse(mem); if (type != null && type.GetType() != typeof(BasicType)) { if (mem.Type == MemberType.Function || mem.Type == MemberType.Method) { Method meth = GenerateMethod(mem); if (!((Class)type).Methods.ContainsKey(meth.Name)) { ((Class)type).Methods.Add(meth.Name, meth); } } else if (mem.Type == MemberType.Member && mem.ConsolidatedType != null) { CMember memb = new CMember() { Name = mem.GetOfficialName(), Type = mem.ConsolidatedType.GetName() }; if (!((Class)type).Members.ContainsKey(memb.Name)) { ((Class)type).Members.Add(memb.Name, memb); } } } } foreach (var mem in member.Body.Values) { Parse(mem); } foreach (var mem in member.ReturnMembers.Values) { Parse(mem); type = mem.ConsolidatedType; } member.ConsolidatedType = type; } }
public void VisitNode(JSInvocationExpression ie) { var type = ie.JSType; var method = ie.JSMethod; var thisExpression = ie.ThisReference; if (method != null) { if ( (type != null) && (type.Type.FullName == "System.Object") ) { switch (method.Method.Member.Name) { case ".ctor": { var replacement = new JSNullExpression(); ParentNode.ReplaceChild(ie, replacement); VisitReplacement(replacement); return; } case "GetType": { JSNode replacement; var thisType = JSExpression.DeReferenceType(thisExpression.GetActualType(TypeSystem), false); if ((thisType is GenericInstanceType) && thisType.FullName.StartsWith("System.Nullable")) { replacement = new JSType(thisType); } else { replacement = JSIL.GetTypeOf(thisExpression); } ParentNode.ReplaceChild(ie, replacement); VisitReplacement(replacement); return; } } } else if ( IsNullable(type.Type) ) { var t = (type.Type as GenericInstanceType).GenericArguments[0]; var @null = JSLiteral.Null(t); var @default = new JSDefaultValueLiteral(t); switch (method.Method.Member.Name) { case ".ctor": JSExpression value; if (ie.Arguments.Count == 0) { value = @null; } else { value = ie.Arguments[0]; } var boe = new JSBinaryOperatorExpression( JSOperator.Assignment, ie.ThisReference, value, type.Type ); ParentNode.ReplaceChild(ie, boe); VisitReplacement(boe); break; case "GetValueOrDefault": var isNull = new JSBinaryOperatorExpression( JSOperator.Equal, ie.ThisReference, @null, TypeSystem.Boolean ); JSTernaryOperatorExpression ternary; if (ie.Arguments.Count == 0) { ternary = new JSTernaryOperatorExpression( isNull, @default, ie.ThisReference, type.Type ); } else { ternary = new JSTernaryOperatorExpression( isNull, ie.Arguments[0], ie.ThisReference, type.Type ); } ParentNode.ReplaceChild(ie, ternary); VisitReplacement(ternary); break; default: throw new NotImplementedException(method.Method.Member.FullName); } return; } else if ( (type != null) && TypeUtil.TypesAreEqual(TypeSystem.String, type.Type) && (method.Method.Name == "Concat") ) { if (ie.Arguments.Count > 2) { if (ie.Arguments.All( (arg) => TypeUtil.TypesAreEqual( TypeSystem.String, arg.GetActualType(TypeSystem) ) )) { var boe = JSBinaryOperatorExpression.New( JSOperator.Add, ie.Arguments, TypeSystem.String ); ParentNode.ReplaceChild( ie, boe ); VisitReplacement(boe); } } else if ( ie.Arguments.Count == 2 ) { var lhs = ie.Arguments[0]; var lhsType = TypeUtil.DereferenceType(lhs.GetActualType(TypeSystem)); if (!( TypeUtil.TypesAreEqual(TypeSystem.String, lhsType) || TypeUtil.TypesAreEqual(TypeSystem.Char, lhsType) )) { lhs = JSInvocationExpression.InvokeMethod(lhsType, JS.toString, lhs, null); } var rhs = ie.Arguments[1]; var rhsType = TypeUtil.DereferenceType(rhs.GetActualType(TypeSystem)); if (!( TypeUtil.TypesAreEqual(TypeSystem.String, rhsType) || TypeUtil.TypesAreEqual(TypeSystem.Char, rhsType) )) { rhs = JSInvocationExpression.InvokeMethod(rhsType, JS.toString, rhs, null); } var boe = new JSBinaryOperatorExpression( JSOperator.Add, lhs, rhs, TypeSystem.String ); ParentNode.ReplaceChild( ie, boe ); VisitReplacement(boe); } else if ( TypeUtil.GetTypeDefinition(ie.Arguments[0].GetActualType(TypeSystem)).FullName == "System.Array" ) { } else { var firstArg = ie.Arguments.FirstOrDefault(); ParentNode.ReplaceChild( ie, firstArg ); if (firstArg != null) { VisitReplacement(firstArg); } } return; } else if ( TypeUtil.IsDelegateType(method.Reference.DeclaringType) && (method.Method.Name == "Invoke") ) { var newIe = new JSDelegateInvocationExpression( thisExpression, ie.GetActualType(TypeSystem), ie.Arguments.ToArray() ); ParentNode.ReplaceChild(ie, newIe); VisitReplacement(newIe); return; } else if ( (method.Reference.DeclaringType.FullName == "System.Type") && (method.Method.Name == "GetTypeFromHandle") ) { var typeObj = ie.Arguments.FirstOrDefault(); ParentNode.ReplaceChild(ie, typeObj); VisitReplacement(typeObj); return; } else if ( (method.Reference.DeclaringType.Name == "RuntimeHelpers") && (method.Method.Name == "InitializeArray") ) { var array = ie.Arguments[0]; var arrayType = array.GetActualType(TypeSystem); var field = ie.Arguments[1].SelfAndChildrenRecursive.OfType <JSField>().First(); var initializer = JSArrayExpression.UnpackArrayInitializer(arrayType, field.Field.Member.InitialValue); var copy = JSIL.ShallowCopy(array, initializer, arrayType); ParentNode.ReplaceChild(ie, copy); VisitReplacement(copy); return; } else if ( method.Reference.DeclaringType.FullName == "System.Reflection.Assembly" ) { switch (method.Reference.Name) { case "GetExecutingAssembly": { var assembly = Method.DeclaringType.Module.Assembly; var asmNode = new JSAssembly(assembly); ParentNode.ReplaceChild(ie, asmNode); VisitReplacement(asmNode); return; } case "GetType": { switch (method.Method.Parameters.Length) { case 1: case 2: JSExpression throwOnFail = new JSBooleanLiteral(false); if (method.Method.Parameters.Length == 2) { throwOnFail = ie.Arguments[1]; } var invocation = JSIL.GetTypeFromAssembly( ie.ThisReference, ie.Arguments[0], throwOnFail ); ParentNode.ReplaceChild(ie, invocation); VisitReplacement(invocation); return; } break; } } } else if ( method.Method.DeclaringType.Definition.FullName == "System.Array" && (ie.Arguments.Count == 1) ) { switch (method.Method.Name) { case "GetLength": case "GetUpperBound": { var index = ie.Arguments[0] as JSLiteral; if (index != null) { var newDot = JSDotExpression.New(thisExpression, new JSStringIdentifier( String.Format("length{0}", Convert.ToInt32(index.Literal)), TypeSystem.Int32 )); if (method.Method.Name == "GetUpperBound") { var newExpr = new JSBinaryOperatorExpression( JSOperator.Subtract, newDot, JSLiteral.New(1), TypeSystem.Int32 ); ParentNode.ReplaceChild(ie, newExpr); } else { ParentNode.ReplaceChild(ie, newDot); } } break; } case "GetLowerBound": ParentNode.ReplaceChild(ie, JSLiteral.New(0)); break; } } } VisitChildren(ie); }
private void GenTypedBase(CompileContext compileContext, JSType aJType) { this.GenCode(compileContext); switch (aJType) { case JSType.Number: compileContext.gen.EmitCallV( CompileContext.mi_JSValue_NumberValue); break; case JSType.String: compileContext.gen.EmitCallV( CompileContext.mi_JSValue_StringValue); break; case JSType.Boolean: compileContext.gen.EmitCallV( CompileContext.mi_JSValue_BoolValue); break; default: throw new Exception(); } }
public void VisitNode(JSType type) { Output.Identifier( type.Type, ReferenceContext, IncludeTypeParens.Peek() ); }