예제 #1
0
        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)));
            }
        }
예제 #2
0
        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)));
            }
        }
예제 #3
0
        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))));
            }
        }
예제 #4
0
        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);
        }