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