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
017 package org.jetbrains.k2js.translate.reference;
018
019 import com.google.dart.compiler.backend.js.ast.JsExpression;
020 import org.jetbrains.annotations.NotNull;
021 import org.jetbrains.annotations.Nullable;
022 import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
023 import org.jetbrains.jet.lang.descriptors.PropertyGetterDescriptor;
024 import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor;
025 import org.jetbrains.jet.lang.descriptors.impl.PropertyDescriptorImpl;
026 import org.jetbrains.jet.lang.descriptors.impl.PropertyGetterDescriptorImpl;
027 import org.jetbrains.jet.lang.resolve.DescriptorFactory;
028 import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
029 import org.jetbrains.k2js.translate.context.TranslationContext;
030
031 import static org.jetbrains.k2js.translate.utils.TranslationUtils.assignmentToBackingField;
032
033 /**
034 * For properies /w accessors.
035 */
036 public final class KotlinPropertyAccessTranslator extends PropertyAccessTranslator {
037
038 @Nullable
039 private final JsExpression receiver;
040 @NotNull
041 private final PropertyDescriptor propertyDescriptor;
042 @NotNull
043 private final ResolvedCall<?> resolvedCall;
044
045 //TODO: too many params in constructor
046 /*package*/ KotlinPropertyAccessTranslator(@NotNull PropertyDescriptor descriptor,
047 @Nullable JsExpression receiver,
048 @NotNull ResolvedCall<?> resolvedCall,
049 @NotNull TranslationContext context) {
050 super(context);
051 this.receiver = receiver;
052 this.propertyDescriptor = descriptor.getOriginal();
053 this.resolvedCall = resolvedCall;
054 }
055
056 @NotNull
057 @Override
058 public JsExpression translateAsGet() {
059 return translateAsGet(receiver);
060 }
061
062 @Override
063 @NotNull
064 public JsExpression translateAsGet(@Nullable JsExpression receiver) {
065 PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
066 if (getter == null) {
067 //TODO: Temporary hack!!! Rewrite codegen!
068 //Now for consistency we don't create default getter for object declaration property descriptor
069 PropertyGetterDescriptorImpl getterImpl = DescriptorFactory.createDefaultGetter(propertyDescriptor);
070 getterImpl.initialize(propertyDescriptor.getType());
071 ((PropertyDescriptorImpl)propertyDescriptor).initialize(getterImpl, null);
072 getter = getterImpl;
073 }
074 assert getter != null : "Getter for kotlin properties should bot be null.";
075 return callBuilderForAccessor(receiver)
076 .descriptor(getter)
077 .translate();
078 }
079
080 @NotNull
081 @Override
082 public JsExpression translateAsSet(@NotNull JsExpression toSetTo) {
083 if (propertyDescriptor.isVar()) {
084 return translateAsSet(receiver, toSetTo);
085 } else {
086 return assignmentToBackingField(context(), propertyDescriptor, toSetTo);
087 }
088 }
089
090 @Override
091 @NotNull
092 public JsExpression translateAsSet(@Nullable JsExpression receiver, @NotNull JsExpression toSetTo) {
093 PropertySetterDescriptor setter = propertyDescriptor.getSetter();
094 assert setter != null : "Setter for kotlin properties should not be null.";
095 return callBuilderForAccessor(receiver)
096 .args(toSetTo)
097 .descriptor(setter)
098 .translate();
099 }
100
101 @NotNull
102 private CallBuilder callBuilderForAccessor(@Nullable JsExpression qualifier) {
103 return CallBuilder.build(context())
104 .receiver(qualifier)
105 .resolvedCall(resolvedCall)
106 .type(getCallType());
107 }
108
109
110 @NotNull
111 @Override
112 public CachedAccessTranslator getCached() {
113 return new CachedPropertyAccessTranslator(receiver, this, context());
114 }
115 }