001 /* 002 * Copyright 2010-2015 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.kotlin.js.translate.context; 018 019 import com.google.dart.compiler.backend.js.ast.*; 020 import org.jetbrains.annotations.NotNull; 021 import org.jetbrains.kotlin.builtins.KotlinBuiltIns; 022 import org.jetbrains.kotlin.descriptors.ClassDescriptor; 023 import org.jetbrains.kotlin.idea.JetLanguage; 024 import org.jetbrains.kotlin.name.FqName; 025 import org.jetbrains.kotlin.resolve.DescriptorUtils; 026 027 import static com.google.dart.compiler.backend.js.ast.AstPackage.JsObjectScope; 028 import static org.jetbrains.kotlin.js.translate.utils.ManglingUtils.getStableMangledNameForDescriptor; 029 030 /** 031 * Encapsulates different types of constants and naming conventions. 032 */ 033 public final class Namer { 034 public static final String KOTLIN_NAME = JetLanguage.NAME; 035 public static final String KOTLIN_LOWER_NAME = KOTLIN_NAME.toLowerCase(); 036 public static final JsNameRef KOTLIN_OBJECT_REF = new JsNameRef(KOTLIN_NAME); 037 public static final JsNameRef KOTLIN_LONG_NAME_REF = new JsNameRef("Long", KOTLIN_OBJECT_REF); 038 039 public static final String EQUALS_METHOD_NAME = getStableMangledNameForDescriptor(KotlinBuiltIns.getInstance().getAny(), "equals"); 040 public static final String COMPARE_TO_METHOD_NAME = getStableMangledNameForDescriptor(KotlinBuiltIns.getInstance().getComparable(), "compareTo"); 041 public static final String NUMBER_RANGE = "NumberRange"; 042 public static final String CHAR_RANGE = "CharRange"; 043 public static final String LONG_FROM_NUMBER = "fromNumber"; 044 public static final String LONG_TO_NUMBER = "toNumber"; 045 public static final String LONG_FROM_INT = "fromInt"; 046 public static final String LONG_ZERO = "ZERO"; 047 public static final String LONG_ONE = "ONE"; 048 public static final String LONG_NEG_ONE = "NEG_ONE"; 049 public static final String PRIMITIVE_COMPARE_TO = "primitiveCompareTo"; 050 public static final String IS_CHAR = "isChar"; 051 public static final String IS_NUMBER = "isNumber"; 052 053 public static final String CALLEE_NAME = "$fun"; 054 055 public static final String CALL_FUNCTION = "call"; 056 private static final String APPLY_FUNCTION = "apply"; 057 058 private static final String CLASS_OBJECT_NAME = "createClass"; 059 private static final String ENUM_CLASS_OBJECT_NAME = "createEnumClass"; 060 private static final String TRAIT_OBJECT_NAME = "createTrait"; 061 private static final String OBJECT_OBJECT_NAME = "createObject"; 062 private static final String CALLABLE_REF_FOR_MEMBER_FUNCTION_NAME = "getCallableRefForMemberFunction"; 063 private static final String CALLABLE_REF_FOR_EXTENSION_FUNCTION_NAME = "getCallableRefForExtensionFunction"; 064 private static final String CALLABLE_REF_FOR_CONSTRUCTOR_NAME = "getCallableRefForConstructor"; 065 private static final String CALLABLE_REF_FOR_TOP_LEVEL_PROPERTY = "getCallableRefForTopLevelProperty"; 066 private static final String CALLABLE_REF_FOR_MEMBER_PROPERTY = "getCallableRefForMemberProperty"; 067 private static final String CALLABLE_REF_FOR_EXTENSION_PROPERTY = "getCallableRefForExtensionProperty"; 068 069 private static final String SETTER_PREFIX = "set_"; 070 private static final String GETTER_PREFIX = "get_"; 071 private static final String BACKING_FIELD_PREFIX = "$"; 072 private static final String DELEGATE = "$delegate"; 073 074 private static final String SUPER_METHOD_NAME = "baseInitializer"; 075 076 private static final String ROOT_PACKAGE = "_"; 077 078 private static final String RECEIVER_PARAMETER_NAME = "$receiver"; 079 080 private static final String THROW_NPE_FUN_NAME = "throwNPE"; 081 private static final String DEFAULT_OBJECT_GETTER = "object"; 082 private static final String DEFAULT_OBJECT_INITIALIZER = "object_initializer$"; 083 private static final String PROTOTYPE_NAME = "prototype"; 084 public static final String CAPTURED_VAR_FIELD = "v"; 085 086 @NotNull 087 public static final JsExpression UNDEFINED_EXPRESSION = new JsPrefixOperation(JsUnaryOperator.VOID, JsNumberLiteral.ZERO); 088 089 public static boolean isUndefined(@NotNull JsExpression expr) { 090 if (expr instanceof JsPrefixOperation) { 091 JsUnaryOperator op = ((JsPrefixOperation) expr).getOperator(); 092 093 return op == JsUnaryOperator.VOID; 094 } 095 096 return false; 097 } 098 099 @NotNull 100 public static String getReceiverParameterName() { 101 return RECEIVER_PARAMETER_NAME; 102 } 103 104 @NotNull 105 public static String getRootPackageName() { 106 return ROOT_PACKAGE; 107 } 108 109 @NotNull 110 public static JsNameRef superMethodNameRef(@NotNull JsName superClassJsName) { 111 return new JsNameRef(SUPER_METHOD_NAME, superClassJsName.makeRef()); 112 } 113 114 @NotNull 115 public static String getNameForAccessor(@NotNull String propertyName, boolean isGetter, boolean useNativeAccessor) { 116 if (useNativeAccessor) { 117 return propertyName; 118 } 119 120 if (isGetter) { 121 return getNameForGetter(propertyName); 122 } 123 else { 124 return getNameForSetter(propertyName); 125 } 126 } 127 128 @NotNull 129 public static String getKotlinBackingFieldName(@NotNull String propertyName) { 130 return getNameWithPrefix(propertyName, BACKING_FIELD_PREFIX); 131 } 132 133 @NotNull 134 private static String getNameForGetter(@NotNull String propertyName) { 135 return getNameWithPrefix(propertyName, GETTER_PREFIX); 136 } 137 138 @NotNull 139 private static String getNameForSetter(@NotNull String propertyName) { 140 return getNameWithPrefix(propertyName, SETTER_PREFIX); 141 } 142 143 @NotNull 144 public static JsExpression getDefaultObjectAccessor(@NotNull JsExpression referenceToClass) { 145 return new JsNameRef(DEFAULT_OBJECT_GETTER, referenceToClass); 146 } 147 148 @NotNull 149 public static String getNameForDefaultObjectInitializer() { 150 return DEFAULT_OBJECT_INITIALIZER; 151 } 152 153 @NotNull 154 public static String getPrototypeName() { 155 return PROTOTYPE_NAME; 156 } 157 158 @NotNull 159 public static JsNameRef getRefToPrototype(@NotNull JsExpression classOrTraitExpression) { 160 return new JsNameRef(getPrototypeName(), classOrTraitExpression); 161 } 162 163 @NotNull 164 public static String getDelegatePrefix() { 165 return DELEGATE; 166 } 167 168 @NotNull 169 public static String getDelegateName(@NotNull String propertyName) { 170 return propertyName + DELEGATE; 171 } 172 173 @NotNull 174 public static JsNameRef getDelegateNameRef(String propertyName) { 175 return new JsNameRef(getDelegateName(propertyName), JsLiteral.THIS); 176 } 177 178 @NotNull 179 private static String getNameWithPrefix(@NotNull String name, @NotNull String prefix) { 180 return prefix + name; 181 } 182 183 @NotNull 184 public static JsNameRef getFunctionCallRef(@NotNull JsExpression functionExpression) { 185 return new JsNameRef(CALL_FUNCTION, functionExpression); 186 } 187 188 @NotNull 189 public static JsNameRef getFunctionApplyRef(@NotNull JsExpression functionExpression) { 190 return new JsNameRef(APPLY_FUNCTION, functionExpression); 191 } 192 193 @NotNull 194 public static JsNameRef getCapturedVarAccessor(@NotNull JsExpression ref) { 195 return new JsNameRef(CAPTURED_VAR_FIELD, ref); 196 } 197 198 @NotNull 199 public static Namer newInstance(@NotNull JsScope rootScope) { 200 return new Namer(rootScope); 201 } 202 203 @NotNull 204 private final JsName kotlinName; 205 @NotNull 206 private final JsObjectScope kotlinScope; 207 @NotNull 208 private final JsName className; 209 @NotNull 210 private final JsName enumClassName; 211 @NotNull 212 private final JsName traitName; 213 @NotNull 214 private final JsExpression definePackage; 215 @NotNull 216 private final JsExpression defineRootPackage; 217 @NotNull 218 private final JsName objectName; 219 @NotNull 220 private final JsName callableRefForMemberFunctionName; 221 @NotNull 222 private final JsName callableRefForExtensionFunctionName; 223 @NotNull 224 private final JsName callableRefForConstructorName; 225 @NotNull 226 private final JsName callableRefForTopLevelProperty; 227 @NotNull 228 private final JsName callableRefForMemberProperty; 229 @NotNull 230 private final JsName callableRefForExtensionProperty; 231 @NotNull 232 private final JsExpression callGetProperty; 233 @NotNull 234 private final JsExpression callSetProperty; 235 236 @NotNull 237 private final JsName isTypeName; 238 239 private Namer(@NotNull JsScope rootScope) { 240 kotlinName = rootScope.declareName(KOTLIN_NAME); 241 kotlinScope = JsObjectScope(rootScope, "Kotlin standard object"); 242 traitName = kotlinScope.declareName(TRAIT_OBJECT_NAME); 243 244 definePackage = kotlin("definePackage"); 245 defineRootPackage = kotlin("defineRootPackage"); 246 247 callGetProperty = kotlin("callGetter"); 248 callSetProperty = kotlin("callSetter"); 249 250 className = kotlinScope.declareName(CLASS_OBJECT_NAME); 251 enumClassName = kotlinScope.declareName(ENUM_CLASS_OBJECT_NAME); 252 objectName = kotlinScope.declareName(OBJECT_OBJECT_NAME); 253 callableRefForMemberFunctionName = kotlinScope.declareName(CALLABLE_REF_FOR_MEMBER_FUNCTION_NAME); 254 callableRefForExtensionFunctionName = kotlinScope.declareName(CALLABLE_REF_FOR_EXTENSION_FUNCTION_NAME); 255 callableRefForConstructorName = kotlinScope.declareName(CALLABLE_REF_FOR_CONSTRUCTOR_NAME); 256 callableRefForTopLevelProperty = kotlinScope.declareName(CALLABLE_REF_FOR_TOP_LEVEL_PROPERTY); 257 callableRefForMemberProperty = kotlinScope.declareName(CALLABLE_REF_FOR_MEMBER_PROPERTY); 258 callableRefForExtensionProperty = kotlinScope.declareName(CALLABLE_REF_FOR_EXTENSION_PROPERTY); 259 260 isTypeName = kotlinScope.declareName("isType"); 261 } 262 263 @NotNull 264 public JsExpression classCreationMethodReference() { 265 return kotlin(className); 266 } 267 268 @NotNull 269 public JsExpression enumClassCreationMethodReference() { 270 return kotlin(enumClassName); 271 } 272 273 @NotNull 274 public JsExpression traitCreationMethodReference() { 275 return kotlin(traitName); 276 } 277 278 @NotNull 279 public JsExpression packageDefinitionMethodReference() { 280 return definePackage; 281 } 282 283 @NotNull 284 public JsExpression rootPackageDefinitionMethodReference() { 285 return defineRootPackage; 286 } 287 288 @NotNull 289 public JsExpression objectCreationMethodReference() { 290 return kotlin(objectName); 291 } 292 293 @NotNull 294 public JsExpression callableRefForMemberFunctionReference() { 295 return kotlin(callableRefForMemberFunctionName); 296 } 297 298 @NotNull 299 public JsExpression callableRefForExtensionFunctionReference() { 300 return kotlin(callableRefForExtensionFunctionName); 301 } 302 303 @NotNull 304 public JsExpression callableRefForConstructorReference() { 305 return kotlin(callableRefForConstructorName); 306 } 307 308 @NotNull 309 public JsExpression callableRefForTopLevelPropertyReference() { 310 return kotlin(callableRefForTopLevelProperty); 311 } 312 313 @NotNull 314 public JsExpression callableRefForMemberPropertyReference() { 315 return kotlin(callableRefForMemberProperty); 316 } 317 318 @NotNull 319 public JsExpression callableRefForExtensionPropertyReference() { 320 return kotlin(callableRefForExtensionProperty); 321 } 322 323 @NotNull 324 public JsExpression throwNPEFunctionRef() { 325 return new JsNameRef(THROW_NPE_FUN_NAME, kotlinObject()); 326 } 327 328 @NotNull 329 private JsNameRef kotlin(@NotNull JsName name) { 330 return new JsNameRef(name, kotlinObject()); 331 } 332 333 @NotNull 334 public JsExpression kotlin(@NotNull String name) { 335 return kotlin(kotlinScope.declareName(name)); 336 } 337 338 @NotNull 339 public JsNameRef kotlinObject() { 340 return kotlinName.makeRef(); 341 } 342 343 @NotNull 344 public JsExpression isOperationReference() { 345 return kotlin(isTypeName); 346 } 347 348 @NotNull 349 /*package*/ JsObjectScope getKotlinScope() { 350 return kotlinScope; 351 } 352 353 @NotNull 354 static String generatePackageName(@NotNull FqName packageFqName) { 355 return packageFqName.isRoot() ? getRootPackageName() : packageFqName.shortName().asString(); 356 } 357 358 @NotNull 359 public JsExpression classCreateInvocation(@NotNull ClassDescriptor descriptor) { 360 switch (descriptor.getKind()) { 361 case TRAIT: 362 return traitCreationMethodReference(); 363 case ENUM_CLASS: 364 return enumClassCreationMethodReference(); 365 case ENUM_ENTRY: 366 case OBJECT: 367 return objectCreationMethodReference(); 368 case ANNOTATION_CLASS: 369 case CLASS: 370 return DescriptorUtils.isAnonymousObject(descriptor) 371 ? objectCreationMethodReference() 372 : classCreationMethodReference(); 373 default: 374 throw new UnsupportedOperationException("Unsupported class kind: " + descriptor); 375 } 376 } 377 378 @NotNull 379 public JsExpression getUndefinedExpression() { 380 return UNDEFINED_EXPRESSION; 381 } 382 383 @NotNull 384 public JsExpression getCallGetProperty() { 385 return callGetProperty; 386 } 387 388 @NotNull 389 public JsExpression getCallSetProperty() { 390 return callSetProperty; 391 } 392 }