001 /*
002 * Copyright 2010-2015 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
017 package org.jetbrains.kotlin.js.translate.reference;
018
019 import com.google.dart.compiler.backend.js.ast.JsExpression;
020 import org.jetbrains.annotations.NotNull;
021 import org.jetbrains.kotlin.psi.*;
022 import org.jetbrains.kotlin.js.translate.context.TemporaryVariable;
023 import org.jetbrains.kotlin.js.translate.context.TranslationContext;
024 import org.jetbrains.kotlin.js.translate.general.Translation;
025 import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
026 import org.jetbrains.kotlin.js.translate.utils.TranslationUtils;
027
028 import java.util.LinkedHashMap;
029 import java.util.Map;
030
031 public final class AccessTranslationUtils {
032 private AccessTranslationUtils() {
033 }
034
035 @NotNull
036 public static AccessTranslator getAccessTranslator(@NotNull JetExpression referenceExpression,
037 @NotNull TranslationContext context) {
038 return getAccessTranslator(referenceExpression, context, false);
039 }
040
041 @NotNull
042 public static AccessTranslator getAccessTranslator(@NotNull JetExpression referenceExpression,
043 @NotNull TranslationContext context, boolean forceOrderOfEvaluation) {
044 assert ((referenceExpression instanceof JetReferenceExpression) ||
045 (referenceExpression instanceof JetQualifiedExpression));
046 if (referenceExpression instanceof JetQualifiedExpression) {
047 return QualifiedExpressionTranslator.getAccessTranslator((JetQualifiedExpression) referenceExpression, context, forceOrderOfEvaluation);
048 }
049 if (referenceExpression instanceof JetSimpleNameExpression) {
050 return ReferenceTranslator.getAccessTranslator((JetSimpleNameExpression) referenceExpression, context);
051 }
052 assert referenceExpression instanceof JetArrayAccessExpression;
053 return getArrayAccessTranslator((JetArrayAccessExpression) referenceExpression, context, forceOrderOfEvaluation);
054 }
055
056 @NotNull
057 private static AccessTranslator getArrayAccessTranslator(
058 @NotNull JetArrayAccessExpression expression,
059 @NotNull TranslationContext context,
060 boolean forceOrderOfEvaluation
061 ) {
062 TranslationContext accessArrayContext;
063 if (forceOrderOfEvaluation) {
064 Map<JetExpression, JsExpression> indexesMap = new LinkedHashMap<JetExpression, JsExpression>();
065 for(JetExpression indexExpression : expression.getIndexExpressions()) {
066 JsExpression jsIndexExpression = Translation.translateAsExpression(indexExpression, context);
067 if (TranslationUtils.isCacheNeeded(jsIndexExpression)) {
068 TemporaryVariable temporaryVariable = context.declareTemporary(null);
069 context.addStatementToCurrentBlock(JsAstUtils.assignment(temporaryVariable.reference(), jsIndexExpression).makeStmt());
070 jsIndexExpression = temporaryVariable.reference();
071 }
072 indexesMap.put(indexExpression, jsIndexExpression);
073 }
074 accessArrayContext = context.innerContextWithAliasesForExpressions(indexesMap);
075 } else {
076 accessArrayContext = context;
077 }
078
079 return ArrayAccessTranslator.newInstance(expression, accessArrayContext);
080 }
081
082 @NotNull
083 public static CachedAccessTranslator getCachedAccessTranslator(@NotNull JetExpression referenceExpression,
084 @NotNull TranslationContext context) {
085 return getAccessTranslator(referenceExpression, context).getCached();
086 }
087
088 @NotNull
089 public static JsExpression translateAsGet(@NotNull JetExpression expression,
090 @NotNull TranslationContext context) {
091 return (getAccessTranslator(expression, context)).translateAsGet();
092 }
093 }