001/*
002 * Copyright 2010-2013 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.jetbrains.k2js.translate.expression;
018
019import com.google.dart.compiler.backend.js.ast.*;
020import com.intellij.util.SmartList;
021import org.jetbrains.annotations.NotNull;
022import org.jetbrains.annotations.Nullable;
023import org.jetbrains.jet.lang.psi.*;
024import org.jetbrains.k2js.translate.context.TranslationContext;
025import org.jetbrains.k2js.translate.general.AbstractTranslator;
026import org.jetbrains.k2js.translate.general.Translation;
027
028import java.util.List;
029
030import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToBlock;
031
032//TODO: not tested at all
033//TODO: not implemented catch logic
034public final class TryTranslator extends AbstractTranslator {
035
036    @NotNull
037    public static JsTry translate(@NotNull JetTryExpression expression,
038                                  @NotNull TranslationContext context) {
039        return (new TryTranslator(expression, context)).translate();
040    }
041
042    @NotNull
043    private final JetTryExpression expression;
044
045    private TryTranslator(@NotNull JetTryExpression expression,
046                          @NotNull TranslationContext context) {
047        super(context);
048        this.expression = expression;
049    }
050
051    private JsTry translate() {
052        return new JsTry(translateTryBlock(), translateCatches(), translateFinallyBlock());
053    }
054
055    @Nullable
056    private JsBlock translateFinallyBlock() {
057        JetFinallySection finallyBlock = expression.getFinallyBlock();
058        if (finallyBlock == null) return null;
059
060        return convertToBlock(Translation.translateAsStatement(finallyBlock.getFinalExpression(), context()));
061    }
062
063    @NotNull
064    private JsBlock translateTryBlock() {
065        return convertToBlock(Translation.translateAsStatement(expression.getTryBlock(), context()));
066    }
067
068    @NotNull
069    private List<JsCatch> translateCatches() {
070        List<JsCatch> result = new SmartList<JsCatch>();
071        for (JetCatchClause catchClause : expression.getCatchClauses()) {
072            result.add(translateCatchClause(catchClause));
073        }
074        return result;
075    }
076
077    @NotNull
078    private JsCatch translateCatchClause(@NotNull JetCatchClause catchClause) {
079        JetParameter catchParameter = catchClause.getCatchParameter();
080        assert catchParameter != null : "Valid catch must have a parameter.";
081
082        JsName parameterName = context().getNameForElement(catchParameter);
083        JsCatch result = new JsCatch(context().scope(), parameterName.getIdent());
084        result.setBody(translateCatchBody(catchClause));
085        return result;
086    }
087
088    @NotNull
089    private JsBlock translateCatchBody(@NotNull JetCatchClause catchClause) {
090        JetExpression catchBody = catchClause.getCatchBody();
091        if (catchBody == null) {
092            return convertToBlock(program().getEmptyStmt());
093        }
094        return convertToBlock(Translation.translateAsStatement(catchBody, context()));
095    }
096
097}