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 import org.jetbrains.jet.plugin.JetLanguage;
026
027 /**
028 * Encapuslates different types of constants and naming conventions.
029 */
030 public final class Namer {
031 public static final String KOTLIN_NAME = JetLanguage.NAME;
032 public static final String KOTLIN_LOWER_NAME = KOTLIN_NAME.toLowerCase();
033
034 public static final String CALLEE_NAME = "$fun";
035 public static final String OUTER_CLASS_NAME = "$outer";
036
037 private static final String CALL_FUNCTION = "call";
038 private static final String CLASS_OBJECT_NAME = "createClass";
039 private static final String TRAIT_OBJECT_NAME = "createTrait";
040 private static final String OBJECT_OBJECT_NAME = "createObject";
041 private static final String ENUM_ENTRIES_NAME = "createEnumEntries";
042 private static final String SETTER_PREFIX = "set_";
043 private static final String GETTER_PREFIX = "get_";
044 private static final String BACKING_FIELD_PREFIX = "$";
045 private static final String SUPER_METHOD_NAME = "baseInitializer";
046 private static final String ROOT_NAMESPACE = "_";
047 private static final String RECEIVER_PARAMETER_NAME = "$receiver";
048 private static final String CLASSES_OBJECT_NAME = "_c";
049 private static final String THROW_NPE_FUN_NAME = "throwNPE";
050 private static final String CLASS_OBJECT_GETTER = "object";
051 private static final String CLASS_OBJECT_INITIALIZER = "object_initializer$";
052 private static final String PROTOTYPE_NAME = "prototype";
053
054
055 private static final String DELEGATE_POSTFIX = "$delegate";
056 private static final String PROPERTY_METADATA = "PropertyMetadata";
057
058 @NotNull
059 public static String getReceiverParameterName() {
060 return RECEIVER_PARAMETER_NAME;
061 }
062
063 @NotNull
064 public static String getRootNamespaceName() {
065 return ROOT_NAMESPACE;
066 }
067
068 @NotNull
069 public static JsNameRef superMethodNameRef(@NotNull JsName superClassJsName) {
070 return new JsNameRef(SUPER_METHOD_NAME, superClassJsName.makeRef());
071 }
072
073 @NotNull
074 public static String nameForClassesVariable() {
075 return CLASSES_OBJECT_NAME;
076 }
077
078 @NotNull
079 public static String getNameForAccessor(@NotNull String propertyName, boolean isGetter, boolean useNativeAccessor) {
080 if (useNativeAccessor) {
081 return propertyName;
082 }
083
084 if (isGetter) {
085 return getNameForGetter(propertyName);
086 }
087 else {
088 return getNameForSetter(propertyName);
089 }
090 }
091
092 @NotNull
093 public static String getKotlinBackingFieldName(@NotNull String propertyName) {
094 return getNameWithPrefix(propertyName, BACKING_FIELD_PREFIX);
095 }
096
097 @NotNull
098 private static String getNameForGetter(@NotNull String propertyName) {
099 return getNameWithPrefix(propertyName, GETTER_PREFIX);
100 }
101
102 @NotNull
103 private static String getNameForSetter(@NotNull String propertyName) {
104 return getNameWithPrefix(propertyName, SETTER_PREFIX);
105 }
106
107 @NotNull
108 public static JsExpression getClassObjectAccessor(@NotNull JsExpression referenceToClass) {
109 return new JsNameRef(CLASS_OBJECT_GETTER, referenceToClass);
110 }
111
112 @NotNull
113 public static String getNameForClassObjectInitializer() {
114 return CLASS_OBJECT_INITIALIZER;
115 }
116
117 @NotNull
118 public static String getPrototypeName() {
119 return PROTOTYPE_NAME;
120 }
121
122 @NotNull
123 public static JsNameRef getRefToPrototype(@NotNull JsExpression classOrTraitExpression) {
124 return new JsNameRef(getPrototypeName(), classOrTraitExpression);
125 }
126
127 @NotNull
128 public static String getDelegateName(@NotNull String propertyName) {
129 return propertyName + DELEGATE_POSTFIX;
130 }
131
132 @NotNull
133 public static JsNameRef getDelegateNameRef(String propertyName) {
134 return new JsNameRef(getDelegateName(propertyName), JsLiteral.THIS);
135 }
136
137 @NotNull
138 private static String getNameWithPrefix(@NotNull String name, @NotNull String prefix) {
139 return prefix + name;
140 }
141
142 @NotNull
143 public static JsNameRef getFunctionCallRef(@NotNull JsExpression functionExpression) {
144 return new JsNameRef(CALL_FUNCTION, functionExpression);
145 }
146
147 @NotNull
148 public static Namer newInstance(@NotNull JsScope rootScope) {
149 return new Namer(rootScope);
150 }
151
152 @NotNull
153 private final JsName kotlinName;
154 @NotNull
155 private final JsScope kotlinScope;
156 @NotNull
157 private final JsName className;
158 @NotNull
159 private final JsName traitName;
160 @NotNull
161 private final JsExpression definePackage;
162 @NotNull
163 private final JsExpression defineRootPackage;
164 @NotNull
165 private final JsName objectName;
166 @NotNull
167 private final JsName enumEntriesName;
168 @NotNull
169 private final JsExpression undefinedExpression;
170 @NotNull
171 private final JsExpression callGetProperty;
172 @NotNull
173 private final JsExpression callSetProperty;
174
175 @NotNull
176 private final JsName isTypeName;
177
178 private Namer(@NotNull JsScope rootScope) {
179 kotlinName = rootScope.declareName(KOTLIN_NAME);
180 kotlinScope = new JsScope(rootScope, "Kotlin standard object");
181 traitName = kotlinScope.declareName(TRAIT_OBJECT_NAME);
182
183 definePackage = kotlin("definePackage");
184 defineRootPackage = kotlin("defineRootPackage");
185
186 callGetProperty = kotlin("callGetter");
187 callSetProperty = kotlin("callSetter");
188
189 className = kotlinScope.declareName(CLASS_OBJECT_NAME);
190 enumEntriesName = kotlinScope.declareName(ENUM_ENTRIES_NAME);
191 objectName = kotlinScope.declareName(OBJECT_OBJECT_NAME);
192
193 isTypeName = kotlinScope.declareName("isType");
194
195 undefinedExpression = new JsPrefixOperation(JsUnaryOperator.VOID, rootScope.getProgram().getNumberLiteral(0));
196 }
197
198 @NotNull
199 public JsExpression classCreationMethodReference() {
200 return kotlin(className);
201 }
202
203 @NotNull
204 public JsExpression enumEntriesCreationMethodReference() {
205 return kotlin(enumEntriesName);
206 }
207
208 @NotNull
209 public JsExpression traitCreationMethodReference() {
210 return kotlin(traitName);
211 }
212
213 @NotNull
214 public JsExpression packageDefinitionMethodReference() {
215 return definePackage;
216 }
217
218 @NotNull
219 public JsExpression rootPackageDefinitionMethodReference() {
220 return defineRootPackage;
221 }
222
223 @NotNull
224 public JsExpression objectCreationMethodReference() {
225 return kotlin(objectName);
226 }
227
228 @NotNull
229 public JsExpression throwNPEFunctionRef() {
230 return new JsNameRef(THROW_NPE_FUN_NAME, kotlinObject());
231 }
232
233 @NotNull
234 public JsNameRef propertyMetadataRef() {
235 return new JsNameRef(PROPERTY_METADATA, kotlinObject());
236 }
237
238 @NotNull
239 private JsNameRef kotlin(@NotNull JsName name) {
240 return new JsNameRef(name, kotlinObject());
241 }
242
243 @NotNull
244 public JsExpression kotlin(@NotNull String name) {
245 return kotlin(kotlinScope.declareName(name));
246 }
247
248 @NotNull
249 public JsNameRef kotlinObject() {
250 return kotlinName.makeRef();
251 }
252
253 @NotNull
254 public JsExpression isOperationReference() {
255 return kotlin(isTypeName);
256 }
257
258 @NotNull
259 /*package*/ JsScope getKotlinScope() {
260 return kotlinScope;
261 }
262
263 @NotNull
264 static String generateNamespaceName(@NotNull DeclarationDescriptor descriptor) {
265 if (DescriptorUtils.isRootNamespace((NamespaceDescriptor) descriptor)) {
266 return getRootNamespaceName();
267 }
268 else {
269 return descriptor.getName().asString();
270 }
271 }
272
273 @NotNull
274 public JsInvocation classCreateInvocation(@NotNull ClassDescriptor descriptor) {
275 switch (descriptor.getKind()) {
276 case TRAIT:
277 return new JsInvocation(traitCreationMethodReference());
278
279 case OBJECT:
280 case CLASS_OBJECT:
281 case ENUM_ENTRY:
282 return new JsInvocation(objectCreationMethodReference());
283
284 default:
285 return new JsInvocation(classCreationMethodReference());
286 }
287 }
288
289 @NotNull
290 public JsInvocation enumEntriesObjectCreateInvocation() {
291 return new JsInvocation(enumEntriesCreationMethodReference());
292 }
293
294 @NotNull
295 public JsExpression getUndefinedExpression() {
296 return undefinedExpression;
297 }
298
299 @NotNull
300 public JsExpression getCallGetProperty() {
301 return callGetProperty;
302 }
303
304 @NotNull
305 public JsExpression getCallSetProperty() {
306 return callSetProperty;
307 }
308 }