Search in sources :

Example 1 with Unit

use of kotlin.Unit in project kotlin by JetBrains.

the class FunctionCodegen method generateDelegateForDefaultImpl.

private void generateDelegateForDefaultImpl(@NotNull final FunctionDescriptor functionDescriptor, @Nullable PsiElement element) {
    Method defaultImplMethod = typeMapper.mapAsmMethod(functionDescriptor, OwnerKind.DEFAULT_IMPLS);
    CodegenUtilKt.generateMethod(v, "Default Impl delegate in interface", Opcodes.ACC_SYNTHETIC | Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, new Method(defaultImplMethod.getName() + JvmAbi.DEFAULT_IMPLS_DELEGATE_SUFFIX, defaultImplMethod.getDescriptor()), element, JvmDeclarationOrigin.NO_ORIGIN, state, new Function1<InstructionAdapter, Unit>() {

        @Override
        public Unit invoke(InstructionAdapter adapter) {
            Method interfaceMethod = typeMapper.mapAsmMethod(functionDescriptor, OwnerKind.IMPLEMENTATION);
            Type type = typeMapper.mapOwner(functionDescriptor);
            generateDelegateToMethodBody(-1, adapter, interfaceMethod, type.getInternalName(), Opcodes.INVOKESPECIAL, true);
            return null;
        }
    });
}
Also used : KotlinType(org.jetbrains.kotlin.types.KotlinType) InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter) Method(org.jetbrains.org.objectweb.asm.commons.Method) Unit(kotlin.Unit)

Example 2 with Unit

use of kotlin.Unit in project kotlin by JetBrains.

the class ExpressionCodegen method visitPostfixExpression.

@Override
public StackValue visitPostfixExpression(@NotNull final KtPostfixExpression expression, StackValue receiver) {
    if (expression.getOperationReference().getReferencedNameElementType() == KtTokens.EXCLEXCL) {
        final StackValue base = genQualified(receiver, expression.getBaseExpression());
        if (isPrimitive(base.type)) {
            return base;
        } else {
            return StackValue.operation(base.type, new Function1<InstructionAdapter, Unit>() {

                @Override
                public Unit invoke(InstructionAdapter v) {
                    base.put(base.type, v);
                    v.dup();
                    Label ok = new Label();
                    v.ifnonnull(ok);
                    v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "throwNpe", "()V", false);
                    v.mark(ok);
                    return null;
                }
            });
        }
    }
    DeclarationDescriptor originalOperation = bindingContext.get(REFERENCE_TARGET, expression.getOperationReference());
    String originalOperationName = originalOperation != null ? originalOperation.getName().asString() : null;
    final ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCallWithAssert(expression, bindingContext);
    DeclarationDescriptor op = resolvedCall.getResultingDescriptor();
    if (!(op instanceof FunctionDescriptor) || originalOperation == null) {
        throw new UnsupportedOperationException("Don't know how to generate this postfix expression: " + originalOperationName + " " + op);
    }
    final Type asmResultType = expressionType(expression);
    final Type asmBaseType = expressionType(expression.getBaseExpression());
    DeclarationDescriptor cls = op.getContainingDeclaration();
    final int increment;
    if (originalOperationName.equals("inc")) {
        increment = 1;
    } else if (originalOperationName.equals("dec")) {
        increment = -1;
    } else {
        throw new UnsupportedOperationException("Unsupported postfix operation: " + originalOperationName + " " + op);
    }
    final boolean isPrimitiveNumberClassDescriptor = isPrimitiveNumberClassDescriptor(cls);
    if (isPrimitiveNumberClassDescriptor && AsmUtil.isPrimitive(asmBaseType)) {
        KtExpression operand = expression.getBaseExpression();
        // Optimization for j = i++, when j and i are Int without any smart cast: we just work with primitive int
        if (operand instanceof KtReferenceExpression && asmResultType == Type.INT_TYPE && bindingContext.get(BindingContext.SMARTCAST, operand) == null) {
            int index = indexOfLocalNotDelegated((KtReferenceExpression) operand);
            if (index >= 0) {
                return StackValue.postIncrement(index, increment);
            }
        }
    }
    return StackValue.operation(asmBaseType, new Function1<InstructionAdapter, Unit>() {

        @Override
        public Unit invoke(InstructionAdapter v) {
            StackValue value = StackValue.complexWriteReadReceiver(gen(expression.getBaseExpression()));
            value.put(asmBaseType, v);
            AsmUtil.dup(v, asmBaseType);
            StackValue previousValue = StackValue.local(myFrameMap.enterTemp(asmBaseType), asmBaseType);
            previousValue.store(StackValue.onStack(asmBaseType), v);
            Type storeType;
            if (isPrimitiveNumberClassDescriptor && AsmUtil.isPrimitive(asmBaseType)) {
                genIncrement(asmBaseType, increment, v);
                storeType = asmBaseType;
            } else {
                StackValue result = invokeFunction(resolvedCall, StackValue.onStack(asmBaseType));
                result.put(result.type, v);
                storeType = result.type;
            }
            value.store(StackValue.onStack(storeType), v, true);
            previousValue.put(asmBaseType, v);
            myFrameMap.leaveTemp(asmBaseType);
            return Unit.INSTANCE;
        }
    });
}
Also used : Label(org.jetbrains.org.objectweb.asm.Label) Unit(kotlin.Unit) IElementType(com.intellij.psi.tree.IElementType) Type(org.jetbrains.org.objectweb.asm.Type) KotlinType(org.jetbrains.kotlin.types.KotlinType) InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)

Example 3 with Unit

use of kotlin.Unit in project kotlin by JetBrains.

the class ExpressionCodegen method generateIfExpression.

/* package */
StackValue generateIfExpression(@NotNull final KtIfExpression expression, final boolean isStatement) {
    final Type asmType = isStatement ? Type.VOID_TYPE : expressionTypeForBranchingOperation(expression);
    final StackValue condition = gen(expression.getCondition());
    final KtExpression thenExpression = expression.getThen();
    final KtExpression elseExpression = expression.getElse();
    if (isEmptyExpression(thenExpression)) {
        if (isEmptyExpression(elseExpression)) {
            return StackValue.coercion(condition, asmType);
        }
        return generateSingleBranchIf(condition, expression, elseExpression, false, isStatement);
    } else {
        if (isEmptyExpression(elseExpression)) {
            return generateSingleBranchIf(condition, expression, thenExpression, true, isStatement);
        }
    }
    return StackValue.operation(asmType, new Function1<InstructionAdapter, Unit>() {

        @Override
        public Unit invoke(InstructionAdapter v) {
            Label elseLabel = new Label();
            BranchedValue.Companion.condJump(condition, elseLabel, true, v);
            Label end = new Label();
            gen(thenExpression, asmType);
            v.goTo(end);
            v.mark(elseLabel);
            gen(elseExpression, asmType);
            markLineNumber(expression, isStatement);
            v.mark(end);
            return Unit.INSTANCE;
        }
    });
}
Also used : IElementType(com.intellij.psi.tree.IElementType) Type(org.jetbrains.org.objectweb.asm.Type) KotlinType(org.jetbrains.kotlin.types.KotlinType) InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter) Label(org.jetbrains.org.objectweb.asm.Label) Unit(kotlin.Unit)

Example 4 with Unit

use of kotlin.Unit in project kotlin by JetBrains.

the class ExpressionCodegen method generateBlock.

private StackValueWithLeaveTask generateBlock(@NotNull List<KtExpression> statements, boolean isStatement, @Nullable Label labelBeforeLastExpression, @Nullable final Label labelBlockEnd) {
    final Label blockEnd = labelBlockEnd != null ? labelBlockEnd : new Label();
    final List<Function<StackValue, Void>> leaveTasks = Lists.newArrayList();
    @Nullable StackValue blockResult = null;
    for (Iterator<KtExpression> iterator = statements.iterator(); iterator.hasNext(); ) {
        KtExpression possiblyLabeledStatement = iterator.next();
        KtElement statement = KtPsiUtil.safeDeparenthesize(possiblyLabeledStatement);
        if (statement instanceof KtNamedDeclaration) {
            KtNamedDeclaration declaration = (KtNamedDeclaration) statement;
            if (KtPsiUtil.isScriptDeclaration(declaration)) {
                continue;
            }
        }
        putDescriptorIntoFrameMap(statement);
        boolean isExpression = !iterator.hasNext() && !isStatement;
        if (isExpression && labelBeforeLastExpression != null) {
            v.mark(labelBeforeLastExpression);
        }
        // Note that this statementResult value is potentially unused (in case of handleResult coroutine call)
        // It's supposed here that no bytecode is emitted until 'put' call on relevant StackValue object
        StackValue statementResult = isExpression ? gen(possiblyLabeledStatement) : genStatement(possiblyLabeledStatement);
        if (!iterator.hasNext()) {
            blockResult = statementResult;
        } else {
            statementResult.put(Type.VOID_TYPE, v);
        }
        addLeaveTaskToRemoveDescriptorFromFrameMap(statement, blockEnd, leaveTasks);
    }
    if (statements.isEmpty()) {
        blockResult = StackValue.none();
    }
    assert blockResult != null : "Block result should be initialized in the loop or the condition above";
    return new StackValueWithLeaveTask(blockResult, new Function1<StackValue, Unit>() {

        @Override
        public Unit invoke(StackValue value) {
            if (labelBlockEnd == null) {
                v.mark(blockEnd);
            }
            for (Function<StackValue, Void> task : Lists.reverse(leaveTasks)) {
                task.fun(value);
            }
            return Unit.INSTANCE;
        }
    });
}
Also used : Label(org.jetbrains.org.objectweb.asm.Label) Unit(kotlin.Unit) Function(com.intellij.util.Function) Nullable(org.jetbrains.annotations.Nullable)

Example 5 with Unit

use of kotlin.Unit in project kotlin by JetBrains.

the class PackagePartCodegen method generateKotlinMetadataAnnotation.

@Override
protected void generateKotlinMetadataAnnotation() {
    List<DeclarationDescriptor> members = new ArrayList<DeclarationDescriptor>();
    for (KtDeclaration declaration : element.getDeclarations()) {
        if (declaration instanceof KtNamedFunction) {
            SimpleFunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, declaration);
            members.add(functionDescriptor);
        } else if (declaration instanceof KtProperty) {
            VariableDescriptor property = bindingContext.get(BindingContext.VARIABLE, declaration);
            members.add(property);
        } else if (declaration instanceof KtTypeAlias) {
            TypeAliasDescriptor typeAlias = bindingContext.get(BindingContext.TYPE_ALIAS, declaration);
            members.add(typeAlias);
        }
    }
    final DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(new JvmSerializerExtension(v.getSerializationBindings(), state));
    final ProtoBuf.Package packageProto = serializer.packagePartProto(element.getPackageFqName(), members).build();
    WriteAnnotationUtilKt.writeKotlinMetadata(v, state, KotlinClassHeader.Kind.FILE_FACADE, 0, new Function1<AnnotationVisitor, Unit>() {

        @Override
        public Unit invoke(AnnotationVisitor av) {
            writeAnnotationData(av, serializer, packageProto);
            return Unit.INSTANCE;
        }
    });
}
Also used : JvmSerializerExtension(org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension) TypeAliasDescriptor(org.jetbrains.kotlin.descriptors.TypeAliasDescriptor) ArrayList(java.util.ArrayList) VariableDescriptor(org.jetbrains.kotlin.descriptors.VariableDescriptor) Unit(kotlin.Unit) ProtoBuf(org.jetbrains.kotlin.serialization.ProtoBuf) DescriptorSerializer(org.jetbrains.kotlin.serialization.DescriptorSerializer) DeclarationDescriptor(org.jetbrains.kotlin.descriptors.DeclarationDescriptor) AnnotationVisitor(org.jetbrains.org.objectweb.asm.AnnotationVisitor) SimpleFunctionDescriptor(org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor)

Aggregations

Unit (kotlin.Unit)18 KotlinType (org.jetbrains.kotlin.types.KotlinType)10 InstructionAdapter (org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)10 IElementType (com.intellij.psi.tree.IElementType)9 Type (org.jetbrains.org.objectweb.asm.Type)8 Label (org.jetbrains.org.objectweb.asm.Label)6 JvmSerializerExtension (org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension)3 KtFile (org.jetbrains.kotlin.psi.KtFile)3 DescriptorSerializer (org.jetbrains.kotlin.serialization.DescriptorSerializer)3 ProtoBuf (org.jetbrains.kotlin.serialization.ProtoBuf)3 Method (org.jetbrains.org.objectweb.asm.commons.Method)3 File (java.io.File)2 NotNull (org.jetbrains.annotations.NotNull)2 Nullable (org.jetbrains.annotations.Nullable)2 AnnotationVisitor (org.jetbrains.org.objectweb.asm.AnnotationVisitor)2 VirtualFile (com.intellij.openapi.vfs.VirtualFile)1 VirtualFileSystem (com.intellij.openapi.vfs.VirtualFileSystem)1 PsiFile (com.intellij.psi.PsiFile)1 Function (com.intellij.util.Function)1 ArrayList (java.util.ArrayList)1