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.reference;
018
019import com.google.common.collect.Lists;
020import com.google.dart.compiler.backend.js.ast.JsExpression;
021import org.jetbrains.annotations.NotNull;
022import org.jetbrains.jet.lang.psi.JetArrayAccessExpression;
023import org.jetbrains.jet.lang.psi.JetExpression;
024import org.jetbrains.k2js.translate.context.TranslationContext;
025import org.jetbrains.k2js.translate.general.AbstractTranslator;
026import org.jetbrains.k2js.translate.general.Translation;
027import org.jetbrains.k2js.translate.utils.BindingUtils;
028import org.jetbrains.k2js.translate.utils.TranslationUtils;
029
030import java.util.List;
031
032public class ArrayAccessTranslator extends AbstractTranslator implements AccessTranslator {
033
034    /*package*/
035    static ArrayAccessTranslator newInstance(@NotNull JetArrayAccessExpression expression,
036                                             @NotNull TranslationContext context) {
037        return new ArrayAccessTranslator(expression, context);
038    }
039
040    @NotNull
041    private final JetArrayAccessExpression expression;
042
043    protected ArrayAccessTranslator(@NotNull JetArrayAccessExpression expression,
044                                    @NotNull TranslationContext context) {
045        super(context);
046        this.expression = expression;
047    }
048
049    @NotNull
050    @Override
051    public JsExpression translateAsGet() {
052        return translateAsGet(translateArrayExpression(), translateIndexExpressions());
053    }
054
055    @NotNull
056    protected JsExpression translateAsGet(@NotNull JsExpression arrayExpression,
057                                          @NotNull List<JsExpression> indexExpression) {
058        return translateAsMethodCall(arrayExpression, indexExpression, /*isGetter = */ true);
059    }
060
061    @NotNull
062    @Override
063    public JsExpression translateAsSet(@NotNull JsExpression setTo) {
064        return translateAsSet(translateArrayExpression(), translateIndexExpressions(), setTo);
065    }
066
067    @NotNull
068    protected JsExpression translateAsSet(@NotNull JsExpression arrayExpression, @NotNull List<JsExpression> indexExpressions, @NotNull JsExpression toSetTo) {
069        List<JsExpression> arguments = Lists.newArrayList(indexExpressions);
070        arguments.add(toSetTo);
071        return translateAsMethodCall(arrayExpression, arguments, /*isGetter = */ false);
072    }
073
074    @NotNull
075    private JsExpression translateAsMethodCall(@NotNull JsExpression arrayExpression,
076                                               @NotNull List<JsExpression> arguments,
077                                               boolean isGetter) {
078        return CallBuilder.build(context())
079                .receiver(arrayExpression)
080                .args(arguments)
081                .resolvedCall(BindingUtils.getResolvedCallForArrayAccess(bindingContext(), expression, isGetter))
082                .translate();
083    }
084
085    @NotNull
086    protected List<JsExpression> translateIndexExpressions() {
087        return TranslationUtils.translateExpressionList(context(), expression.getIndexExpressions());
088    }
089
090    @NotNull
091    protected JsExpression translateArrayExpression() {
092        JetExpression arrayExpression = expression.getArrayExpression();
093        assert arrayExpression != null : "Code with parsing errors shouldn't be translated";
094        return Translation.translateAsExpression(arrayExpression, context());
095    }
096
097    @NotNull
098    @Override
099    public CachedAccessTranslator getCached() {
100        return new CachedArrayAccessTranslator(expression, context());
101    }
102}