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 }