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)))); } }
private Expression VisitExpression(ref BoundSpillSequenceBuilder builder, Expression expression) { // wrap the node in a spill sequence to mark the fact that it must be moved up the tree. // The caller will handle this node type if the result is discarded. if (expression != null && expression.NodeType == NodeType.AwaitExpression) { // we force the await expression to be assigned to a temp variable var awaitExpression = (AwaitExpression)expression; awaitExpression.BaseExpression = VisitExpression(ref builder, awaitExpression.BaseExpression); var local = _F.DeclareTempLocal(_currentMethod, awaitExpression.ExpressionType); var replacement = _F.CreateAssignment( awaitExpression.LexicalInfo, _F.CreateLocalReference(local), awaitExpression); if (builder == null) { builder = new BoundSpillSequenceBuilder(); } builder.AddLocal(local); builder.AddStatement(new ExpressionStatement(replacement)); return(_F.CreateLocalReference(local)); } var e = Visit(expression); if (e == null || e.NodeType != SpillSequenceBuilder) { return(e); } var newBuilder = (BoundSpillSequenceBuilder)e; if (builder == null) { builder = newBuilder.Update(null); } else { builder.Include(newBuilder); } return(newBuilder.Value); }