All Downloads are FREE. Search and download functionalities are using the official Maven repository.

.kotlin.kotlin-compiler.1.3.11.source-code.InitializerVisitor Maven / Gradle / Ivy

There is a newer version: 2.1.0-Beta1
Show newest version
/*
 * Copyright 2010-2017 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jetbrains.kotlin.js.translate.initializer;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
import org.jetbrains.kotlin.js.backend.ast.*;
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.declaration.PropertyTranslatorKt;
import org.jetbrains.kotlin.js.translate.general.TranslatorVisitor;
import org.jetbrains.kotlin.js.translate.utils.BindingUtils;
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils;
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.types.KotlinType;

import static org.jetbrains.kotlin.js.translate.general.Translation.translateAsStatementAndMergeInBlockIfNeeded;
import static org.jetbrains.kotlin.js.translate.initializer.InitializerUtils.generateInitializerForDelegate;
import static org.jetbrains.kotlin.js.translate.initializer.InitializerUtils.generateInitializerForProperty;

public final class InitializerVisitor extends TranslatorVisitor {
    @Override
    protected Void emptyResult(@NotNull TranslationContext context) {
        return null;
    }

    @Override
    public final Void visitProperty(@NotNull KtProperty property, @NotNull TranslationContext context) {
        PropertyDescriptor descriptor = BindingUtils.getPropertyDescriptor(context.bindingContext(), property);
        JsExpression value = PropertyTranslatorKt.translateDelegateOrInitializerExpression(context, property);
        JsStatement statement = null;

        KtExpression initializer = property.getInitializer();
        KtExpression delegate = property.getDelegateExpression();
        if (initializer != null) {
            assert value != null;
            KotlinType type = TranslationUtils.isReferenceToSyntheticBackingField(descriptor) ?
                              descriptor.getType() :
                              TranslationUtils.getReturnTypeForCoercion(descriptor);
            value = TranslationUtils.coerce(context, value, type);
            statement = generateInitializerForProperty(context, descriptor, value);
        }
        else if (delegate != null) {
            assert value != null;
            statement = generateInitializerForDelegate(context, descriptor, value);
        }
        else if (Boolean.TRUE.equals(context.bindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, descriptor))) {
            JsNameRef backingFieldReference = TranslationUtils.backingFieldReference(context, descriptor);
            JsExpression defaultValue = generateDefaultValue(descriptor, backingFieldReference);
            statement = TranslationUtils.assignmentToBackingField(context, descriptor, defaultValue).source(property).makeStmt();
        }
        else if (JsDescriptorUtils.isSimpleFinalProperty(descriptor)) {
            JsNameRef propRef = new JsNameRef(context.getNameForDescriptor(descriptor), new JsThisRef());
            JsExpression defaultValue = generateDefaultValue(descriptor, propRef);
            statement = JsAstUtils.assignment(propRef, defaultValue).source(property).makeStmt();
        }

        if (statement != null && !JsAstUtils.isEmptyStatement(statement)) {
            context.addStatementsToCurrentBlock(JsAstUtils.flattenStatement(statement));
        }

        return null;
    }

    @NotNull
    private static JsExpression generateDefaultValue(
            @NotNull PropertyDescriptor property,
            @NotNull JsExpression lateInitDefault
    ) {
        if (property.isLateInit()) return lateInitDefault.deepCopy();

        KotlinType type = property.getType();
        if (KotlinBuiltIns.isInt(type) || KotlinBuiltIns.isFloat(type) || KotlinBuiltIns.isDouble(type) ||
            KotlinBuiltIns.isByte(type) || KotlinBuiltIns.isShort(type)
        ) {
            return new JsIntLiteral(0);
        }
        else if (KotlinBuiltIns.isBoolean(type)) {
            return new JsBooleanLiteral(false);
        }
        else {
            return new JsNullLiteral();
        }
    }

    @Override
    public Void visitAnonymousInitializer(@NotNull KtAnonymousInitializer initializer, @NotNull TranslationContext context) {
        KtExpression initializerBody = initializer.getBody();
        if (initializerBody != null) {
            context.addStatementsToCurrentBlock(JsAstUtils.flattenStatement(
                    translateAsStatementAndMergeInBlockIfNeeded(initializerBody, context)));
        }
        return null;
    }

    @Override
    // Not interested in other types of declarations, they do not contain initializers.
    public Void visitDeclaration(@NotNull KtDeclaration expression, @NotNull TranslationContext context) {
        return null;
    }

    @Override
    public Void visitSecondaryConstructor(@NotNull KtSecondaryConstructor constructor, TranslationContext data) {
        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy