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

org.jetbrains.k2js.translate.expression.foreach.ForTranslator Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/*
 * Copyright 2010-2013 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.k2js.translate.expression.foreach;

import com.google.dart.compiler.backend.js.ast.JsBlock;
import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsStatement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetForExpression;
import org.jetbrains.jet.lang.psi.JetMultiDeclaration;
import org.jetbrains.jet.lang.psi.JetParameter;
import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.expression.MultiDeclarationTranslator;
import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.general.Translation;

import static org.jetbrains.k2js.translate.utils.JsAstUtils.newVar;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopBody;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopParameter;

public abstract class ForTranslator extends AbstractTranslator {

    @NotNull
    public static JsStatement translate(@NotNull JetForExpression expression,
                                        @NotNull TranslationContext context) {
        if (RangeLiteralForTranslator.isApplicable(expression, context)) {
            return RangeLiteralForTranslator.doTranslate(expression, context);
        }
        if (RangeForTranslator.isApplicable(expression, context)) {
            return RangeForTranslator.doTranslate(expression, context);
        }
        if (ArrayForTranslator.isApplicable(expression, context)) {
            return ArrayForTranslator.doTranslate(expression, context);
        }
        return IteratorForTranslator.doTranslate(expression, context);
    }

    @NotNull
    protected final JetForExpression expression;
    @NotNull
    protected final JsName parameterName;
    @Nullable
    protected final JetMultiDeclaration multiParameter;

    protected ForTranslator(@NotNull JetForExpression forExpression, @NotNull TranslationContext context) {
        super(context);
        this.expression = forExpression;
        this.multiParameter = forExpression.getMultiParameter();
        this.parameterName = declareParameter();
    }

    @NotNull
    private JsName declareParameter() {
        JetParameter loopParameter = getLoopParameter(expression);
        if (loopParameter != null) {
            return context().getNameForElement(loopParameter);
        }
        assert parameterIsMultiDeclaration() : "If loopParameter is null, multi parameter must be not null";
        return context().scope().declareTemporary();
    }

    private boolean parameterIsMultiDeclaration() {
        return multiParameter != null;
    }

    @NotNull
    private JsStatement makeCurrentVarInit(@Nullable JsExpression itemValue) {
        if (multiParameter == null) {
            return newVar(parameterName, itemValue);
        } else {
            return MultiDeclarationTranslator.translate(multiParameter, parameterName, itemValue, context());
        }
    }

    @NotNull
    protected JsStatement translateBody(@Nullable JsExpression itemValue) {
        JsStatement realBody = Translation.translateAsStatement(getLoopBody(expression), context());
        if (itemValue == null && !parameterIsMultiDeclaration()) {
            return realBody;
        } else {
            JsStatement currentVarInit = makeCurrentVarInit(itemValue);
            if (realBody instanceof JsBlock) {
                JsBlock block = (JsBlock) realBody;
                block.getStatements().add(0, currentVarInit);
                return block;
            }
            else {
                return new JsBlock(currentVarInit, realBody);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy