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.builtins;
018
019 import kotlin.SetsKt;
020 import kotlin.jvm.functions.Function1;
021 import org.jetbrains.annotations.NotNull;
022 import org.jetbrains.annotations.Nullable;
023 import org.jetbrains.kotlin.builtins.functions.BuiltInFictitiousFunctionClassFactory;
024 import org.jetbrains.kotlin.descriptors.*;
025 import org.jetbrains.kotlin.descriptors.annotations.*;
026 import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl;
027 import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
028 import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
029 import org.jetbrains.kotlin.name.ClassId;
030 import org.jetbrains.kotlin.name.FqName;
031 import org.jetbrains.kotlin.name.FqNameUnsafe;
032 import org.jetbrains.kotlin.name.Name;
033 import org.jetbrains.kotlin.resolve.DescriptorUtils;
034 import org.jetbrains.kotlin.resolve.constants.ConstantValue;
035 import org.jetbrains.kotlin.resolve.scopes.MemberScope;
036 import org.jetbrains.kotlin.serialization.deserialization.AdditionalSupertypes;
037 import org.jetbrains.kotlin.storage.LockBasedStorageManager;
038 import org.jetbrains.kotlin.types.*;
039 import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
040
041 import java.io.InputStream;
042 import java.util.*;
043
044 import static kotlin.CollectionsKt.*;
045 import static kotlin.SetsKt.setOf;
046 import static org.jetbrains.kotlin.builtins.PrimitiveType.*;
047 import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName;
048
049 public abstract class KotlinBuiltIns {
050 public static final Name BUILT_INS_PACKAGE_NAME = Name.identifier("kotlin");
051 public static final FqName BUILT_INS_PACKAGE_FQ_NAME = FqName.topLevel(BUILT_INS_PACKAGE_NAME);
052 public static final FqName ANNOTATION_PACKAGE_FQ_NAME = BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier("annotation"));
053
054 public static final Set<FqName> BUILT_INS_PACKAGE_FQ_NAMES = setOf(
055 BUILT_INS_PACKAGE_FQ_NAME,
056 ANNOTATION_PACKAGE_FQ_NAME,
057 ReflectionTypesKt.getKOTLIN_REFLECT_FQ_NAME()
058 );
059
060 protected final ModuleDescriptorImpl builtInsModule;
061 private final BuiltinsPackageFragment builtinsPackageFragment;
062 private final BuiltinsPackageFragment annotationPackageFragment;
063
064 private final Map<PrimitiveType, KotlinType> primitiveTypeToArrayKotlinType;
065 private final Map<KotlinType, KotlinType> primitiveKotlinTypeToKotlinArrayType;
066 private final Map<KotlinType, KotlinType> kotlinArrayTypeToPrimitiveKotlinType;
067
068 public static final FqNames FQ_NAMES = new FqNames();
069
070 protected KotlinBuiltIns() {
071 LockBasedStorageManager storageManager = new LockBasedStorageManager();
072 builtInsModule = new ModuleDescriptorImpl(
073 Name.special("<built-ins module>"), storageManager, ModuleParameters.Empty.INSTANCE$, this
074 );
075
076 PackageFragmentProvider packageFragmentProvider = BuiltInsPackageFragmentProviderKt.createBuiltInPackageFragmentProvider(
077 storageManager, builtInsModule, BUILT_INS_PACKAGE_FQ_NAMES,
078 new BuiltInFictitiousFunctionClassFactory(storageManager, builtInsModule),
079 getAdditionalSupertypesProvider(),
080 new Function1<String, InputStream>() {
081 @Override
082 public InputStream invoke(String path) {
083 return KotlinBuiltIns.class.getClassLoader().getResourceAsStream(path);
084 }
085 }
086 );
087
088 builtInsModule.initialize(packageFragmentProvider);
089 builtInsModule.setDependencies(builtInsModule);
090
091 builtinsPackageFragment = (BuiltinsPackageFragment) single(packageFragmentProvider.getPackageFragments(BUILT_INS_PACKAGE_FQ_NAME));
092 annotationPackageFragment = (BuiltinsPackageFragment) single(packageFragmentProvider.getPackageFragments(ANNOTATION_PACKAGE_FQ_NAME));
093
094 primitiveTypeToArrayKotlinType = new EnumMap<PrimitiveType, KotlinType>(PrimitiveType.class);
095 primitiveKotlinTypeToKotlinArrayType = new HashMap<KotlinType, KotlinType>();
096 kotlinArrayTypeToPrimitiveKotlinType = new HashMap<KotlinType, KotlinType>();
097 for (PrimitiveType primitive : PrimitiveType.values()) {
098 makePrimitive(primitive);
099 }
100 }
101
102 @NotNull
103 protected AdditionalSupertypes getAdditionalSupertypesProvider() {
104 return AdditionalSupertypes.None.INSTANCE$;
105 }
106
107 private void makePrimitive(@NotNull PrimitiveType primitiveType) {
108 KotlinType type = getBuiltInTypeByClassName(primitiveType.getTypeName().asString());
109 KotlinType arrayType = getBuiltInTypeByClassName(primitiveType.getArrayTypeName().asString());
110
111 primitiveTypeToArrayKotlinType.put(primitiveType, arrayType);
112 primitiveKotlinTypeToKotlinArrayType.put(type, arrayType);
113 kotlinArrayTypeToPrimitiveKotlinType.put(arrayType, type);
114 }
115
116 public static class FqNames {
117 public final FqNameUnsafe any = fqNameUnsafe("Any");
118 public final FqNameUnsafe nothing = fqNameUnsafe("Nothing");
119 public final FqNameUnsafe cloneable = fqNameUnsafe("Cloneable");
120 public final FqNameUnsafe suppress = fqNameUnsafe("Suppress");
121 public final FqNameUnsafe unit = fqNameUnsafe("Unit");
122 public final FqNameUnsafe string = fqNameUnsafe("String");
123 public final FqNameUnsafe array = fqNameUnsafe("Array");
124
125 public final FqNameUnsafe _boolean = fqNameUnsafe("Boolean");
126 public final FqNameUnsafe _char = fqNameUnsafe("Char");
127 public final FqNameUnsafe _byte = fqNameUnsafe("Byte");
128 public final FqNameUnsafe _short = fqNameUnsafe("Short");
129 public final FqNameUnsafe _int = fqNameUnsafe("Int");
130 public final FqNameUnsafe _long = fqNameUnsafe("Long");
131 public final FqNameUnsafe _float = fqNameUnsafe("Float");
132 public final FqNameUnsafe _double = fqNameUnsafe("Double");
133
134 public final FqNameUnsafe _collection = fqNameUnsafe("Collection");
135 public final FqNameUnsafe _list = fqNameUnsafe("List");
136 public final FqNameUnsafe _set = fqNameUnsafe("Set");
137 public final FqNameUnsafe _iterable = fqNameUnsafe("Iterable");
138
139 public final FqName throwable = fqName("Throwable");
140
141 public final FqName deprecated = fqName("Deprecated");
142 public final FqName tailRecursive = fqName("tailrec");
143 public final FqName extension = fqName("Extension");
144 public final FqName target = annotationName("Target");
145 public final FqName annotationTarget = annotationName("AnnotationTarget");
146 public final FqName annotationRetention = annotationName("AnnotationRetention");
147 public final FqName retention = annotationName("Retention");
148 public final FqName repeatable = annotationName("Repeatable");
149 public final FqName mustBeDocumented = annotationName("MustBeDocumented");
150 public final FqName unsafeVariance = fqName("UnsafeVariance");
151
152 public final FqName mutableList = fqName("MutableList");
153 public final FqName mutableSet = fqName("MutableSet");
154 public final FqName mutableMap = fqName("MutableMap");
155
156 public final FqNameUnsafe kClass = reflect("KClass");
157 public final FqNameUnsafe kCallable = reflect("KCallable");
158 public final ClassId kProperty = ClassId.topLevel(reflect("KProperty").toSafe());
159
160 public final Map<FqNameUnsafe, PrimitiveType> fqNameToPrimitiveType;
161 public final Map<FqNameUnsafe, PrimitiveType> arrayClassFqNameToPrimitiveType;
162 {
163 fqNameToPrimitiveType = new HashMap<FqNameUnsafe, PrimitiveType>(0);
164 arrayClassFqNameToPrimitiveType = new HashMap<FqNameUnsafe, PrimitiveType>(0);
165 for (PrimitiveType primitiveType : PrimitiveType.values()) {
166 fqNameToPrimitiveType.put(fqNameUnsafe(primitiveType.getTypeName().asString()), primitiveType);
167 arrayClassFqNameToPrimitiveType.put(fqNameUnsafe(primitiveType.getArrayTypeName().asString()), primitiveType);
168 }
169 }
170
171 @NotNull
172 private static FqNameUnsafe fqNameUnsafe(@NotNull String simpleName) {
173 return fqName(simpleName).toUnsafe();
174 }
175
176 @NotNull
177 private static FqName fqName(@NotNull String simpleName) {
178 return BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier(simpleName));
179 }
180
181 @NotNull
182 private static FqNameUnsafe reflect(@NotNull String simpleName) {
183 return ReflectionTypesKt.getKOTLIN_REFLECT_FQ_NAME().child(Name.identifier(simpleName)).toUnsafe();
184 }
185
186 @NotNull
187 private static FqName annotationName(@NotNull String simpleName) {
188 return ANNOTATION_PACKAGE_FQ_NAME.child(Name.identifier(simpleName));
189 }
190 }
191
192 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
193
194 @NotNull
195 public ModuleDescriptorImpl getBuiltInsModule() {
196 return builtInsModule;
197 }
198
199 @NotNull
200 public PackageFragmentDescriptor getBuiltInsPackageFragment() {
201 return builtinsPackageFragment;
202 }
203
204 @NotNull
205 public MemberScope getBuiltInsPackageScope() {
206 return builtinsPackageFragment.getMemberScope();
207 }
208
209 @NotNull
210 public MemberScope getAnnotationPackageScope() {
211 return annotationPackageFragment.getMemberScope();
212 }
213
214 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
215
216 // GET CLASS
217
218 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
219
220 @NotNull
221 public ClassDescriptor getAnnotationClassByName(@NotNull Name simpleName) {
222 ClassifierDescriptor classifier = annotationPackageFragment.getMemberScope().getContributedClassifier(simpleName,
223 NoLookupLocation.FROM_BUILTINS);
224 assert classifier instanceof ClassDescriptor : "Must be a class descriptor " + simpleName + ", but was " +
225 (classifier == null ? "null" : classifier.toString());
226 return (ClassDescriptor) classifier;
227 }
228
229 @NotNull
230 public ClassDescriptor getBuiltInClassByName(@NotNull Name simpleName) {
231 ClassDescriptor classDescriptor = getBuiltInClassByNameNullable(simpleName);
232 assert classDescriptor != null : "Must be a class descriptor " + simpleName + ", but was null";
233 return classDescriptor;
234 }
235
236 @Nullable
237 public ClassDescriptor getBuiltInClassByNameNullable(@NotNull Name simpleName) {
238 ClassifierDescriptor classifier = getBuiltInsPackageFragment().getMemberScope().getContributedClassifier(simpleName,
239 NoLookupLocation.FROM_BUILTINS);
240 assert classifier == null ||
241 classifier instanceof ClassDescriptor : "Must be a class descriptor " + simpleName + ", but was " + classifier;
242 return (ClassDescriptor) classifier;
243 }
244
245 @NotNull
246 private ClassDescriptor getBuiltInClassByName(@NotNull String simpleName) {
247 return getBuiltInClassByName(Name.identifier(simpleName));
248 }
249
250 // Special
251
252 @NotNull
253 public ClassDescriptor getAny() {
254 return getBuiltInClassByName("Any");
255 }
256
257 @NotNull
258 public ClassDescriptor getNothing() {
259 return getBuiltInClassByName("Nothing");
260 }
261
262 // Primitive
263
264 @NotNull
265 public ClassDescriptor getPrimitiveClassDescriptor(@NotNull PrimitiveType type) {
266 return getBuiltInClassByName(type.getTypeName().asString());
267 }
268
269 @NotNull
270 public ClassDescriptor getByte() {
271 return getPrimitiveClassDescriptor(BYTE);
272 }
273
274 @NotNull
275 public ClassDescriptor getShort() {
276 return getPrimitiveClassDescriptor(SHORT);
277 }
278
279 @NotNull
280 public ClassDescriptor getInt() {
281 return getPrimitiveClassDescriptor(INT);
282 }
283
284 @NotNull
285 public ClassDescriptor getLong() {
286 return getPrimitiveClassDescriptor(LONG);
287 }
288
289 @NotNull
290 public ClassDescriptor getFloat() {
291 return getPrimitiveClassDescriptor(FLOAT);
292 }
293
294 @NotNull
295 public ClassDescriptor getDouble() {
296 return getPrimitiveClassDescriptor(DOUBLE);
297 }
298
299 @NotNull
300 public ClassDescriptor getChar() {
301 return getPrimitiveClassDescriptor(CHAR);
302 }
303
304 @NotNull
305 public ClassDescriptor getBoolean() {
306 return getPrimitiveClassDescriptor(BOOLEAN);
307 }
308
309 // Recognized
310
311 @NotNull
312 public Set<DeclarationDescriptor> getIntegralRanges() {
313 return SetsKt.<DeclarationDescriptor>setOf(
314 getBuiltInClassByName("ByteRange"),
315 getBuiltInClassByName("ShortRange"),
316 getBuiltInClassByName("CharRange"),
317 getBuiltInClassByName("IntRange")
318 );
319 }
320
321 @NotNull
322 public ClassDescriptor getArray() {
323 return getBuiltInClassByName("Array");
324 }
325
326 @NotNull
327 public ClassDescriptor getPrimitiveArrayClassDescriptor(@NotNull PrimitiveType type) {
328 return getBuiltInClassByName(type.getArrayTypeName().asString());
329 }
330
331 @NotNull
332 public ClassDescriptor getNumber() {
333 return getBuiltInClassByName("Number");
334 }
335
336 @NotNull
337 public ClassDescriptor getUnit() {
338 return getBuiltInClassByName("Unit");
339 }
340
341 @NotNull
342 public static String getFunctionName(int parameterCount) {
343 return "Function" + parameterCount;
344 }
345
346 @NotNull
347 public static String getExtensionFunctionName(int parameterCount) {
348 return getFunctionName(parameterCount + 1);
349 }
350
351 @NotNull
352 public ClassDescriptor getFunction(int parameterCount) {
353 return getBuiltInClassByName(getFunctionName(parameterCount));
354 }
355
356 /**
357 * @return the descriptor representing the class kotlin.Function{parameterCount + 1}
358 * @deprecated there are no ExtensionFunction classes anymore, use {@link #getFunction(int)} instead
359 */
360 @Deprecated
361 @NotNull
362 public ClassDescriptor getExtensionFunction(int parameterCount) {
363 return getBuiltInClassByName(getExtensionFunctionName((parameterCount)));
364 }
365
366 @NotNull
367 public ClassDescriptor getThrowable() {
368 return getBuiltInClassByName("Throwable");
369 }
370
371 @NotNull
372 public ClassDescriptor getCloneable() {
373 return getBuiltInClassByName("Cloneable");
374 }
375
376 @NotNull
377 public ClassDescriptor getDeprecatedAnnotation() {
378 return getBuiltInClassByName(FQ_NAMES.deprecated.shortName());
379 }
380
381 @NotNull
382 public ClassDescriptor getTargetAnnotation() {
383 return getAnnotationClassByName(FQ_NAMES.target.shortName());
384 }
385
386 @NotNull
387 public ClassDescriptor getRetentionAnnotation() {
388 return getAnnotationClassByName(FQ_NAMES.retention.shortName());
389 }
390
391 @NotNull
392 public ClassDescriptor getRepeatableAnnotation() {
393 return getAnnotationClassByName(FQ_NAMES.repeatable.shortName());
394 }
395
396 @NotNull
397 public ClassDescriptor getMustBeDocumentedAnnotation() {
398 return getAnnotationClassByName(FQ_NAMES.mustBeDocumented.shortName());
399 }
400
401 @NotNull
402 public ClassDescriptor getAnnotationTargetEnum() {
403 return getAnnotationClassByName(FQ_NAMES.annotationTarget.shortName());
404 }
405
406 @Nullable
407 public ClassDescriptor getAnnotationTargetEnumEntry(@NotNull KotlinTarget target) {
408 ClassifierDescriptor result = getAnnotationTargetEnum().getUnsubstitutedInnerClassesScope().getContributedClassifier(
409 Name.identifier(target.name()), NoLookupLocation.FROM_BUILTINS
410 );
411 return result instanceof ClassDescriptor ? (ClassDescriptor) result : null;
412 }
413
414 @NotNull
415 public ClassDescriptor getAnnotationRetentionEnum() {
416 return getAnnotationClassByName(FQ_NAMES.annotationRetention.shortName());
417 }
418
419 @Nullable
420 public ClassDescriptor getAnnotationRetentionEnumEntry(@NotNull KotlinRetention retention) {
421 ClassifierDescriptor result = getAnnotationRetentionEnum().getUnsubstitutedInnerClassesScope().getContributedClassifier(
422 Name.identifier(retention.name()), NoLookupLocation.FROM_BUILTINS
423 );
424 return result instanceof ClassDescriptor ? (ClassDescriptor) result : null;
425 }
426
427 @NotNull
428 public ClassDescriptor getString() {
429 return getBuiltInClassByName("String");
430 }
431
432 @NotNull
433 public ClassDescriptor getCharSequence() {
434 return getBuiltInClassByName("CharSequence");
435 }
436
437 @NotNull
438 public ClassDescriptor getComparable() {
439 return getBuiltInClassByName("Comparable");
440 }
441
442 @NotNull
443 public ClassDescriptor getEnum() {
444 return getBuiltInClassByName("Enum");
445 }
446
447 @NotNull
448 public ClassDescriptor getAnnotation() {
449 return getBuiltInClassByName("Annotation");
450 }
451
452 @NotNull
453 public ClassDescriptor getIterator() {
454 return getBuiltInClassByName("Iterator");
455 }
456
457 @NotNull
458 public ClassDescriptor getIterable() {
459 return getBuiltInClassByName("Iterable");
460 }
461
462 @NotNull
463 public ClassDescriptor getMutableIterable() {
464 return getBuiltInClassByName("MutableIterable");
465 }
466
467 @NotNull
468 public ClassDescriptor getMutableIterator() {
469 return getBuiltInClassByName("MutableIterator");
470 }
471
472 @NotNull
473 public ClassDescriptor getCollection() {
474 return getBuiltInClassByName("Collection");
475 }
476
477 @NotNull
478 public ClassDescriptor getMutableCollection() {
479 return getBuiltInClassByName("MutableCollection");
480 }
481
482 @NotNull
483 public ClassDescriptor getList() {
484 return getBuiltInClassByName("List");
485 }
486
487 @NotNull
488 public ClassDescriptor getMutableList() {
489 return getBuiltInClassByName("MutableList");
490 }
491
492 @NotNull
493 public ClassDescriptor getSet() {
494 return getBuiltInClassByName("Set");
495 }
496
497 @NotNull
498 public ClassDescriptor getMutableSet() {
499 return getBuiltInClassByName("MutableSet");
500 }
501
502 @NotNull
503 public ClassDescriptor getMap() {
504 return getBuiltInClassByName("Map");
505 }
506
507 @NotNull
508 public ClassDescriptor getMutableMap() {
509 return getBuiltInClassByName("MutableMap");
510 }
511
512 @NotNull
513 public ClassDescriptor getMapEntry() {
514 ClassDescriptor classDescriptor = DescriptorUtils.getInnerClassByName(getMap(), "Entry", NoLookupLocation.FROM_BUILTINS);
515 assert classDescriptor != null : "Can't find Map.Entry";
516 return classDescriptor;
517 }
518
519 @NotNull
520 public ClassDescriptor getMutableMapEntry() {
521 ClassDescriptor classDescriptor = DescriptorUtils.getInnerClassByName(getMutableMap(), "MutableEntry", NoLookupLocation.FROM_BUILTINS);
522 assert classDescriptor != null : "Can't find MutableMap.MutableEntry";
523 return classDescriptor;
524 }
525
526 @NotNull
527 public ClassDescriptor getListIterator() {
528 return getBuiltInClassByName("ListIterator");
529 }
530
531 @NotNull
532 public ClassDescriptor getMutableListIterator() {
533 return getBuiltInClassByName("MutableListIterator");
534 }
535
536 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
537
538 // GET TYPE
539
540 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
541
542 @NotNull
543 private KotlinType getBuiltInTypeByClassName(@NotNull String classSimpleName) {
544 return getBuiltInClassByName(classSimpleName).getDefaultType();
545 }
546
547 // Special
548
549 @NotNull
550 public KotlinType getNothingType() {
551 return getNothing().getDefaultType();
552 }
553
554 @NotNull
555 public KotlinType getNullableNothingType() {
556 return TypeUtils.makeNullable(getNothingType());
557 }
558
559 @NotNull
560 public KotlinType getAnyType() {
561 return getAny().getDefaultType();
562 }
563
564 @NotNull
565 public KotlinType getNullableAnyType() {
566 return TypeUtils.makeNullable(getAnyType());
567 }
568
569 // Primitive
570
571 @NotNull
572 public KotlinType getPrimitiveKotlinType(@NotNull PrimitiveType type) {
573 return getPrimitiveClassDescriptor(type).getDefaultType();
574 }
575
576 @NotNull
577 public KotlinType getByteType() {
578 return getPrimitiveKotlinType(BYTE);
579 }
580
581 @NotNull
582 public KotlinType getShortType() {
583 return getPrimitiveKotlinType(SHORT);
584 }
585
586 @NotNull
587 public KotlinType getIntType() {
588 return getPrimitiveKotlinType(INT);
589 }
590
591 @NotNull
592 public KotlinType getLongType() {
593 return getPrimitiveKotlinType(LONG);
594 }
595
596 @NotNull
597 public KotlinType getFloatType() {
598 return getPrimitiveKotlinType(FLOAT);
599 }
600
601 @NotNull
602 public KotlinType getDoubleType() {
603 return getPrimitiveKotlinType(DOUBLE);
604 }
605
606 @NotNull
607 public KotlinType getCharType() {
608 return getPrimitiveKotlinType(CHAR);
609 }
610
611 @NotNull
612 public KotlinType getBooleanType() {
613 return getPrimitiveKotlinType(BOOLEAN);
614 }
615
616 // Recognized
617
618 @NotNull
619 public KotlinType getUnitType() {
620 return getUnit().getDefaultType();
621 }
622
623 @NotNull
624 public KotlinType getStringType() {
625 return getString().getDefaultType();
626 }
627
628 @NotNull
629 public KotlinType getArrayElementType(@NotNull KotlinType arrayType) {
630 if (isArray(arrayType)) {
631 if (arrayType.getArguments().size() != 1) {
632 throw new IllegalStateException();
633 }
634 return arrayType.getArguments().get(0).getType();
635 }
636 KotlinType primitiveType = kotlinArrayTypeToPrimitiveKotlinType.get(TypeUtils.makeNotNullable(arrayType));
637 if (primitiveType == null) {
638 throw new IllegalStateException("not array: " + arrayType);
639 }
640 return primitiveType;
641 }
642
643 @NotNull
644 public KotlinType getPrimitiveArrayKotlinType(@NotNull PrimitiveType primitiveType) {
645 return primitiveTypeToArrayKotlinType.get(primitiveType);
646 }
647
648 /**
649 * @return {@code null} if not primitive
650 */
651 @Nullable
652 public KotlinType getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(@NotNull KotlinType kotlinType) {
653 return primitiveKotlinTypeToKotlinArrayType.get(kotlinType);
654 }
655
656 public static boolean isPrimitiveArray(@NotNull FqNameUnsafe arrayFqName) {
657 return getPrimitiveTypeByArrayClassFqName(arrayFqName) != null;
658 }
659
660 @Nullable
661 public static PrimitiveType getPrimitiveTypeByFqName(@NotNull FqNameUnsafe primitiveClassFqName) {
662 return FQ_NAMES.fqNameToPrimitiveType.get(primitiveClassFqName);
663 }
664
665 @Nullable
666 public static PrimitiveType getPrimitiveTypeByArrayClassFqName(@NotNull FqNameUnsafe primitiveArrayClassFqName) {
667 return FQ_NAMES.arrayClassFqNameToPrimitiveType.get(primitiveArrayClassFqName);
668 }
669
670 @NotNull
671 public KotlinType getArrayType(@NotNull Variance projectionType, @NotNull KotlinType argument) {
672 List<TypeProjectionImpl> types = Collections.singletonList(new TypeProjectionImpl(projectionType, argument));
673 return KotlinTypeImpl.create(
674 Annotations.Companion.getEMPTY(),
675 getArray(),
676 false,
677 types
678 );
679 }
680
681 @NotNull
682 public KotlinType getEnumType(@NotNull KotlinType argument) {
683 Variance projectionType = Variance.INVARIANT;
684 List<TypeProjectionImpl> types = Collections.singletonList(new TypeProjectionImpl(projectionType, argument));
685 return KotlinTypeImpl.create(
686 Annotations.Companion.getEMPTY(),
687 getEnum(),
688 false,
689 types
690 );
691 }
692
693 @NotNull
694 public KotlinType getAnnotationType() {
695 return getAnnotation().getDefaultType();
696 }
697
698 @NotNull
699 public AnnotationDescriptor createExtensionAnnotation() {
700 return new AnnotationDescriptorImpl(getBuiltInClassByName(FQ_NAMES.extension.shortName()).getDefaultType(),
701 Collections.<ValueParameterDescriptor, ConstantValue<?>>emptyMap(), SourceElement.NO_SOURCE);
702 }
703
704 private static boolean isTypeAnnotatedWithExtension(@NotNull KotlinType type) {
705 return type.getAnnotations().findAnnotation(FQ_NAMES.extension) != null;
706 }
707
708 @NotNull
709 public KotlinType getFunctionType(
710 @NotNull Annotations annotations,
711 @Nullable KotlinType receiverType,
712 @NotNull List<KotlinType> parameterTypes,
713 @NotNull KotlinType returnType
714 ) {
715 List<TypeProjection> arguments = getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType);
716 int size = parameterTypes.size();
717 ClassDescriptor classDescriptor = receiverType == null ? getFunction(size) : getExtensionFunction(size);
718
719 Annotations typeAnnotations = receiverType == null ? annotations : addExtensionAnnotation(annotations);
720
721 return KotlinTypeImpl.create(typeAnnotations, classDescriptor, false, arguments);
722 }
723
724 @NotNull
725 private Annotations addExtensionAnnotation(@NotNull Annotations annotations) {
726 if (annotations.findAnnotation(FQ_NAMES.extension) != null) return annotations;
727
728 // TODO: preserve laziness of given annotations
729 return new AnnotationsImpl(plus(annotations, listOf(createExtensionAnnotation())));
730 }
731
732 @NotNull
733 public static List<TypeProjection> getFunctionTypeArgumentProjections(
734 @Nullable KotlinType receiverType,
735 @NotNull List<KotlinType> parameterTypes,
736 @NotNull KotlinType returnType
737 ) {
738 List<TypeProjection> arguments = new ArrayList<TypeProjection>(parameterTypes.size() + (receiverType != null ? 1 : 0) + 1);
739 if (receiverType != null) {
740 arguments.add(defaultProjection(receiverType));
741 }
742 for (KotlinType parameterType : parameterTypes) {
743 arguments.add(defaultProjection(parameterType));
744 }
745 arguments.add(defaultProjection(returnType));
746 return arguments;
747 }
748
749 private static TypeProjection defaultProjection(KotlinType returnType) {
750 return new TypeProjectionImpl(Variance.INVARIANT, returnType);
751 }
752
753 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
754
755 // IS TYPE
756
757 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
758
759 public static boolean isArray(@NotNull KotlinType type) {
760 return isConstructedFromGivenClass(type, FQ_NAMES.array);
761 }
762
763 public static boolean isPrimitiveArray(@NotNull KotlinType type) {
764 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
765 return descriptor != null && getPrimitiveTypeByArrayClassFqName(getFqName(descriptor)) != null;
766 }
767
768 public static boolean isPrimitiveType(@NotNull KotlinType type) {
769 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
770 return !type.isMarkedNullable() && descriptor instanceof ClassDescriptor && isPrimitiveClass((ClassDescriptor) descriptor);
771 }
772
773 public static boolean isPrimitiveClass(@NotNull ClassDescriptor descriptor) {
774 return getPrimitiveTypeByFqName(getFqName(descriptor)) != null;
775 }
776
777 // Functions
778
779 public static boolean isFunctionOrExtensionFunctionType(@NotNull KotlinType type) {
780 return isFunctionType(type) || isExtensionFunctionType(type);
781 }
782
783 public static boolean isFunctionType(@NotNull KotlinType type) {
784 if (isExactFunctionType(type)) return true;
785
786 for (KotlinType superType : type.getConstructor().getSupertypes()) {
787 if (isFunctionType(superType)) return true;
788 }
789
790 return false;
791 }
792
793 public static boolean isExtensionFunctionType(@NotNull KotlinType type) {
794 if (isExactExtensionFunctionType(type)) return true;
795
796 for (KotlinType superType : type.getConstructor().getSupertypes()) {
797 if (isExtensionFunctionType(superType)) return true;
798 }
799
800 return false;
801 }
802
803 public static boolean isExactFunctionOrExtensionFunctionType(@NotNull KotlinType type) {
804 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
805 return descriptor != null && isNumberedFunctionClassFqName(getFqName(descriptor));
806 }
807
808 public static boolean isExactFunctionType(@NotNull KotlinType type) {
809 return isExactFunctionOrExtensionFunctionType(type) && !isTypeAnnotatedWithExtension(type);
810 }
811
812 public static boolean isExactExtensionFunctionType(@NotNull KotlinType type) {
813 return isExactFunctionOrExtensionFunctionType(type) && isTypeAnnotatedWithExtension(type);
814 }
815
816 /**
817 * @return true if this is an FQ name of a fictitious class representing the function type,
818 * e.g. kotlin.Function1 (but NOT kotlin.reflect.KFunction1)
819 */
820 public static boolean isNumberedFunctionClassFqName(@NotNull FqNameUnsafe fqName) {
821 List<Name> segments = fqName.pathSegments();
822 if (segments.size() != 2) return false;
823
824 if (!BUILT_INS_PACKAGE_NAME.equals(first(segments))) return false;
825
826 String shortName = last(segments).asString();
827 return BuiltInFictitiousFunctionClassFactory.parseClassName(shortName, BUILT_INS_PACKAGE_FQ_NAME) != null;
828 }
829
830 @Nullable
831 public static KotlinType getReceiverType(@NotNull KotlinType type) {
832 assert isFunctionOrExtensionFunctionType(type) : type;
833 if (isExtensionFunctionType(type)) {
834 // TODO: this is incorrect when a class extends from an extension function and swaps type arguments
835 return type.getArguments().get(0).getType();
836 }
837 return null;
838 }
839
840 @NotNull
841 public static List<ValueParameterDescriptor> getValueParameters(@NotNull FunctionDescriptor functionDescriptor, @NotNull KotlinType type) {
842 assert isFunctionOrExtensionFunctionType(type);
843 List<TypeProjection> parameterTypes = getParameterTypeProjectionsFromFunctionType(type);
844 List<ValueParameterDescriptor> valueParameters = new ArrayList<ValueParameterDescriptor>(parameterTypes.size());
845 for (int i = 0; i < parameterTypes.size(); i++) {
846 TypeProjection parameterType = parameterTypes.get(i);
847 ValueParameterDescriptorImpl valueParameterDescriptor = new ValueParameterDescriptorImpl(
848 functionDescriptor, null, i, Annotations.Companion.getEMPTY(),
849 Name.identifier("p" + (i + 1)), parameterType.getType(),
850 /* declaresDefaultValue = */ false,
851 /* isCrossinline = */ false,
852 /* isNoinline = */ false,
853 null, SourceElement.NO_SOURCE
854 );
855 valueParameters.add(valueParameterDescriptor);
856 }
857 return valueParameters;
858 }
859
860 @NotNull
861 public static KotlinType getReturnTypeFromFunctionType(@NotNull KotlinType type) {
862 assert isFunctionOrExtensionFunctionType(type);
863 List<TypeProjection> arguments = type.getArguments();
864 return arguments.get(arguments.size() - 1).getType();
865 }
866
867 @NotNull
868 public static List<TypeProjection> getParameterTypeProjectionsFromFunctionType(@NotNull KotlinType type) {
869 assert isFunctionOrExtensionFunctionType(type);
870 List<TypeProjection> arguments = type.getArguments();
871 int first = isExtensionFunctionType(type) ? 1 : 0;
872 int last = arguments.size() - 2;
873 // TODO: fix bugs associated with this here and in neighboring methods, see KT-9820
874 assert first <= last + 1 : "Not an exact function type: " + type;
875 List<TypeProjection> parameterTypes = new ArrayList<TypeProjection>(last - first + 1);
876 for (int i = first; i <= last; i++) {
877 parameterTypes.add(arguments.get(i));
878 }
879 return parameterTypes;
880 }
881
882 // Recognized & special
883
884 private static boolean isConstructedFromGivenClass(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) {
885 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
886 return descriptor != null &&
887 /* quick check to avoid creation of full FqName instance */ descriptor.getName().equals(fqName.shortName()) &&
888 fqName.equals(getFqName(descriptor));
889 }
890
891 private static boolean isNotNullConstructedFromGivenClass(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) {
892 return !type.isMarkedNullable() && isConstructedFromGivenClass(type, fqName);
893 }
894
895 public static boolean isSpecialClassWithNoSupertypes(@NotNull ClassDescriptor descriptor) {
896 FqNameUnsafe fqName = getFqName(descriptor);
897 return FQ_NAMES.any.equals(fqName) || FQ_NAMES.nothing.equals(fqName);
898 }
899
900 public static boolean isAny(@NotNull ClassDescriptor descriptor) {
901 return isAny(getFqName(descriptor));
902 }
903
904 public static boolean isAny(@NotNull KotlinType type) {
905 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES.any);
906 }
907
908 public static boolean isBoolean(@NotNull KotlinType type) {
909
910 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._boolean);
911 }
912
913 public static boolean isBooleanOrNullableBoolean(@NotNull KotlinType type) {
914 return isConstructedFromGivenClass(type, FQ_NAMES._boolean);
915 }
916
917 public static boolean isBoolean(@NotNull ClassDescriptor classDescriptor) {
918 return FQ_NAMES._boolean.equals(getFqName(classDescriptor));
919 }
920
921 public static boolean isChar(@NotNull KotlinType type) {
922 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._char);
923 }
924
925 public static boolean isInt(@NotNull KotlinType type) {
926 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._int);
927 }
928
929 public static boolean isByte(@NotNull KotlinType type) {
930 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._byte);
931 }
932
933 public static boolean isLong(@NotNull KotlinType type) {
934 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._long);
935 }
936
937 public static boolean isShort(@NotNull KotlinType type) {
938 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._short);
939 }
940
941 public static boolean isFloat(@NotNull KotlinType type) {
942 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._float);
943 }
944
945 public static boolean isDouble(@NotNull KotlinType type) {
946 return isConstructedFromGivenClassAndNotNullable(type, FQ_NAMES._double);
947 }
948
949 private static boolean isConstructedFromGivenClassAndNotNullable(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) {
950 return isConstructedFromGivenClass(type, fqName) && !type.isMarkedNullable();
951 }
952
953 public static boolean isAny(@NotNull FqNameUnsafe fqName) {
954 return FQ_NAMES.any.equals(fqName);
955 }
956
957 public static boolean isNothing(@NotNull KotlinType type) {
958 return isNothingOrNullableNothing(type)
959 && !type.isMarkedNullable();
960 }
961
962 public static boolean isNullableNothing(@NotNull KotlinType type) {
963 return isNothingOrNullableNothing(type)
964 && type.isMarkedNullable();
965 }
966
967 public static boolean isNothingOrNullableNothing(@NotNull KotlinType type) {
968 return isConstructedFromGivenClass(type, FQ_NAMES.nothing);
969 }
970
971 public static boolean isAnyOrNullableAny(@NotNull KotlinType type) {
972 return isConstructedFromGivenClass(type, FQ_NAMES.any);
973 }
974
975 public static boolean isNullableAny(@NotNull KotlinType type) {
976 return isAnyOrNullableAny(type) && type.isMarkedNullable();
977 }
978
979 public static boolean isDefaultBound(@NotNull KotlinType type) {
980 return isNullableAny(type);
981 }
982
983 public static boolean isUnit(@NotNull KotlinType type) {
984 return isNotNullConstructedFromGivenClass(type, FQ_NAMES.unit);
985 }
986
987 public boolean isBooleanOrSubtype(@NotNull KotlinType type) {
988 return KotlinTypeChecker.DEFAULT.isSubtypeOf(type, getBooleanType());
989 }
990
991 public boolean isMemberOfAny(@NotNull DeclarationDescriptor descriptor) {
992 return descriptor.getContainingDeclaration() == getAny();
993 }
994
995 public static boolean isString(@Nullable KotlinType type) {
996 return type != null && isNotNullConstructedFromGivenClass(type, FQ_NAMES.string);
997 }
998
999 public static boolean isCollectionOrNullableCollection(@NotNull KotlinType type) {
1000 return isConstructedFromGivenClass(type, FQ_NAMES._collection);
1001 }
1002
1003 public static boolean isListOrNullableList(@NotNull KotlinType type) {
1004 return isConstructedFromGivenClass(type, FQ_NAMES._list);
1005 }
1006
1007 public static boolean isSetOrNullableSet(@NotNull KotlinType type) {
1008 return isConstructedFromGivenClass(type, FQ_NAMES._set);
1009 }
1010
1011 public static boolean isIterableOrNullableIterable(@NotNull KotlinType type) {
1012 return isConstructedFromGivenClass(type, FQ_NAMES._iterable);
1013 }
1014
1015 public static boolean isKClass(@NotNull ClassDescriptor descriptor) {
1016 return FQ_NAMES.kClass.equals(getFqName(descriptor));
1017 }
1018
1019 public static boolean isNonPrimitiveArray(@NotNull ClassDescriptor descriptor) {
1020 return FQ_NAMES.array.equals(getFqName(descriptor));
1021 }
1022
1023 public static boolean isCloneable(@NotNull ClassDescriptor descriptor) {
1024 return FQ_NAMES.cloneable.equals(getFqName(descriptor));
1025 }
1026
1027 public static boolean isDeprecated(@NotNull DeclarationDescriptor declarationDescriptor) {
1028 if (containsAnnotation(declarationDescriptor, FQ_NAMES.deprecated)) return true;
1029
1030 if (declarationDescriptor instanceof PropertyDescriptor) {
1031 boolean isVar = ((PropertyDescriptor) declarationDescriptor).isVar();
1032 PropertyGetterDescriptor getter = ((PropertyDescriptor) declarationDescriptor).getGetter();
1033 PropertySetterDescriptor setter = ((PropertyDescriptor) declarationDescriptor).getSetter();
1034 return getter != null && isDeprecated(getter) && (!isVar || setter != null && isDeprecated(setter));
1035 }
1036
1037 return false;
1038 }
1039
1040 public static boolean isSuppressAnnotation(@NotNull AnnotationDescriptor annotationDescriptor) {
1041 return isConstructedFromGivenClass(annotationDescriptor.getType(), FQ_NAMES.suppress);
1042 }
1043
1044 private static boolean containsAnnotation(DeclarationDescriptor descriptor, FqName annotationClassFqName) {
1045 DeclarationDescriptor original = descriptor.getOriginal();
1046 Annotations annotations = original.getAnnotations();
1047
1048 if (annotations.findAnnotation(annotationClassFqName) != null) return true;
1049
1050 AnnotationUseSiteTarget associatedUseSiteTarget = AnnotationUseSiteTarget.Companion.getAssociatedUseSiteTarget(descriptor);
1051 if (associatedUseSiteTarget != null) {
1052 if (Annotations.Companion.findUseSiteTargetedAnnotation(annotations, associatedUseSiteTarget, annotationClassFqName) != null) {
1053 return true;
1054 }
1055 }
1056
1057 return false;
1058 }
1059
1060 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1061
1062 @NotNull
1063 public KotlinType getDefaultBound() {
1064 return getNullableAnyType();
1065 }
1066
1067 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1068
1069 // GET FUNCTION
1070
1071 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1072
1073 @NotNull
1074 public FunctionDescriptor getIdentityEquals() {
1075 return first(getBuiltInsPackageFragment().getMemberScope().getContributedFunctions(Name.identifier("identityEquals"),
1076 NoLookupLocation.FROM_BUILTINS));
1077 }
1078 }