public static void UnpackArray(BooCodeBuilder codeBuilder, Method method, Block block, Expression expression, DeclarationCollection declarations) { ILocalEntity local = expression.Entity as ILocalEntity; if (null == local) { local = codeBuilder.DeclareTempLocal(method, expression.ExpressionType); block.Add( codeBuilder.CreateAssignment( codeBuilder.CreateReference(local), expression)); } for (int i = 0; i < declarations.Count; ++i) { Declaration declaration = declarations[i]; block.Add( codeBuilder.CreateAssignment( codeBuilder.CreateReference( declaration.Entity), codeBuilder.CreateSlicing( codeBuilder.CreateReference(local), i))); } }
public void DeclareFieldsAndConstructor(BooClassBuilder builder) { var keys = _referencedEntities.Keys.Cast <ITypedEntity>().ToArray(); foreach (var entity in keys) { _collector.Visit(entity.Type); } if (_collector.Matches.Any()) { BuildTypeMap(builder.ClassDefinition); } // referenced entities turn into fields foreach (var entity in keys) { Field field = builder.AddInternalField(GetUniqueName(entity.Name), _mapper.MapType(entity.Type)); _referencedEntities[entity] = (InternalField)field.Entity; } // single constructor taking all referenced entities BooMethodBuilder constructor = builder.AddConstructor(); constructor.Modifiers = TypeMemberModifiers.Public; constructor.Body.Add(CodeBuilder.CreateSuperConstructorInvocation(builder.Entity.BaseType)); foreach (var entity in _referencedEntities.Keys) { InternalField field = _referencedEntities[entity]; ParameterDeclaration parameter = constructor.AddParameter(field.Name, ((ITypedEntity)entity).Type); constructor.Body.Add( CodeBuilder.CreateAssignment(CodeBuilder.CreateReference(field), CodeBuilder.CreateReference(parameter))); } }
public static void UnpackEnumerable(BooCodeBuilder codeBuilder, Method method, Block block, Expression expression, DeclarationCollection declarations) { TypeSystemServices tss = codeBuilder.TypeSystemServices; InternalLocal local = codeBuilder.DeclareTempLocal(method, tss.IEnumeratorType); IType expressionType = expression.ExpressionType; if (expressionType.IsSubclassOf(codeBuilder.TypeSystemServices.IEnumeratorType)) { block.Add( codeBuilder.CreateAssignment( codeBuilder.CreateReference(local), expression)); } else { if (!expressionType.IsSubclassOf(codeBuilder.TypeSystemServices.IEnumerableType)) { expression = codeBuilder.CreateMethodInvocation( RuntimeServices_GetEnumerable, expression); } block.Add( codeBuilder.CreateAssignment( block.LexicalInfo, codeBuilder.CreateReference(local), codeBuilder.CreateMethodInvocation( expression, IEnumerable_GetEnumerator))); } for (int i = 0; i < declarations.Count; ++i) { Declaration declaration = declarations[i]; block.Add( codeBuilder.CreateAssignment( codeBuilder.CreateReference(declaration.Entity), codeBuilder.CreateMethodInvocation(RuntimeServices_MoveNext, codeBuilder.CreateReference(local)))); } }
Method CreateFieldAccessor(IField member) { BooCodeBuilder builder = _context.CodeBuilder; Method method = builder.CreateMethod("___" + member.Name, member.Type, TypeMemberModifiers.None); method.Body.Add( new ReturnStatement( builder.CreateReference(member))); return(method); }
Method CreateFieldSetter(IField member) { BooCodeBuilder builder = _context.CodeBuilder; Method method = builder.CreateMethod("___" + member.Name, _context.TypeSystemServices.VoidType, TypeMemberModifiers.None); ParameterDeclaration value = builder.CreateParameterDeclaration(1, "value", member.Type); method.Parameters.Add(value); method.Body.Add( builder.CreateFieldAssignment( LexicalInfo.Empty, member, builder.CreateReference(value))); return(method); }
Method CreateMethodAccessor(IMethod member) { BooCodeBuilder builder = _context.CodeBuilder; Method method = builder.CreateMethodFromPrototype(LexicalInfo.Empty, member, TypeMemberModifiers.None); method.Name = "___" + member.Name; MethodInvocationExpression mie = builder.CreateMethodInvocation(member); foreach (ParameterDeclaration p in method.Parameters) { mie.Arguments.Add(builder.CreateReference(p)); } if (member.ReturnType == _context.TypeSystemServices.VoidType) { method.Body.Add(mie); } else { method.Body.Add(new ReturnStatement(mie)); } return(method); }