public CodeExpression[] Generate(Table table, HardwireCodeGenerationContext generatorContext, CodeTypeMemberCollection members) { string className = "AIDX_" + Guid.NewGuid().ToString("N"); string name = table.Get("name").String; bool setter = table.Get("setter").Boolean; CodeTypeDeclaration classCode = new CodeTypeDeclaration(className); classCode.TypeAttributes = System.Reflection.TypeAttributes.NestedPrivate | System.Reflection.TypeAttributes.Sealed; classCode.BaseTypes.Add(typeof(ArrayMemberDescriptor)); CodeConstructor ctor = new CodeConstructor(); ctor.Attributes = MemberAttributes.Assembly; classCode.Members.Add(ctor); ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(name)); ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(setter)); DynValue vparams = table.Get("params"); if (vparams.Type == DataType.Table) { List <HardwireParameterDescriptor> paramDescs = HardwireParameterDescriptor.LoadDescriptorsFromTable(vparams.Table); ctor.BaseConstructorArgs.Add(new CodeArrayCreateExpression(typeof(ParameterDescriptor), paramDescs.Select(e => e.Expression).ToArray())); } members.Add(classCode); return(new CodeExpression[] { new CodeObjectCreateExpression(className) }); }
public CodeExpression[] Generate(Table table, HardwireCodeGenerationContext generatorContext, CodeTypeMemberCollection members) { string className = "AIDX_" + Guid.NewGuid().ToString("N"); string name = table.Get("name").String; bool setter = table.Get("setter").Boolean; CodeTypeDeclaration classCode = new CodeTypeDeclaration(className); classCode.TypeAttributes = System.Reflection.TypeAttributes.NestedPrivate | System.Reflection.TypeAttributes.Sealed; classCode.BaseTypes.Add(typeof(ArrayMemberDescriptor)); CodeConstructor ctor = new CodeConstructor(); ctor.Attributes = MemberAttributes.Assembly; classCode.Members.Add(ctor); ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(name)); ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(setter)); DynValue vparams = table.Get("params"); if (vparams.Type == DataType.Table) { List<HardwireParameterDescriptor> paramDescs = HardwireParameterDescriptor.LoadDescriptorsFromTable(vparams.Table); ctor.BaseConstructorArgs.Add(new CodeArrayCreateExpression(typeof(ParameterDescriptor), paramDescs.Select(e => e.Expression).ToArray())); } members.Add(classCode); return new CodeExpression[] { new CodeObjectCreateExpression(className) }; }
public CodeExpression[] Generate(Table table, HardwireCodeGenerationContext generatorContext, CodeTypeMemberCollection members) { string className = "DVAL_" + Guid.NewGuid().ToString("N"); DynValue kval = table.Get("value"); DynValue vtype = table.Get("type"); DynValue vstaticType = table.Get("staticType"); string type = (vtype.Type == DataType.String) ? vtype.String : null; string staticType = (vstaticType.Type == DataType.String) ? vstaticType.String : null; CodeTypeDeclaration classCode = new CodeTypeDeclaration(className); classCode.TypeAttributes = System.Reflection.TypeAttributes.NestedPrivate | System.Reflection.TypeAttributes.Sealed; classCode.BaseTypes.Add(typeof(DynValueMemberDescriptor)); CodeConstructor ctor = new CodeConstructor(); ctor.Attributes = MemberAttributes.Assembly; classCode.Members.Add(ctor); if (type == null) { Table tbl = new Table(null); tbl.Set(1, kval); string str = tbl.Serialize(); ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(table.Get("name").String)); ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(str)); } else if (type == "userdata") { ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(table.Get("name").String)); CodeMemberProperty p = new CodeMemberProperty(); p.Name = "Value"; p.Type = new CodeTypeReference(typeof(DynValue)); p.Attributes = MemberAttributes.Override | MemberAttributes.Public; p.GetStatements.Add( new CodeMethodReturnStatement( new CodeMethodInvokeExpression( new CodeTypeReferenceExpression(typeof(UserData)), "CreateStatic", new CodeTypeOfExpression(staticType)))); classCode.Members.Add(p); } members.Add(classCode); return(new CodeExpression[] { new CodeObjectCreateExpression(className) }); }
public CodeExpression[] Generate(Table table, HardwireCodeGenerationContext generatorContext, CodeTypeMemberCollection members) { string className = "DVAL_" + Guid.NewGuid().ToString("N"); DynValue kval = table.Get("value"); DynValue vtype = table.Get("type"); DynValue vstaticType = table.Get("staticType"); string type = (vtype.Type == DataType.String) ? vtype.String : null; string staticType = (vstaticType.Type == DataType.String) ? vstaticType.String : null; CodeTypeDeclaration classCode = new CodeTypeDeclaration(className); classCode.TypeAttributes = System.Reflection.TypeAttributes.NestedPrivate | System.Reflection.TypeAttributes.Sealed; classCode.BaseTypes.Add(typeof(DynValueMemberDescriptor)); CodeConstructor ctor = new CodeConstructor(); ctor.Attributes = MemberAttributes.Assembly; classCode.Members.Add(ctor); if (type == null) { Table tbl = new Table(null); tbl.Set(1, kval); string str = tbl.Serialize(); ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(table.Get("name").String)); ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(str)); } else if (type == "userdata") { ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(table.Get("name").String)); CodeMemberProperty p = new CodeMemberProperty(); p.Name = "Value"; p.Type = new CodeTypeReference(typeof(DynValue)); p.Attributes = MemberAttributes.Override | MemberAttributes.Public; p.GetStatements.Add( new CodeMethodReturnStatement( new CodeMethodInvokeExpression( new CodeTypeReferenceExpression(typeof(UserData)), "CreateStatic", new CodeTypeOfExpression(staticType)))); classCode.Members.Add(p); } members.Add(classCode); return new CodeExpression[] { new CodeObjectCreateExpression(className) }; }
public CodeExpression[] Generate(Table table, HardwireCodeGenerationContext generator, CodeTypeMemberCollection members) { string type = (string)table["$key"]; string className = "TYPE_" + Guid.NewGuid().ToString("N"); CodeTypeDeclaration classCode = new CodeTypeDeclaration(className); classCode.Comments.Add(new CodeCommentStatement("Descriptor of " + type)); classCode.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Descriptor of " + type)); classCode.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, string.Empty)); classCode.TypeAttributes = System.Reflection.TypeAttributes.NestedPrivate | System.Reflection.TypeAttributes.Sealed; classCode.BaseTypes.Add(typeof(HardwiredUserDataDescriptor)); CodeConstructor ctor = new CodeConstructor(); ctor.Attributes = MemberAttributes.Assembly; ctor.BaseConstructorArgs.Add(new CodeTypeOfExpression(type)); classCode.Members.Add(ctor); generator.DispatchTablePairs(table.Get("members").Table, classCode.Members, (key, exp) => { var mname = new CodePrimitiveExpression(key); ctor.Statements.Add(new CodeMethodInvokeExpression( new CodeThisReferenceExpression(), "AddMember", mname, exp)); }); generator.DispatchTablePairs(table.Get("metamembers").Table, classCode.Members, (key, exp) => { var mname = new CodePrimitiveExpression(key); ctor.Statements.Add(new CodeMethodInvokeExpression( new CodeThisReferenceExpression(), "AddMetaMember", mname, exp)); }); members.Add(classCode); return new CodeExpression[] { new CodeObjectCreateExpression(className) }; }
public CodeExpression[] Generate(Table table, HardwireCodeGenerationContext generator, CodeTypeMemberCollection members) { MethodMemberDescriptorGenerator mgen = new MethodMemberDescriptorGenerator("VTDC"); Table mt = new Table(null); mt["params"] = new Table(null); mt["name"] = "__new"; mt["type"] = table["type"]; mt["ctor"] = true; mt["extension"] = false; mt["decltype"] = table["type"]; mt["ret"] = table["type"]; mt["special"] = false; return(mgen.Generate(mt, generator, members)); }
public CodeExpression[] Generate(Table table, HardwireCodeGenerationContext generator, CodeTypeMemberCollection members) { MethodMemberDescriptorGenerator mgen = new MethodMemberDescriptorGenerator("VTDC"); Table mt = new Table(null); mt["params"] = new Table(null); mt["name"] = "__new"; mt["type"] = table["type"]; mt["ctor"] = true; mt["extension"] = false; mt["decltype"] = table["type"]; mt["ret"] = table["type"]; mt["special"] = false; return mgen.Generate(mt, generator, members); }
public CodeExpression[] Generate(Table table, HardwireCodeGenerationContext generator, CodeTypeMemberCollection members) { List<CodeExpression> initializers = new List<CodeExpression>(); generator.DispatchTablePairs(table.Get("overloads").Table, members, exp => { initializers.Add(exp); }); var name = new CodePrimitiveExpression((table["name"] as string)); var type = new CodeTypeOfExpression(table["decltype"] as string); var array = new CodeArrayCreateExpression(typeof(IOverloadableMemberDescriptor), initializers.ToArray()); return new CodeExpression[] { new CodeObjectCreateExpression(typeof(OverloadedMethodMemberDescriptor), name, type, array) }; }
public CodeExpression[] Generate(Table table, HardwireCodeGenerationContext generator, CodeTypeMemberCollection members) { List <CodeExpression> initializers = new List <CodeExpression>(); generator.DispatchTablePairs(table.Get("overloads").Table, members, exp => { initializers.Add(exp); }); var name = new CodePrimitiveExpression((table["name"] as string)); var type = new CodeTypeOfExpression(table["decltype"] as string); var array = new CodeArrayCreateExpression(typeof(IOverloadableMemberDescriptor), initializers.ToArray()); return(new CodeExpression[] { new CodeObjectCreateExpression(typeof(OverloadedMethodMemberDescriptor), name, type, array) }); }
private void EmitInvalid(HardwireCodeGenerationContext generator, CodeStatementCollection coll, string message) { generator.Warning(message); coll.Add(new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(InvalidOperationException), new CodePrimitiveExpression(message)))); }
private CodeStatementCollection GenerateCall(Table table, HardwireCodeGenerationContext generator, bool isVoid, bool isCtor, bool isStatic, bool isExtension, CodeExpression[] arguments, CodeExpression paramThis, string declaringType, bool specialName, int refparCount) { string arrayCtorType = table.Get("arraytype").IsNil() ? null : table.Get("arraytype").String; CodeStatementCollection coll = new CodeStatementCollection(); CodeExpression retVal = null; if (isCtor) { if (arrayCtorType != null) { var exp = generator.TargetLanguage.CreateMultidimensionalArray(arrayCtorType, arguments); retVal = new CodeArrayCreateExpression(arrayCtorType, arguments); } else { retVal = new CodeObjectCreateExpression(table.Get("ret").String, arguments); } } else if (specialName) { GenerateSpecialNameCall(table, generator, isVoid, isCtor, isStatic, isExtension, arguments, paramThis, declaringType, table.Get("name").String, coll); } else { retVal = new CodeMethodInvokeExpression(paramThis, table.Get("name").String, arguments); } if (retVal != null) { if (isVoid) { coll.Add(new CodeExpressionStatement(retVal)); retVal = new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(typeof(DynValue)), (refparCount == 0) ? "Void" : "Nil"); } if (refparCount == 0) { coll.Add(new CodeMethodReturnStatement(retVal)); } else { coll.Add(new CodeVariableDeclarationStatement(typeof(object), "retv", retVal)); List <CodeExpression> retVals = new List <CodeExpression>(); retVals.Add(WrapFromObject(new CodeVariableReferenceExpression("retv"))); for (int i = 0; i < refparCount; i++) { retVals.Add(WrapFromObject(new CodeVariableReferenceExpression(GenerateRefParamVariable(i)))); } var arrayExp = new CodeArrayCreateExpression(typeof(DynValue), retVals.ToArray()); var tupleExp = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(DynValue)), "NewTuple", arrayExp); coll.Add(new CodeMethodReturnStatement(tupleExp)); } } return(coll); }
public CodeExpression[] Generate(Table table, HardwireCodeGenerationContext generator, CodeTypeMemberCollection members) { bool isStatic = table.Get("static").Boolean; string memberType = table.Get("type").String; string name = table.Get("name").String; string decltype = table.Get("decltype").String; bool declvtype = table.Get("declvtype").Boolean; bool canWrite = table.Get("write").Boolean; bool canRead = table.Get("read").Boolean; if (declvtype && canWrite) { generator.Warning("Member '{0}.{1}::Set' will be a no-op, as it's a member of a value type.", decltype, name); } MemberDescriptorAccess access = 0; if (canWrite) access = access | MemberDescriptorAccess.CanWrite; if (canRead) access = access | MemberDescriptorAccess.CanRead; string className = GetPrefix() + "_" + Guid.NewGuid().ToString("N"); CodeTypeDeclaration classCode = new CodeTypeDeclaration(className); classCode.TypeAttributes = System.Reflection.TypeAttributes.NestedPrivate | System.Reflection.TypeAttributes.Sealed; classCode.BaseTypes.Add(typeof(HardwiredMemberDescriptor)); // protected HardwiredMemberDescriptor(Type memberType, string name, bool isStatic, MemberDescriptorAccess access) CodeConstructor ctor = new CodeConstructor(); ctor.Attributes = MemberAttributes.Assembly; ctor.BaseConstructorArgs.Add(new CodeTypeOfExpression(memberType)); ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(name)); ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(isStatic)); ctor.BaseConstructorArgs.Add(new CodeCastExpression(typeof(MemberDescriptorAccess), new CodePrimitiveExpression((int)access))); classCode.Members.Add(ctor); var thisExp = isStatic ? (CodeExpression)(new CodeTypeReferenceExpression(decltype)) : (CodeExpression)(new CodeCastExpression(decltype, new CodeVariableReferenceExpression("obj"))); if (canRead) { var memberExp = GetMemberAccessExpression(thisExp, name); // protected virtual object GetValueImpl(Script script, object obj) CodeMemberMethod m = new CodeMemberMethod(); classCode.Members.Add(m); m.Name = "GetValueImpl"; m.Attributes = MemberAttributes.Override | MemberAttributes.Family; m.ReturnType = new CodeTypeReference(typeof(object)); m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Script), "script")); m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "obj")); m.Statements.Add(new CodeMethodReturnStatement(memberExp)); } if (canWrite) { // protected virtual object GetValueImpl(Script script, object obj) CodeMemberMethod m = new CodeMemberMethod(); classCode.Members.Add(m); m.Name = "SetValueImpl"; m.Attributes = MemberAttributes.Override | MemberAttributes.Family; m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Script), "script")); m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "obj")); m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "value")); var valExp = new CodeCastExpression(memberType, new CodeVariableReferenceExpression("value")); if (isStatic) { var e = GetMemberAccessExpression(thisExp, name); m.Statements.Add(new CodeAssignStatement(e, valExp)); } else { m.Statements.Add(new CodeVariableDeclarationStatement(decltype, "tmp", thisExp)); var memberExp = GetMemberAccessExpression(new CodeVariableReferenceExpression("tmp"), name); m.Statements.Add(new CodeAssignStatement(memberExp, valExp)); } } members.Add(classCode); return new CodeExpression[] { new CodeObjectCreateExpression(className) }; }
private void GenerateSpecialNameCall(Table table, HardwireCodeGenerationContext generator, bool isVoid, bool isCtor, bool isStatic, bool isExtension, CodeExpression[] arguments, CodeExpression paramThis, string declaringType, string specialName, CodeStatementCollection coll) { ReflectionSpecialName special = new ReflectionSpecialName(specialName); CodeExpression exp = null; CodeStatement stat = null; switch (special.Type) { case ReflectionSpecialNameType.IndexGetter: if (isStatic) { EmitInvalid(generator, coll, "Static indexers are not supported by hardwired descriptors."); } else { exp = new CodeIndexerExpression(paramThis, arguments); } break; case ReflectionSpecialNameType.IndexSetter: if (isStatic) { EmitInvalid(generator, coll, "Static indexers are not supported by hardwired descriptors."); } else { coll.Add(new CodeVariableDeclarationStatement(declaringType, "tmp", paramThis)); stat = new CodeAssignStatement(new CodeIndexerExpression(new CodeVariableReferenceExpression("tmp"), arguments.Take(arguments.Length - 1).ToArray()), arguments.Last()); } break; case ReflectionSpecialNameType.ImplicitCast: case ReflectionSpecialNameType.ExplicitCast: exp = paramThis; break; case ReflectionSpecialNameType.OperatorTrue: GenerateBooleanOperator(paramThis, coll, true); break; case ReflectionSpecialNameType.OperatorFalse: generator.Minor("'false' operator is implemented in terms of 'true' operator."); GenerateBooleanOperator(paramThis, coll, false); break; case ReflectionSpecialNameType.PropertyGetter: exp = new CodePropertyReferenceExpression(paramThis, special.Argument); break; case ReflectionSpecialNameType.PropertySetter: { if (isStatic) { var memberExp = new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(declaringType), special.Argument); coll.Add(new CodeAssignStatement(memberExp, arguments[0])); } else { coll.Add(new CodeVariableDeclarationStatement(declaringType, "tmp", paramThis)); var memberExp = new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("tmp"), special.Argument); coll.Add(new CodeAssignStatement(memberExp, arguments[0])); } coll.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null))); } break; case ReflectionSpecialNameType.OperatorAdd: exp = BinaryOperator(CodeBinaryOperatorType.Add, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorAnd: exp = BinaryOperator(CodeBinaryOperatorType.BitwiseAnd, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorOr: exp = BinaryOperator(CodeBinaryOperatorType.BitwiseOr, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorDec: exp = generator.TargetLanguage.UnaryDecrement(arguments[0]); if (exp == null) { EmitInvalid(generator, coll, string.Format("Language {0} does not support decrement operators.", generator.TargetLanguage.Name)); } break; case ReflectionSpecialNameType.OperatorDiv: exp = BinaryOperator(CodeBinaryOperatorType.Divide, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorEq: exp = BinaryOperator(CodeBinaryOperatorType.ValueEquality, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorXor: exp = generator.TargetLanguage.BinaryXor(arguments[0], arguments[1]); if (exp == null) { EmitInvalid(generator, coll, string.Format("Language {0} does not support XOR operators.", generator.TargetLanguage.Name)); } break; case ReflectionSpecialNameType.OperatorGt: exp = BinaryOperator(CodeBinaryOperatorType.GreaterThan, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorGte: exp = BinaryOperator(CodeBinaryOperatorType.GreaterThanOrEqual, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorInc: exp = generator.TargetLanguage.UnaryIncrement(arguments[0]); if (exp == null) { EmitInvalid(generator, coll, string.Format("Language {0} does not support increment operators.", generator.TargetLanguage.Name)); } break; case ReflectionSpecialNameType.OperatorNeq: exp = BinaryOperator(CodeBinaryOperatorType.IdentityInequality, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorLt: exp = BinaryOperator(CodeBinaryOperatorType.LessThan, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorLte: exp = BinaryOperator(CodeBinaryOperatorType.LessThanOrEqual, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorNot: exp = generator.TargetLanguage.UnaryLogicalNot(arguments[0]); if (exp == null) { EmitInvalid(generator, coll, string.Format("Language {0} does not support logical NOT operators.", generator.TargetLanguage.Name)); } break; case ReflectionSpecialNameType.OperatorMod: exp = BinaryOperator(CodeBinaryOperatorType.Modulus, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorMul: exp = BinaryOperator(CodeBinaryOperatorType.Multiply, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorCompl: exp = generator.TargetLanguage.UnaryOneComplement(arguments[0]); if (exp == null) { EmitInvalid(generator, coll, string.Format("Language {0} does not support bitwise NOT operators.", generator.TargetLanguage.Name)); } break; case ReflectionSpecialNameType.OperatorSub: exp = BinaryOperator(CodeBinaryOperatorType.Subtract, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorNeg: exp = generator.TargetLanguage.UnaryNegation(arguments[0]); if (exp == null) { EmitInvalid(generator, coll, string.Format("Language {0} does not support negation operators.", generator.TargetLanguage.Name)); } break; case ReflectionSpecialNameType.OperatorUnaryPlus: exp = generator.TargetLanguage.UnaryPlus(arguments[0]); if (exp == null) { EmitInvalid(generator, coll, string.Format("Language {0} does not support unary + operators.", generator.TargetLanguage.Name)); } break; case ReflectionSpecialNameType.AddEvent: case ReflectionSpecialNameType.RemoveEvent: coll.Add(new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(InvalidOperationException), new CodePrimitiveExpression("Access to event special methods is not supported by hardwired decriptors.")))); break; default: break; } if (stat != null) { coll.Add(stat); exp = exp ?? new CodePrimitiveExpression(null); } if (exp != null) { coll.Add(new CodeMethodReturnStatement(exp)); } }
public CodeExpression[] Generate(Table table, HardwireCodeGenerationContext generator, CodeTypeMemberCollection members) { bool isArray = table.Get("arraytype").IsNotNil(); string memberName = table.Get("name").String; // Ignore arrays weird special members if (isArray) { if ((memberName == "Get") || (memberName == "Set") || (memberName == "Address")) { return(null); } } // Create the descriptor class string className = m_Prefix + "_" + Guid.NewGuid().ToString("N"); CodeTypeDeclaration classCode = new CodeTypeDeclaration(className); classCode.TypeAttributes = System.Reflection.TypeAttributes.NestedPrivate | System.Reflection.TypeAttributes.Sealed; classCode.BaseTypes.Add(typeof(HardwiredMethodMemberDescriptor)); // Create the class constructor CodeConstructor ctor = new CodeConstructor(); ctor.Attributes = MemberAttributes.Assembly; classCode.Members.Add(ctor); // Create the parameters List <HardwireParameterDescriptor> paramDescs = HardwireParameterDescriptor.LoadDescriptorsFromTable(table.Get("params").Table); int paramNum = paramDescs.Count; int optionalNum = paramDescs.Where(p => p.HasDefaultValue).Count(); // Add initialize call to ctor List <CodeExpression> initParams = new List <CodeExpression>(); initParams.Add(new CodePrimitiveExpression(memberName)); initParams.Add(new CodePrimitiveExpression(table.Get("static").Boolean || table.Get("ctor").Boolean)); initParams.Add(new CodeArrayCreateExpression(typeof(ParameterDescriptor), paramDescs.Select(e => e.Expression).ToArray())); initParams.Add(new CodePrimitiveExpression(table.Get("extension").Boolean)); ctor.Statements.Add(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "Initialize", initParams.ToArray())); // Create the Invoke method : protected override object Invoke(Script script, object obj, object[] pars, int argscount); CodeMemberMethod m = new CodeMemberMethod(); m.Name = "Invoke"; m.Attributes = MemberAttributes.Override | MemberAttributes.Family; m.ReturnType = new CodeTypeReference(typeof(object)); m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Script), "script")); m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "obj")); m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object[]), "pars")); m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "argscount")); // get some meta about the method bool isVoid = table.Get("ret").String == "System.Void"; bool isCtor = table.Get("ctor").Boolean; bool isStatic = table.Get("static").Boolean; bool isExtension = table.Get("extension").Boolean; bool specialName = table.Get("special").Boolean; string declType = table.Get("decltype").String; var paramArray = new CodeVariableReferenceExpression("pars"); var paramThis = isStatic ? (CodeExpression)(new CodeTypeReferenceExpression(declType)) : (CodeExpression)(new CodeCastExpression(declType, new CodeVariableReferenceExpression("obj"))); // Build a list of arguments to the call int refparCount = 0; List <CodeExpression> paramExps = new List <CodeExpression>(); for (int i = 0; i < paramDescs.Count; i++) { var P = paramDescs[i]; CodeExpression paramExp = new CodeCastExpression(paramDescs[i].ParamType, new CodeArrayIndexerExpression(paramArray, new CodePrimitiveExpression(i))); if (P.IsOut) { string varName = GenerateRefParamVariable(refparCount++); var vd = new CodeVariableDeclarationStatement(P.ParamType, varName); m.Statements.Add(vd); paramExp = new CodeDirectionExpression(FieldDirection.Out, new CodeVariableReferenceExpression(varName)); } else if (P.IsRef) { string varName = GenerateRefParamVariable(refparCount++); var vd = new CodeVariableDeclarationStatement(P.ParamType, varName, paramExp); m.Statements.Add(vd); paramExp = new CodeDirectionExpression(FieldDirection.Ref, new CodeVariableReferenceExpression(varName)); } paramExps.Add(paramExp); } // build a list of possible dispatching to default params List <CodeExpression[]> calls = new List <CodeExpression[]>(); var paramArgsCount = new CodeVariableReferenceExpression("argscount"); for (int callidx = paramNum - optionalNum; callidx <= paramNum; callidx++) { List <CodeExpression> pars = new List <CodeExpression>(); // Build the array of parameters expressions for (int i = 0; i < callidx; i++) { pars.Add(paramExps[i]); } calls.Add(pars.ToArray()); } // foreach "overload" of default pars, dispatch a call for (int i = 0; i < calls.Count - 1; i++) { int argcnt = calls[i].Length; CodeExpression condition = new CodeBinaryOperatorExpression(paramArgsCount, CodeBinaryOperatorType.LessThanOrEqual, new CodePrimitiveExpression(argcnt)); var ifs = new CodeConditionStatement(condition, GenerateCall(table, generator, isVoid, isCtor, isStatic, isExtension, calls[i], paramThis, declType, specialName, refparCount).OfType <CodeStatement>().ToArray()); m.Statements.Add(ifs); } m.Statements.AddRange(GenerateCall(table, generator, isVoid, isCtor, isStatic, isExtension, calls[calls.Count - 1], paramThis, declType, specialName, refparCount)); // close classCode.Members.Add(m); members.Add(classCode); return(new CodeExpression[] { new CodeObjectCreateExpression(className) }); }
private void EmitInvalid(HardwireCodeGenerationContext generator, CodeStatementCollection coll, string message) { generator.Warning(message); coll.Add(new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(InvalidOperationException), new CodePrimitiveExpression(message)))); }
public CodeExpression[] Generate(Table table, HardwireCodeGenerationContext generator, CodeTypeMemberCollection members) { bool isStatic = table.Get("static").Boolean; string memberType = table.Get("type").String; string name = table.Get("name").String; string decltype = table.Get("decltype").String; bool declvtype = table.Get("declvtype").Boolean; bool canWrite = table.Get("write").Boolean; bool canRead = table.Get("read").Boolean; if (declvtype && canWrite) { generator.Warning("Member '{0}.{1}::Set' will be a no-op, as it's a member of a value type.", decltype, name); } MemberDescriptorAccess access = 0; if (canWrite) { access = access | MemberDescriptorAccess.CanWrite; } if (canRead) { access = access | MemberDescriptorAccess.CanRead; } string className = GetPrefix() + "_" + Guid.NewGuid().ToString("N"); CodeTypeDeclaration classCode = new CodeTypeDeclaration(className); classCode.TypeAttributes = System.Reflection.TypeAttributes.NestedPrivate | System.Reflection.TypeAttributes.Sealed; classCode.BaseTypes.Add(typeof(HardwiredMemberDescriptor)); // protected HardwiredMemberDescriptor(Type memberType, string name, bool isStatic, MemberDescriptorAccess access) CodeConstructor ctor = new CodeConstructor(); ctor.Attributes = MemberAttributes.Assembly; ctor.BaseConstructorArgs.Add(new CodeTypeOfExpression(memberType)); ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(name)); ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(isStatic)); ctor.BaseConstructorArgs.Add(new CodeCastExpression(typeof(MemberDescriptorAccess), new CodePrimitiveExpression((int)access))); classCode.Members.Add(ctor); var thisExp = isStatic ? (CodeExpression)(new CodeTypeReferenceExpression(decltype)) : (CodeExpression)(new CodeCastExpression(decltype, new CodeVariableReferenceExpression("obj"))); if (canRead) { var memberExp = GetMemberAccessExpression(thisExp, name); // protected virtual object GetValueImpl(Script script, object obj) CodeMemberMethod m = new CodeMemberMethod(); classCode.Members.Add(m); m.Name = "GetValueImpl"; m.Attributes = MemberAttributes.Override | MemberAttributes.Family; m.ReturnType = new CodeTypeReference(typeof(object)); m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Script), "script")); m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "obj")); m.Statements.Add(new CodeMethodReturnStatement(memberExp)); } if (canWrite) { // protected virtual object GetValueImpl(Script script, object obj) CodeMemberMethod m = new CodeMemberMethod(); classCode.Members.Add(m); m.Name = "SetValueImpl"; m.Attributes = MemberAttributes.Override | MemberAttributes.Family; m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Script), "script")); m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "obj")); m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "value")); var valExp = new CodeCastExpression(memberType, new CodeVariableReferenceExpression("value")); if (isStatic) { var e = GetMemberAccessExpression(thisExp, name); m.Statements.Add(new CodeAssignStatement(e, valExp)); } else { m.Statements.Add(new CodeVariableDeclarationStatement(decltype, "tmp", thisExp)); var memberExp = GetMemberAccessExpression(new CodeVariableReferenceExpression("tmp"), name); m.Statements.Add(new CodeAssignStatement(memberExp, valExp)); } } members.Add(classCode); return(new CodeExpression[] { new CodeObjectCreateExpression(className) }); }
private CodeStatementCollection GenerateCall(Table table, HardwireCodeGenerationContext generator, bool isVoid, bool isCtor, bool isStatic, bool isExtension, CodeExpression[] arguments, CodeExpression paramThis, string declaringType, bool specialName, int refparCount) { string arrayCtorType = table.Get("arraytype").IsNil() ? null : table.Get("arraytype").String; CodeStatementCollection coll = new CodeStatementCollection(); CodeExpression retVal = null; if (isCtor) { if (arrayCtorType != null) { var exp = generator.TargetLanguage.CreateMultidimensionalArray(arrayCtorType, arguments); retVal = new CodeArrayCreateExpression(arrayCtorType, arguments); } else { retVal = new CodeObjectCreateExpression(table.Get("ret").String, arguments); } } else if (specialName) { GenerateSpecialNameCall(table, generator, isVoid, isCtor, isStatic, isExtension, arguments, paramThis, declaringType, table.Get("name").String, coll); } else { retVal = new CodeMethodInvokeExpression(paramThis, table.Get("name").String, arguments); } if (retVal != null) { if (isVoid) { coll.Add(new CodeExpressionStatement(retVal)); retVal = new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(typeof(DynValue)), (refparCount == 0) ? "Void" : "Nil"); } if (refparCount == 0) { coll.Add(new CodeMethodReturnStatement(retVal)); } else { coll.Add(new CodeVariableDeclarationStatement(typeof(object), "retv", retVal)); List<CodeExpression> retVals = new List<CodeExpression>(); retVals.Add(WrapFromObject(new CodeVariableReferenceExpression("retv"))); for (int i = 0; i < refparCount; i++) retVals.Add(WrapFromObject(new CodeVariableReferenceExpression(GenerateRefParamVariable(i)))); var arrayExp = new CodeArrayCreateExpression(typeof(DynValue), retVals.ToArray()); var tupleExp = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(typeof(DynValue)), "NewTuple", arrayExp); coll.Add(new CodeMethodReturnStatement(tupleExp)); } } return coll; }
private void GenerateSpecialNameCall(Table table, HardwireCodeGenerationContext generator, bool isVoid, bool isCtor, bool isStatic, bool isExtension, CodeExpression[] arguments, CodeExpression paramThis, string declaringType, string specialName, CodeStatementCollection coll) { ReflectionSpecialName special = new ReflectionSpecialName(specialName); CodeExpression exp = null; CodeStatement stat = null; switch (special.Type) { case ReflectionSpecialNameType.IndexGetter: if (isStatic) EmitInvalid(generator, coll, "Static indexers are not supported by hardwired descriptors."); else exp = new CodeIndexerExpression(paramThis, arguments); break; case ReflectionSpecialNameType.IndexSetter: if (isStatic) EmitInvalid(generator, coll, "Static indexers are not supported by hardwired descriptors."); else { coll.Add(new CodeVariableDeclarationStatement(declaringType, "tmp", paramThis)); stat = new CodeAssignStatement(new CodeIndexerExpression(new CodeVariableReferenceExpression("tmp"), arguments.Take(arguments.Length - 1).ToArray()), arguments.Last()); } break; case ReflectionSpecialNameType.ImplicitCast: case ReflectionSpecialNameType.ExplicitCast: exp = paramThis; break; case ReflectionSpecialNameType.OperatorTrue: GenerateBooleanOperator(paramThis, coll, true); break; case ReflectionSpecialNameType.OperatorFalse: generator.Minor("'false' operator is implemented in terms of 'true' operator."); GenerateBooleanOperator(paramThis, coll, false); break; case ReflectionSpecialNameType.PropertyGetter: exp = new CodePropertyReferenceExpression(paramThis, special.Argument); break; case ReflectionSpecialNameType.PropertySetter: { if (isStatic) { var memberExp = new CodePropertyReferenceExpression(new CodeTypeReferenceExpression(declaringType), special.Argument); coll.Add(new CodeAssignStatement(memberExp, arguments[0])); } else { coll.Add(new CodeVariableDeclarationStatement(declaringType, "tmp", paramThis)); var memberExp = new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("tmp"), special.Argument); coll.Add(new CodeAssignStatement(memberExp, arguments[0])); } coll.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null))); } break; case ReflectionSpecialNameType.OperatorAdd: exp = BinaryOperator(CodeBinaryOperatorType.Add, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorAnd: exp = BinaryOperator(CodeBinaryOperatorType.BitwiseAnd, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorOr: exp = BinaryOperator(CodeBinaryOperatorType.BitwiseOr, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorDec: exp = generator.TargetLanguage.UnaryDecrement(arguments[0]); if (exp == null) EmitInvalid(generator, coll, string.Format("Language {0} does not support decrement operators.", generator.TargetLanguage.Name)); break; case ReflectionSpecialNameType.OperatorDiv: exp = BinaryOperator(CodeBinaryOperatorType.Divide, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorEq: exp = BinaryOperator(CodeBinaryOperatorType.ValueEquality, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorXor: exp = generator.TargetLanguage.BinaryXor(arguments[0], arguments[1]); if (exp == null) EmitInvalid(generator, coll, string.Format("Language {0} does not support XOR operators.", generator.TargetLanguage.Name)); break; case ReflectionSpecialNameType.OperatorGt: exp = BinaryOperator(CodeBinaryOperatorType.GreaterThan, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorGte: exp = BinaryOperator(CodeBinaryOperatorType.GreaterThanOrEqual, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorInc: exp = generator.TargetLanguage.UnaryIncrement(arguments[0]); if (exp == null) EmitInvalid(generator, coll, string.Format("Language {0} does not support increment operators.", generator.TargetLanguage.Name)); break; case ReflectionSpecialNameType.OperatorNeq: exp = BinaryOperator(CodeBinaryOperatorType.IdentityInequality, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorLt: exp = BinaryOperator(CodeBinaryOperatorType.LessThan, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorLte: exp = BinaryOperator(CodeBinaryOperatorType.LessThanOrEqual, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorNot: exp = generator.TargetLanguage.UnaryLogicalNot(arguments[0]); if (exp == null) EmitInvalid(generator, coll, string.Format("Language {0} does not support logical NOT operators.", generator.TargetLanguage.Name)); break; case ReflectionSpecialNameType.OperatorMod: exp = BinaryOperator(CodeBinaryOperatorType.Modulus, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorMul: exp = BinaryOperator(CodeBinaryOperatorType.Multiply, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorCompl: exp = generator.TargetLanguage.UnaryOneComplement(arguments[0]); if (exp == null) EmitInvalid(generator, coll, string.Format("Language {0} does not support bitwise NOT operators.", generator.TargetLanguage.Name)); break; case ReflectionSpecialNameType.OperatorSub: exp = BinaryOperator(CodeBinaryOperatorType.Subtract, paramThis, arguments); break; case ReflectionSpecialNameType.OperatorNeg: exp = generator.TargetLanguage.UnaryNegation(arguments[0]); if (exp == null) EmitInvalid(generator, coll, string.Format("Language {0} does not support negation operators.", generator.TargetLanguage.Name)); break; case ReflectionSpecialNameType.OperatorUnaryPlus: exp = generator.TargetLanguage.UnaryPlus(arguments[0]); if (exp == null) EmitInvalid(generator, coll, string.Format("Language {0} does not support unary + operators.", generator.TargetLanguage.Name)); break; case ReflectionSpecialNameType.AddEvent: case ReflectionSpecialNameType.RemoveEvent: coll.Add(new CodeThrowExceptionStatement(new CodeObjectCreateExpression(typeof(InvalidOperationException), new CodePrimitiveExpression("Access to event special methods is not supported by hardwired decriptors.")))); break; default: break; } if (stat != null) { coll.Add(stat); exp = exp ?? new CodePrimitiveExpression(null); } if (exp != null) coll.Add(new CodeMethodReturnStatement(exp)); }
public CodeExpression[] Generate(Table table, HardwireCodeGenerationContext generator, CodeTypeMemberCollection members) { bool isArray = table.Get("arraytype").IsNotNil(); string memberName = table.Get("name").String; // Ignore arrays weird special members if (isArray) { if ((memberName == "Get") || (memberName == "Set") || (memberName == "Address")) return null; } // Create the descriptor class string className = m_Prefix + "_" + Guid.NewGuid().ToString("N"); CodeTypeDeclaration classCode = new CodeTypeDeclaration(className); classCode.TypeAttributes = System.Reflection.TypeAttributes.NestedPrivate | System.Reflection.TypeAttributes.Sealed; classCode.BaseTypes.Add(typeof(HardwiredMethodMemberDescriptor)); // Create the class constructor CodeConstructor ctor = new CodeConstructor(); ctor.Attributes = MemberAttributes.Assembly; classCode.Members.Add(ctor); // Create the parameters List<HardwireParameterDescriptor> paramDescs = HardwireParameterDescriptor.LoadDescriptorsFromTable(table.Get("params").Table); int paramNum = paramDescs.Count; int optionalNum = paramDescs.Where(p => p.HasDefaultValue).Count(); // Add initialize call to ctor List<CodeExpression> initParams = new List<CodeExpression>(); initParams.Add(new CodePrimitiveExpression(memberName)); initParams.Add(new CodePrimitiveExpression(table.Get("static").Boolean || table.Get("ctor").Boolean)); initParams.Add(new CodeArrayCreateExpression(typeof(ParameterDescriptor), paramDescs.Select(e => e.Expression).ToArray())); initParams.Add(new CodePrimitiveExpression(table.Get("extension").Boolean)); ctor.Statements.Add(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "Initialize", initParams.ToArray())); // Create the Invoke method : protected override object Invoke(Script script, object obj, object[] pars, int argscount); CodeMemberMethod m = new CodeMemberMethod(); m.Name = "Invoke"; m.Attributes = MemberAttributes.Override | MemberAttributes.Family; m.ReturnType = new CodeTypeReference(typeof(object)); m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Script), "script")); m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "obj")); m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object[]), "pars")); m.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "argscount")); // get some meta about the method bool isVoid = table.Get("ret").String == "System.Void"; bool isCtor = table.Get("ctor").Boolean; bool isStatic = table.Get("static").Boolean; bool isExtension = table.Get("extension").Boolean; bool specialName = table.Get("special").Boolean; string declType = table.Get("decltype").String; var paramArray = new CodeVariableReferenceExpression("pars"); var paramThis = isStatic ? (CodeExpression)(new CodeTypeReferenceExpression(declType)) : (CodeExpression)(new CodeCastExpression(declType, new CodeVariableReferenceExpression("obj"))); // Build a list of arguments to the call int refparCount = 0; List<CodeExpression> paramExps = new List<CodeExpression>(); for (int i = 0; i < paramDescs.Count; i++) { var P = paramDescs[i]; CodeExpression paramExp = new CodeCastExpression(paramDescs[i].ParamType, new CodeArrayIndexerExpression(paramArray, new CodePrimitiveExpression(i))); if (P.IsOut) { string varName = GenerateRefParamVariable(refparCount++); var vd = new CodeVariableDeclarationStatement(P.ParamType, varName); m.Statements.Add(vd); paramExp = new CodeDirectionExpression(FieldDirection.Out, new CodeVariableReferenceExpression(varName)); } else if (P.IsRef) { string varName = GenerateRefParamVariable(refparCount++); var vd = new CodeVariableDeclarationStatement(P.ParamType, varName, paramExp); m.Statements.Add(vd); paramExp = new CodeDirectionExpression(FieldDirection.Ref, new CodeVariableReferenceExpression(varName)); } paramExps.Add(paramExp); } // build a list of possible dispatching to default params List<CodeExpression[]> calls = new List<CodeExpression[]>(); var paramArgsCount = new CodeVariableReferenceExpression("argscount"); for(int callidx = paramNum - optionalNum; callidx <= paramNum; callidx++) { List<CodeExpression> pars = new List<CodeExpression>(); // Build the array of parameters expressions for(int i = 0; i < callidx; i++) { pars.Add(paramExps[i]); } calls.Add(pars.ToArray()); } // foreach "overload" of default pars, dispatch a call for (int i = 0; i < calls.Count - 1; i++) { int argcnt = calls[i].Length; CodeExpression condition = new CodeBinaryOperatorExpression(paramArgsCount, CodeBinaryOperatorType.LessThanOrEqual, new CodePrimitiveExpression(argcnt)); var ifs = new CodeConditionStatement(condition, GenerateCall(table, generator, isVoid, isCtor, isStatic, isExtension, calls[i], paramThis, declType, specialName, refparCount).OfType<CodeStatement>().ToArray()); m.Statements.Add(ifs); } m.Statements.AddRange(GenerateCall(table, generator, isVoid, isCtor, isStatic, isExtension, calls[calls.Count - 1], paramThis, declType, specialName, refparCount)); // close classCode.Members.Add(m); members.Add(classCode); return new CodeExpression[] { new CodeObjectCreateExpression(className) }; }
public CodeExpression[] Generate(Table table, HardwireCodeGenerationContext generator, CodeTypeMemberCollection members) { generator.Error("Missing code generator for '{0}'.", ManagedType); return new CodeExpression[0]; }
public CodeExpression[] Generate(Table table, HardwireCodeGenerationContext generator, CodeTypeMemberCollection members) { generator.Error("Missing code generator for '{0}'.", ManagedType); return(new CodeExpression[0]); }