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.dart.compiler.backend.js.ast.JsExpression; 020import com.google.dart.compiler.backend.js.ast.JsName; 021import com.google.dart.compiler.backend.js.ast.JsNameRef; 022import org.jetbrains.annotations.NotNull; 023import org.jetbrains.annotations.Nullable; 024import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; 025import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; 026import org.jetbrains.k2js.translate.context.TranslationContext; 027 028import static org.jetbrains.k2js.translate.utils.JsAstUtils.assignment; 029import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getExpectedThisDescriptor; 030 031/** 032 * For native apis that use .property notation for access. 033 */ 034public final class NativePropertyAccessTranslator extends PropertyAccessTranslator { 035 036 @Nullable 037 private final JsExpression receiver; 038 @NotNull 039 private final PropertyDescriptor propertyDescriptor; 040 041 /*package*/ 042 NativePropertyAccessTranslator(@NotNull PropertyDescriptor descriptor, 043 @Nullable JsExpression receiver, 044 @NotNull TranslationContext context) { 045 super(context); 046 this.receiver = receiver; 047 this.propertyDescriptor = descriptor.getOriginal(); 048 } 049 050 @Override 051 @NotNull 052 public JsExpression translateAsGet() { 053 return translateAsGet(getReceiver()); 054 } 055 056 @NotNull 057 @Override 058 protected JsExpression translateAsGet(@Nullable JsExpression receiver) { 059 return getCallType().constructCall(receiver, new CallType.CallConstructor() { 060 @NotNull 061 @Override 062 public JsExpression construct(@Nullable JsExpression receiver) { 063 return doTranslateAsGet(receiver); 064 } 065 }, context()); 066 } 067 068 @NotNull 069 private JsExpression doTranslateAsGet(JsExpression receiver) { 070 JsName nativePropertyName = context().getNameForDescriptor(propertyDescriptor); 071 if (receiver != null) { 072 return new JsNameRef(nativePropertyName, receiver); 073 } 074 else { 075 return nativePropertyName.makeRef(); 076 } 077 } 078 079 @Override 080 @NotNull 081 protected JsExpression translateAsSet(@Nullable JsExpression receiver, @NotNull final JsExpression setTo) { 082 assert receiver != null; 083 return getCallType().constructCall(receiver, new CallType.CallConstructor() { 084 @NotNull 085 @Override 086 public JsExpression construct(@Nullable JsExpression receiver) { 087 return assignment(translateAsGet(receiver), setTo); 088 } 089 }, context()); 090 } 091 092 @NotNull 093 @Override 094 public JsExpression translateAsSet(@NotNull JsExpression setTo) { 095 return translateAsSet(getReceiver(), setTo); 096 } 097 098 @Nullable 099 private JsExpression getReceiver() { 100 if (receiver != null) { 101 return receiver; 102 } 103 assert propertyDescriptor.getReceiverParameter() == null : "Can't have native extension properties."; 104 DeclarationDescriptor expectedThisDescriptor = getExpectedThisDescriptor(propertyDescriptor); 105 if (expectedThisDescriptor == null) { 106 return null; 107 } 108 return context().getThisObject(expectedThisDescriptor); 109 } 110 111 @NotNull 112 @Override 113 public CachedAccessTranslator getCached() { 114 return new CachedPropertyAccessTranslator(getReceiver(), this, context()); 115 } 116}