org.jetbrains.k2js.translate.expression.foreach.ForTranslator Maven / Gradle / Ivy
/*
* 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);
}
}
}
}