public void visitArrayExpression()

in src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java [1666:1795]


    public void visitArrayExpression(final ArrayExpression expression) {
        MethodVisitor mv = controller.getMethodVisitor();
        CompileStack  compileStack = controller.getCompileStack();
        OperandStack  operandStack = controller.getOperandStack();

        ClassNode arrayType = expression.getType();
        ClassNode elementType = arrayType.getComponentType();

        int size = 0, dimensions = 0;
        if (expression.hasInitializer()) {
            if (containsSpreadExpression(expression)) {
                despreadList(expression.getExpressions(), false);
                if (elementType.equals(ClassHelper.OBJECT_TYPE)){
                    operandStack.push(arrayType);
                    return;
                }
                mv.visitInsn(DUP); // Object[] from despreadList
                mv.visitInsn(ARRAYLENGTH);
                mv.visitInsn(DUP); // store value count
                operandStack.push(ClassHelper.int_TYPE);
                size = -compileStack.defineTemporaryVariable("value$count", ClassHelper.int_TYPE, true);
            } else {
                size = expression.getExpressions().size();
                BytecodeHelper.pushConstant(mv, size);
            }
            // stack: ..., size
        } else {
            for (final Expression sizeExpr : expression.getSizeExpression()) {
                if (sizeExpr == ConstantExpression.EMPTY_EXPRESSION) break;
                dimensions += 1;
                sizeExpr.visit(this);
                operandStack.doGroovyCast(ClassHelper.int_TYPE);
            }
            operandStack.remove(dimensions);
            // stack: ..., size (one per dimension)
        }

        int storeIns = AASTORE;
        if (!elementType.isArray() || expression.hasInitializer()) {
            if (isPrimitiveType(elementType)) {
                int primType = 0;
                if (isPrimitiveBoolean(elementType)) {
                    primType = T_BOOLEAN;
                    storeIns = BASTORE;
                } else if (isPrimitiveChar(elementType)) {
                    primType = T_CHAR;
                    storeIns = CASTORE;
                } else if (isPrimitiveFloat(elementType)) {
                    primType = T_FLOAT;
                    storeIns = FASTORE;
                } else if (isPrimitiveDouble(elementType)) {
                    primType = T_DOUBLE;
                    storeIns = DASTORE;
                } else if (isPrimitiveByte(elementType)) {
                    primType = T_BYTE;
                    storeIns = BASTORE;
                } else if (isPrimitiveShort(elementType)) {
                    primType = T_SHORT;
                    storeIns = SASTORE;
                } else if (isPrimitiveInt(elementType)) {
                    primType = T_INT;
                    storeIns = IASTORE;
                } else if (isPrimitiveLong(elementType)) {
                    primType = T_LONG;
                    storeIns = LASTORE;
                }
                mv.visitIntInsn(NEWARRAY, primType);
            } else {
                mv.visitTypeInsn(ANEWARRAY, BytecodeHelper.getClassInternalName(elementType));
                maybeInnerClassEntry(elementType);
            }
        } else {
            mv.visitMultiANewArrayInsn(BytecodeHelper.getTypeDescription(arrayType), dimensions);
        }
        // stack: ..., array

        if (size >= 0) {
            for (int i = 0; i < size; i += 1) {
                mv.visitInsn(DUP); // array ref
                BytecodeHelper.pushConstant(mv, i);
                Optional.ofNullable(expression.getExpression(i))
                        .orElse(ConstantExpression.NULL)
                        .visit(this);
                operandStack.doGroovyCast(elementType);
                mv.visitInsn(storeIns);
                operandStack.remove(1);
            }
        } else {
            // stack: ..., source, target
            Label top = new Label();
            mv.visitLabel(top);

            {
                final int idx = -size;
                mv.visitIincInsn(idx, -1);

                mv.visitInsn(DUP2);
                mv.visitInsn(SWAP);
                // stack: ..., target, source
                mv.visitVarInsn(ILOAD, idx);
                // stack: ..., target, source, index
                mv.visitInsn(AALOAD);
                // stack: ..., target, value
                operandStack.push(ClassHelper.OBJECT_TYPE);
                operandStack.doGroovyCast(elementType);

                mv.visitVarInsn(ILOAD, idx);
                // stack: ..., target, value, index
                operandStack.push(ClassHelper.int_TYPE);
                operandStack.swap();
                // stack: ..., target, index, value
                mv.visitInsn(storeIns);
                operandStack.remove(2);
                // stack: ...

                mv.visitVarInsn(ILOAD, idx);
                mv.visitJumpInsn(IFNE, top);

                compileStack.removeVar(idx);
            }

            // stack: ..., source, target
            mv.visitInsn(SWAP);
            // stack: ..., target, source
            mv.visitInsn(POP);
            // stack: ..., target
        }

        operandStack.push(arrayType);
    }