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.context;
018    
019    import com.google.dart.compiler.backend.js.ast.*;
020    import org.jetbrains.annotations.NotNull;
021    import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
022    import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
023    import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
024    import org.jetbrains.jet.lang.resolve.DescriptorUtils;
025    
026    /**
027     * Encapuslates different types of constants and naming conventions.
028     */
029    public final class Namer {
030        public static final String CALLEE_NAME = "$fun";
031    
032        private static final String INITIALIZE_METHOD_NAME = "initialize";
033        private static final String CLASS_OBJECT_NAME = "createClass";
034        private static final String TRAIT_OBJECT_NAME = "createTrait";
035        private static final String OBJECT_OBJECT_NAME = "createObject";
036        private static final String SETTER_PREFIX = "set_";
037        private static final String GETTER_PREFIX = "get_";
038        private static final String BACKING_FIELD_PREFIX = "$";
039        private static final String SUPER_METHOD_NAME = "super_init";
040        private static final String KOTLIN_OBJECT_NAME = "Kotlin";
041        private static final String ROOT_NAMESPACE = "_";
042        private static final String RECEIVER_PARAMETER_NAME = "receiver";
043        private static final String CLASSES_OBJECT_NAME = "classes";
044        private static final String THROW_NPE_FUN_NAME = "throwNPE";
045    
046        @NotNull
047        public static String getReceiverParameterName() {
048            return RECEIVER_PARAMETER_NAME;
049        }
050    
051        @NotNull
052        public static String getRootNamespaceName() {
053            return ROOT_NAMESPACE;
054        }
055    
056        @NotNull
057        public static JsNameRef initializeMethodReference() {
058            return new JsNameRef(INITIALIZE_METHOD_NAME);
059        }
060    
061        @NotNull
062        public static String superMethodName() {
063            return SUPER_METHOD_NAME;
064        }
065    
066        @NotNull
067        public static String nameForClassesVariable() {
068            return CLASSES_OBJECT_NAME;
069        }
070    
071        @NotNull
072        public static String getNameForAccessor(@NotNull String propertyName, boolean isGetter, boolean useNativeAccessor) {
073            if (useNativeAccessor) {
074                return propertyName;
075            }
076    
077            if (isGetter) {
078                return getNameForGetter(propertyName);
079            }
080            else {
081                return getNameForSetter(propertyName);
082            }
083        }
084    
085        @NotNull
086        public static String getKotlinBackingFieldName(@NotNull String propertyName) {
087            return getNameWithPrefix(propertyName, BACKING_FIELD_PREFIX);
088        }
089    
090        @NotNull
091        private static String getNameForGetter(@NotNull String propertyName) {
092            return getNameWithPrefix(propertyName, GETTER_PREFIX);
093        }
094    
095        @NotNull
096        private static String getNameForSetter(@NotNull String propertyName) {
097            return getNameWithPrefix(propertyName, SETTER_PREFIX);
098        }
099    
100        @NotNull
101        private static String getNameWithPrefix(@NotNull String name, @NotNull String prefix) {
102            return prefix + name;
103        }
104    
105        public static Namer newInstance(@NotNull JsScope rootScope) {
106            return new Namer(rootScope);
107        }
108    
109        @NotNull
110        private final JsName kotlinName;
111        @NotNull
112        private final JsScope kotlinScope;
113        @NotNull
114        private final JsName className;
115        @NotNull
116        private final JsName traitName;
117        @NotNull
118        private final JsExpression definePackage;
119        @NotNull
120        private final JsName objectName;
121    
122        @NotNull
123        private final JsName isTypeName;
124    
125        private Namer(@NotNull JsScope rootScope) {
126            kotlinName = rootScope.declareName(KOTLIN_OBJECT_NAME);
127            kotlinScope = new JsScope(rootScope, "Kotlin standard object");
128            traitName = kotlinScope.declareName(TRAIT_OBJECT_NAME);
129    
130            definePackage = kotlin("definePackage");
131    
132            className = kotlinScope.declareName(CLASS_OBJECT_NAME);
133            objectName = kotlinScope.declareName(OBJECT_OBJECT_NAME);
134    
135            isTypeName = kotlinScope.declareName("isType");
136        }
137    
138        @NotNull
139        public JsExpression classCreationMethodReference() {
140            return kotlin(className);
141        }
142    
143        @NotNull
144        public JsExpression traitCreationMethodReference() {
145            return kotlin(traitName);
146        }
147    
148        @NotNull
149        public JsExpression packageDefinitionMethodReference() {
150            return definePackage;
151        }
152    
153        @NotNull
154        public JsExpression objectCreationMethodReference() {
155            return kotlin(objectName);
156        }
157    
158        @NotNull
159        public JsExpression throwNPEFunctionCall() {
160            return new JsInvocation(new JsNameRef(THROW_NPE_FUN_NAME, kotlinObject()));
161        }
162    
163        @NotNull
164        private JsNameRef kotlin(@NotNull JsName name) {
165            return new JsNameRef(name, kotlinObject());
166        }
167    
168        @NotNull
169        public JsExpression kotlin(@NotNull String name) {
170            return kotlin(kotlinScope.declareName(name));
171        }
172    
173        @NotNull
174        public JsNameRef kotlinObject() {
175            return kotlinName.makeRef();
176        }
177    
178        @NotNull
179        public JsExpression isOperationReference() {
180            return kotlin(isTypeName);
181        }
182    
183        @NotNull
184            /*package*/ JsScope getKotlinScope() {
185            return kotlinScope;
186        }
187    
188        @NotNull
189        static String generateNamespaceName(DeclarationDescriptor descriptor) {
190            if (DescriptorUtils.isRootNamespace((NamespaceDescriptor) descriptor)) {
191                return getRootNamespaceName();
192            }
193            else {
194                return descriptor.getName().asString();
195            }
196        }
197    
198        @NotNull
199        public JsInvocation classCreateInvocation(@NotNull ClassDescriptor descriptor) {
200            switch (descriptor.getKind()) {
201                case TRAIT:
202                    return new JsInvocation(traitCreationMethodReference());
203                case OBJECT:
204                    return new JsInvocation(objectCreationMethodReference());
205    
206                default:
207                    return new JsInvocation(classCreationMethodReference());
208            }
209        }
210    }