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 KtExpression referenceExpression, 037 @NotNull TranslationContext context) { 038 return getAccessTranslator(referenceExpression, context, false); 039 } 040 041 @NotNull 042 public static AccessTranslator getAccessTranslator(@NotNull KtExpression referenceExpression, 043 @NotNull TranslationContext context, boolean forceOrderOfEvaluation) { 044 assert ((referenceExpression instanceof KtReferenceExpression) || 045 (referenceExpression instanceof KtQualifiedExpression)); 046 if (referenceExpression instanceof KtQualifiedExpression) { 047 return QualifiedExpressionTranslator.getAccessTranslator((KtQualifiedExpression) referenceExpression, context, forceOrderOfEvaluation); 048 } 049 if (referenceExpression instanceof KtSimpleNameExpression) { 050 return ReferenceTranslator.getAccessTranslator((KtSimpleNameExpression) referenceExpression, context); 051 } 052 assert referenceExpression instanceof KtArrayAccessExpression; 053 return getArrayAccessTranslator((KtArrayAccessExpression) referenceExpression, context, forceOrderOfEvaluation); 054 } 055 056 @NotNull 057 private static AccessTranslator getArrayAccessTranslator( 058 @NotNull KtArrayAccessExpression expression, 059 @NotNull TranslationContext context, 060 boolean forceOrderOfEvaluation 061 ) { 062 TranslationContext accessArrayContext; 063 if (forceOrderOfEvaluation) { 064 Map<KtExpression, JsExpression> indexesMap = new LinkedHashMap<KtExpression, JsExpression>(); 065 for(KtExpression 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 KtExpression referenceExpression, 084 @NotNull TranslationContext context) { 085 return getAccessTranslator(referenceExpression, context).getCached(); 086 } 087 088 @NotNull 089 public static JsExpression translateAsGet(@NotNull KtExpression expression, 090 @NotNull TranslationContext context) { 091 return (getAccessTranslator(expression, context)).translateAsGet(); 092 } 093 }