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.initializer;
018    
019    import com.google.dart.compiler.backend.js.ast.*;
020    import org.jetbrains.annotations.NotNull;
021    import org.jetbrains.annotations.Nullable;
022    import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
023    import org.jetbrains.jet.lang.descriptors.Named;
024    import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
025    import org.jetbrains.jet.lang.psi.JetExpression;
026    import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
027    import org.jetbrains.jet.lang.psi.JetProperty;
028    import org.jetbrains.k2js.translate.context.Namer;
029    import org.jetbrains.k2js.translate.context.TranslationContext;
030    import org.jetbrains.k2js.translate.declaration.ClassTranslator;
031    import org.jetbrains.k2js.translate.general.Translation;
032    import org.jetbrains.k2js.translate.utils.JsAstUtils;
033    
034    import java.util.List;
035    
036    import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor;
037    import static org.jetbrains.k2js.translate.utils.JsAstUtils.assignment;
038    import static org.jetbrains.k2js.translate.utils.TranslationUtils.assignmentToBackingField;
039    
040    public final class InitializerUtils {
041        private InitializerUtils() {
042        }
043    
044        @NotNull
045        public static JsStatement generateInitializerForProperty(@NotNull TranslationContext context,
046                @NotNull PropertyDescriptor descriptor,
047                @NotNull JsExpression value) {
048            if (context.isEcma5()) {
049                return JsAstUtils.definePropertyDataDescriptor(descriptor, value, context).makeStmt();
050            }
051            else {
052                return assignmentToBackingField(context, descriptor, value).makeStmt();
053            }
054        }
055    
056        @Nullable
057        public static JsStatement generateInitializerForDelegate(@NotNull TranslationContext context, @NotNull JetProperty property) {
058            JetExpression delegate = property.getDelegateExpression();
059            if (delegate != null) {
060                JsExpression value = Translation.translateAsExpression(delegate, context);
061                String name = property.getName();
062                assert name != null: "Delegate property must have name";
063                return JsAstUtils.defineSimpleProperty(Namer.getDelegateName(name), value, context);
064            }
065            return null;
066        }
067    
068        public static void generate(@NotNull JetObjectDeclaration declaration,
069                @NotNull List<JsStatement> initializers,
070                @Nullable List<JsPropertyInitializer> definitions,
071                @NotNull TranslationContext context) {
072            ClassDescriptor descriptor = getClassDescriptor(context.bindingContext(), declaration);
073            JsExpression value = ClassTranslator.generateClassCreation(declaration, descriptor, context);
074            if (definitions != null && value instanceof JsLiteral) {
075                definitions.add(createPropertyInitializer(descriptor, value, context));
076            }
077            else {
078                initializers.add(create(descriptor, value, context));
079            }
080        }
081    
082        public static JsStatement create(Named named, JsExpression value, TranslationContext context) {
083            JsExpression expression;
084            if (context.isEcma5()) {
085                expression = JsAstUtils.defineProperty(named.getName().asString(), JsAstUtils.createDataDescriptor(value), context);
086            }
087            else {
088                expression = assignment(new JsNameRef(named.getName().asString(), JsLiteral.THIS), value);
089            }
090            return expression.makeStmt();
091        }
092    
093    
094        public static JsExpression toDataDescriptor(JsExpression value, TranslationContext context) {
095            return context.isEcma5() ? JsAstUtils.createDataDescriptor(value) : value;
096        }
097    
098        public static JsPropertyInitializer createPropertyInitializer(Named named, JsExpression value, TranslationContext context) {
099            return new JsPropertyInitializer(context.nameToLiteral(named), toDataDescriptor(value, context));
100        }
101    }