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.types;
018
019 import kotlin.CollectionsKt;
020 import kotlin.jvm.functions.Function1;
021 import org.jetbrains.annotations.NotNull;
022 import org.jetbrains.annotations.Nullable;
023 import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
024 import org.jetbrains.kotlin.descriptors.ClassDescriptor;
025 import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
026 import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
027 import org.jetbrains.kotlin.descriptors.annotations.Annotations;
028 import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor;
029 import org.jetbrains.kotlin.resolve.scopes.KtScope;
030 import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
031 import org.jetbrains.kotlin.utils.DFS;
032
033 import java.util.*;
034
035 public class TypeUtils {
036 public static final KotlinType DONT_CARE = ErrorUtils.createErrorTypeWithCustomDebugName("DONT_CARE");
037 public static final KotlinType PLACEHOLDER_FUNCTION_TYPE = ErrorUtils.createErrorTypeWithCustomDebugName("PLACEHOLDER_FUNCTION_TYPE");
038
039 public static final KotlinType CANT_INFER_FUNCTION_PARAM_TYPE = ErrorUtils.createErrorType("Cannot be inferred");
040
041 public static class SpecialType implements KotlinType {
042 private final String name;
043
044 public SpecialType(String name) {
045 this.name = name;
046 }
047
048 @NotNull
049 @Override
050 public TypeConstructor getConstructor() {
051 throw new IllegalStateException(name);
052 }
053
054 @NotNull
055 @Override
056 public List<TypeProjection> getArguments() {
057 throw new IllegalStateException(name);
058 }
059
060 @NotNull
061 @Override
062 public TypeSubstitution getSubstitution() {
063 throw new IllegalStateException(name);
064 }
065
066 @Override
067 public boolean isMarkedNullable() {
068 throw new IllegalStateException(name);
069 }
070
071 @NotNull
072 @Override
073 public KtScope getMemberScope() {
074 throw new IllegalStateException(name);
075 }
076
077 @Override
078 public boolean isError() {
079 return false;
080 }
081
082 @NotNull
083 @Override
084 public Annotations getAnnotations() {
085 throw new IllegalStateException(name);
086 }
087
088 @Nullable
089 @Override
090 public <T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass) {
091 return null;
092 }
093
094 @NotNull
095 @Override
096 public TypeCapabilities getCapabilities() {
097 return TypeCapabilities.NONE.INSTANCE;
098 }
099
100 @Override
101 public String toString() {
102 return name;
103 }
104 }
105
106 @NotNull
107 public static final KotlinType NO_EXPECTED_TYPE = new SpecialType("NO_EXPECTED_TYPE");
108
109 public static final KotlinType UNIT_EXPECTED_TYPE = new SpecialType("UNIT_EXPECTED_TYPE");
110
111 public static boolean noExpectedType(@NotNull KotlinType type) {
112 return type == NO_EXPECTED_TYPE || type == UNIT_EXPECTED_TYPE;
113 }
114
115 public static boolean isDontCarePlaceholder(@Nullable KotlinType type) {
116 return type != null && type.getConstructor() == DONT_CARE.getConstructor();
117 }
118
119 @NotNull
120 public static KotlinType makeNullable(@NotNull KotlinType type) {
121 return makeNullableAsSpecified(type, true);
122 }
123
124 @NotNull
125 public static KotlinType makeNotNullable(@NotNull KotlinType type) {
126 return makeNullableAsSpecified(type, false);
127 }
128
129 @NotNull
130 public static KotlinType makeNullableAsSpecified(@NotNull KotlinType type, boolean nullable) {
131 NullAwareness nullAwareness = type.getCapability(NullAwareness.class);
132 if (nullAwareness != null) {
133 return nullAwareness.makeNullableAsSpecified(nullable);
134 }
135
136 // Wrapping serves two purposes here
137 // 1. It's requires less memory than copying with a changed nullability flag: a copy has many fields, while a wrapper has only one
138 // 2. It preserves laziness of types
139
140 // Unwrap to avoid long delegation call chains
141 if (type instanceof AbstractTypeWithKnownNullability) {
142 return makeNullableAsSpecified(((AbstractTypeWithKnownNullability) type).delegate, nullable);
143 }
144
145 // checking to preserve laziness
146 if (!(type instanceof LazyType) && type.isMarkedNullable() == nullable) {
147 return type;
148 }
149
150 return nullable ? new NullableType(type) : new NotNullType(type);
151 }
152
153 @NotNull
154 public static KotlinType makeNullableIfNeeded(@NotNull KotlinType type, boolean nullable) {
155 if (nullable) {
156 return makeNullable(type);
157 }
158 return type;
159 }
160
161 public static boolean canHaveSubtypes(KotlinTypeChecker typeChecker, @NotNull KotlinType type) {
162 if (type.isMarkedNullable()) {
163 return true;
164 }
165 if (!type.getConstructor().isFinal()) {
166 return true;
167 }
168
169 List<TypeParameterDescriptor> parameters = type.getConstructor().getParameters();
170 List<TypeProjection> arguments = type.getArguments();
171 for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) {
172 TypeParameterDescriptor parameterDescriptor = parameters.get(i);
173 TypeProjection typeProjection = arguments.get(i);
174 Variance projectionKind = typeProjection.getProjectionKind();
175 KotlinType argument = typeProjection.getType();
176
177 switch (parameterDescriptor.getVariance()) {
178 case INVARIANT:
179 switch (projectionKind) {
180 case INVARIANT:
181 if (lowerThanBound(typeChecker, argument, parameterDescriptor) || canHaveSubtypes(typeChecker, argument)) {
182 return true;
183 }
184 break;
185 case IN_VARIANCE:
186 if (lowerThanBound(typeChecker, argument, parameterDescriptor)) {
187 return true;
188 }
189 break;
190 case OUT_VARIANCE:
191 if (canHaveSubtypes(typeChecker, argument)) {
192 return true;
193 }
194 break;
195 }
196 break;
197 case IN_VARIANCE:
198 if (projectionKind != Variance.OUT_VARIANCE) {
199 if (lowerThanBound(typeChecker, argument, parameterDescriptor)) {
200 return true;
201 }
202 }
203 else {
204 if (canHaveSubtypes(typeChecker, argument)) {
205 return true;
206 }
207 }
208 break;
209 case OUT_VARIANCE:
210 if (projectionKind != Variance.IN_VARIANCE) {
211 if (canHaveSubtypes(typeChecker, argument)) {
212 return true;
213 }
214 }
215 else {
216 if (lowerThanBound(typeChecker, argument, parameterDescriptor)) {
217 return true;
218 }
219 }
220 break;
221 }
222 }
223 return false;
224 }
225
226 private static boolean lowerThanBound(KotlinTypeChecker typeChecker, KotlinType argument, TypeParameterDescriptor parameterDescriptor) {
227 for (KotlinType bound : parameterDescriptor.getUpperBounds()) {
228 if (typeChecker.isSubtypeOf(argument, bound)) {
229 if (!argument.getConstructor().equals(bound.getConstructor())) {
230 return true;
231 }
232 }
233 }
234 return false;
235 }
236
237 @NotNull
238 public static KotlinType makeUnsubstitutedType(ClassDescriptor classDescriptor, KtScope unsubstitutedMemberScope) {
239 if (ErrorUtils.isError(classDescriptor)) {
240 return ErrorUtils.createErrorType("Unsubstituted type for " + classDescriptor);
241 }
242 TypeConstructor typeConstructor = classDescriptor.getTypeConstructor();
243 List<TypeProjection> arguments = getDefaultTypeProjections(typeConstructor.getParameters());
244 return KotlinTypeImpl.create(
245 Annotations.Companion.getEMPTY(),
246 typeConstructor,
247 false,
248 arguments,
249 unsubstitutedMemberScope
250 );
251 }
252
253 @NotNull
254 public static List<TypeProjection> getDefaultTypeProjections(@NotNull List<TypeParameterDescriptor> parameters) {
255 List<TypeProjection> result = new ArrayList<TypeProjection>(parameters.size());
256 for (TypeParameterDescriptor parameterDescriptor : parameters) {
257 result.add(new TypeProjectionImpl(parameterDescriptor.getDefaultType()));
258 }
259 return org.jetbrains.kotlin.utils.CollectionsKt.toReadOnlyList(result);
260 }
261
262 @NotNull
263 public static List<KotlinType> getImmediateSupertypes(@NotNull KotlinType type) {
264 boolean isNullable = type.isMarkedNullable();
265 TypeSubstitutor substitutor = TypeSubstitutor.create(type);
266 Collection<KotlinType> originalSupertypes = type.getConstructor().getSupertypes();
267 List<KotlinType> result = new ArrayList<KotlinType>(originalSupertypes.size());
268 for (KotlinType supertype : originalSupertypes) {
269 KotlinType substitutedType = substitutor.substitute(supertype, Variance.INVARIANT);
270 if (substitutedType != null) {
271 result.add(makeNullableIfNeeded(substitutedType, isNullable));
272 }
273 }
274 return result;
275 }
276
277 private static void collectAllSupertypes(@NotNull KotlinType type, @NotNull Set<KotlinType> result) {
278 List<KotlinType> immediateSupertypes = getImmediateSupertypes(type);
279 result.addAll(immediateSupertypes);
280 for (KotlinType supertype : immediateSupertypes) {
281 collectAllSupertypes(supertype, result);
282 }
283 }
284
285
286 @NotNull
287 public static Set<KotlinType> getAllSupertypes(@NotNull KotlinType type) {
288 // 15 is obtained by experimentation: JDK classes like ArrayList tend to have so many supertypes,
289 // the average number is lower
290 Set<KotlinType> result = new LinkedHashSet<KotlinType>(15);
291 collectAllSupertypes(type, result);
292 return result;
293 }
294
295 public static boolean hasNullableLowerBound(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
296 for (KotlinType bound : typeParameterDescriptor.getLowerBounds()) {
297 if (bound.isMarkedNullable()) {
298 return true;
299 }
300 }
301 return false;
302 }
303
304 /**
305 * A work-around of the generic nullability problem in the type checker
306 * Semantics should be the same as `!isSubtype(T, Any)`
307 * @return true if a value of this type can be null
308 */
309 public static boolean isNullableType(@NotNull KotlinType type) {
310 if (type.isMarkedNullable()) {
311 return true;
312 }
313 if (FlexibleTypesKt.isFlexible(type) && isNullableType(FlexibleTypesKt.flexibility(type).getUpperBound())) {
314 return true;
315 }
316 if (isTypeParameter(type)) {
317 return hasNullableSuperType(type);
318 }
319 return false;
320 }
321
322 /**
323 * Differs from `isNullableType` only by treating type parameters: acceptsNullable(T) <=> T has nullable lower bound
324 * Semantics should be the same as `isSubtype(Nothing?, T)`
325 * @return true if `null` can be assigned to storage of this type
326 */
327 public static boolean acceptsNullable(@NotNull KotlinType type) {
328 if (type.isMarkedNullable()) {
329 return true;
330 }
331 if (FlexibleTypesKt.isFlexible(type) && acceptsNullable(FlexibleTypesKt.flexibility(type).getUpperBound())) {
332 return true;
333 }
334 if (isTypeParameter(type)) {
335 return hasNullableLowerBound((TypeParameterDescriptor) type.getConstructor().getDeclarationDescriptor());
336 }
337 return false;
338 }
339
340 public static boolean hasNullableSuperType(@NotNull KotlinType type) {
341 if (type.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) {
342 // A class/trait cannot have a nullable supertype
343 return false;
344 }
345
346 for (KotlinType supertype : getImmediateSupertypes(type)) {
347 if (supertype.isMarkedNullable()) return true;
348 if (hasNullableSuperType(supertype)) return true;
349 }
350
351 return false;
352 }
353
354 @Nullable
355 public static ClassDescriptor getClassDescriptor(@NotNull KotlinType type) {
356 DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
357 if (declarationDescriptor instanceof ClassDescriptor) {
358 return (ClassDescriptor) declarationDescriptor;
359 }
360 return null;
361 }
362
363 @NotNull
364 public static KotlinType substituteParameters(@NotNull ClassDescriptor clazz, @NotNull List<KotlinType> typeArguments) {
365 List<TypeProjection> projections = CollectionsKt.map(typeArguments, new Function1<KotlinType, TypeProjection>() {
366 @Override
367 public TypeProjection invoke(KotlinType type) {
368 return new TypeProjectionImpl(type);
369 }
370 });
371
372 return substituteProjectionsForParameters(clazz, projections);
373 }
374
375 @NotNull
376 public static KotlinType substituteProjectionsForParameters(@NotNull ClassDescriptor clazz, @NotNull List<TypeProjection> projections) {
377 List<TypeParameterDescriptor> clazzTypeParameters = clazz.getTypeConstructor().getParameters();
378 if (clazzTypeParameters.size() != projections.size()) {
379 throw new IllegalArgumentException("type parameter counts do not match: " + clazz + ", " + projections);
380 }
381
382 Map<TypeConstructor, TypeProjection> substitutions = org.jetbrains.kotlin.utils.CollectionsKt
383 .newHashMapWithExpectedSize(clazzTypeParameters.size());
384
385 for (int i = 0; i < clazzTypeParameters.size(); ++i) {
386 TypeConstructor typeConstructor = clazzTypeParameters.get(i).getTypeConstructor();
387 substitutions.put(typeConstructor, projections.get(i));
388 }
389
390 return TypeSubstitutor.create(substitutions).substitute(clazz.getDefaultType(), Variance.INVARIANT);
391 }
392
393 public static boolean equalTypes(@NotNull KotlinType a, @NotNull KotlinType b) {
394 return KotlinTypeChecker.DEFAULT.isSubtypeOf(a, b) && KotlinTypeChecker.DEFAULT.isSubtypeOf(b, a);
395 }
396
397 public static boolean dependsOnTypeParameters(@NotNull KotlinType type, @NotNull Collection<TypeParameterDescriptor> typeParameters) {
398 return dependsOnTypeConstructors(type, CollectionsKt.map(
399 typeParameters,
400 new Function1<TypeParameterDescriptor, TypeConstructor>() {
401 @Override
402 public TypeConstructor invoke(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
403 return typeParameterDescriptor.getTypeConstructor();
404 }
405 }
406 ));
407 }
408
409 public static boolean dependsOnTypeConstructors(@NotNull KotlinType type, @NotNull Collection<TypeConstructor> typeParameterConstructors) {
410 if (typeParameterConstructors.contains(type.getConstructor())) return true;
411 for (TypeProjection typeProjection : type.getArguments()) {
412 if (!typeProjection.isStarProjection() && dependsOnTypeConstructors(typeProjection.getType(), typeParameterConstructors)) {
413 return true;
414 }
415 }
416 return false;
417 }
418
419 public static boolean containsSpecialType(@Nullable KotlinType type, @NotNull final KotlinType specialType) {
420 return containsSpecialType(type, new Function1<KotlinType, Boolean>() {
421 @Override
422 public Boolean invoke(KotlinType type) {
423 return specialType.equals(type);
424 }
425 });
426 }
427
428 public static boolean containsSpecialType(
429 @Nullable KotlinType type,
430 @NotNull Function1<KotlinType, Boolean> isSpecialType
431 ) {
432 if (type == null) return false;
433 if (isSpecialType.invoke(type)) return true;
434 Flexibility flexibility = type.getCapability(Flexibility.class);
435 if (flexibility != null
436 && (containsSpecialType(flexibility.getLowerBound(), isSpecialType) || containsSpecialType(flexibility.getUpperBound(), isSpecialType))) {
437 return true;
438 }
439 for (TypeProjection projection : type.getArguments()) {
440 if (!projection.isStarProjection() && containsSpecialType(projection.getType(), isSpecialType)) return true;
441 }
442 return false;
443 }
444
445 @NotNull
446 public static TypeProjection makeStarProjection(@NotNull TypeParameterDescriptor parameterDescriptor) {
447 return new StarProjectionImpl(parameterDescriptor);
448 }
449
450 @Nullable
451 public static KotlinType commonSupertypeForNumberTypes(@NotNull Collection<KotlinType> numberLowerBounds) {
452 if (numberLowerBounds.isEmpty()) return null;
453 Set<KotlinType> intersectionOfSupertypes = getIntersectionOfSupertypes(numberLowerBounds);
454 KotlinType primitiveNumberType = getDefaultPrimitiveNumberType(intersectionOfSupertypes);
455 if (primitiveNumberType != null) {
456 return primitiveNumberType;
457 }
458 return CommonSupertypes.commonSupertype(numberLowerBounds);
459 }
460
461 @NotNull
462 private static Set<KotlinType> getIntersectionOfSupertypes(@NotNull Collection<KotlinType> types) {
463 Set<KotlinType> upperBounds = new HashSet<KotlinType>();
464 for (KotlinType type : types) {
465 Collection<KotlinType> supertypes = type.getConstructor().getSupertypes();
466 if (upperBounds.isEmpty()) {
467 upperBounds.addAll(supertypes);
468 }
469 else {
470 upperBounds.retainAll(supertypes);
471 }
472 }
473 return upperBounds;
474 }
475
476 @NotNull
477 public static KotlinType getDefaultPrimitiveNumberType(@NotNull IntegerValueTypeConstructor numberValueTypeConstructor) {
478 KotlinType type = getDefaultPrimitiveNumberType(numberValueTypeConstructor.getSupertypes());
479 assert type != null : "Strange number value type constructor: " + numberValueTypeConstructor + ". " +
480 "Super types doesn't contain double, int or long: " + numberValueTypeConstructor.getSupertypes();
481 return type;
482 }
483
484 @Nullable
485 private static KotlinType getDefaultPrimitiveNumberType(@NotNull Collection<KotlinType> supertypes) {
486 if (supertypes.isEmpty()) {
487 return null;
488 }
489
490 KotlinBuiltIns builtIns = supertypes.iterator().next().getConstructor().getBuiltIns();
491 KotlinType doubleType = builtIns.getDoubleType();
492 if (supertypes.contains(doubleType)) {
493 return doubleType;
494 }
495 KotlinType intType = builtIns.getIntType();
496 if (supertypes.contains(intType)) {
497 return intType;
498 }
499 KotlinType longType = builtIns.getLongType();
500 if (supertypes.contains(longType)) {
501 return longType;
502 }
503 return null;
504 }
505
506 @NotNull
507 public static KotlinType getPrimitiveNumberType(
508 @NotNull IntegerValueTypeConstructor numberValueTypeConstructor,
509 @NotNull KotlinType expectedType
510 ) {
511 if (noExpectedType(expectedType) || expectedType.isError()) {
512 return getDefaultPrimitiveNumberType(numberValueTypeConstructor);
513 }
514 for (KotlinType primitiveNumberType : numberValueTypeConstructor.getSupertypes()) {
515 if (KotlinTypeChecker.DEFAULT.isSubtypeOf(primitiveNumberType, expectedType)) {
516 return primitiveNumberType;
517 }
518 }
519 return getDefaultPrimitiveNumberType(numberValueTypeConstructor);
520 }
521
522 public static List<TypeConstructor> topologicallySortSuperclassesAndRecordAllInstances(
523 @NotNull KotlinType type,
524 @NotNull final Map<TypeConstructor, Set<KotlinType>> constructorToAllInstances,
525 @NotNull final Set<TypeConstructor> visited
526 ) {
527 return DFS.dfs(
528 Collections.singletonList(type),
529 new DFS.Neighbors<KotlinType>() {
530 @NotNull
531 @Override
532 public Iterable<KotlinType> getNeighbors(KotlinType current) {
533 TypeSubstitutor substitutor = TypeSubstitutor.create(current);
534 Collection<KotlinType> supertypes = current.getConstructor().getSupertypes();
535 List<KotlinType> result = new ArrayList<KotlinType>(supertypes.size());
536 for (KotlinType supertype : supertypes) {
537 if (visited.contains(supertype.getConstructor())) {
538 continue;
539 }
540 result.add(substitutor.safeSubstitute(supertype, Variance.INVARIANT));
541 }
542 return result;
543 }
544 },
545 new DFS.Visited<KotlinType>() {
546 @Override
547 public boolean checkAndMarkVisited(KotlinType current) {
548 return visited.add(current.getConstructor());
549 }
550 },
551 new DFS.NodeHandlerWithListResult<KotlinType, TypeConstructor>() {
552 @Override
553 public boolean beforeChildren(KotlinType current) {
554 TypeConstructor constructor = current.getConstructor();
555
556 Set<KotlinType> instances = constructorToAllInstances.get(constructor);
557 if (instances == null) {
558 instances = new HashSet<KotlinType>();
559 constructorToAllInstances.put(constructor, instances);
560 }
561 instances.add(current);
562
563 return true;
564 }
565
566 @Override
567 public void afterChildren(KotlinType current) {
568 result.addFirst(current.getConstructor());
569 }
570 }
571 );
572 }
573
574 public static TypeSubstitutor makeConstantSubstitutor(Collection<TypeParameterDescriptor> typeParameterDescriptors, KotlinType type) {
575 final Set<TypeConstructor> constructors = org.jetbrains.kotlin.utils.CollectionsKt
576 .newHashSetWithExpectedSize(typeParameterDescriptors.size());
577 for (TypeParameterDescriptor typeParameterDescriptor : typeParameterDescriptors) {
578 constructors.add(typeParameterDescriptor.getTypeConstructor());
579 }
580 final TypeProjection projection = new TypeProjectionImpl(type);
581
582 return TypeSubstitutor.create(new TypeConstructorSubstitution() {
583 @Override
584 public TypeProjection get(@NotNull TypeConstructor key) {
585 if (constructors.contains(key)) {
586 return projection;
587 }
588 return null;
589 }
590
591 @Override
592 public boolean isEmpty() {
593 return false;
594 }
595 });
596 }
597
598 public static boolean isTypeParameter(@NotNull KotlinType type) {
599 return getTypeParameterDescriptorOrNull(type) != null;
600 }
601
602 public static boolean isNonReifiedTypeParemeter(@NotNull KotlinType type) {
603 TypeParameterDescriptor typeParameterDescriptor = getTypeParameterDescriptorOrNull(type);
604 return typeParameterDescriptor != null && !typeParameterDescriptor.isReified();
605 }
606
607 @Nullable
608 public static TypeParameterDescriptor getTypeParameterDescriptorOrNull(@NotNull KotlinType type) {
609 if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
610 return (TypeParameterDescriptor) type.getConstructor().getDeclarationDescriptor();
611 }
612 return null;
613 }
614
615 private static abstract class AbstractTypeWithKnownNullability extends AbstractKotlinType {
616 private final KotlinType delegate;
617
618 private AbstractTypeWithKnownNullability(@NotNull KotlinType delegate) {
619 this.delegate = delegate;
620 }
621
622 @Override
623 @NotNull
624 public TypeConstructor getConstructor() {
625 return delegate.getConstructor();
626 }
627
628 @Override
629 @NotNull
630 public List<TypeProjection> getArguments() {
631 return delegate.getArguments();
632 }
633
634 @Override
635 public abstract boolean isMarkedNullable();
636
637 @Override
638 @NotNull
639 public KtScope getMemberScope() {
640 return delegate.getMemberScope();
641 }
642
643 @Override
644 public boolean isError() {
645 return delegate.isError();
646 }
647
648 @Override
649 @NotNull
650 public Annotations getAnnotations() {
651 return delegate.getAnnotations();
652 }
653
654 @NotNull
655 @Override
656 public TypeSubstitution getSubstitution() {
657 return delegate.getSubstitution();
658 }
659
660 @Nullable
661 @Override
662 public <T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass) {
663 return delegate.getCapability(capabilityClass);
664 }
665
666 @NotNull
667 @Override
668 public TypeCapabilities getCapabilities() {
669 return delegate.getCapabilities();
670 }
671 }
672
673 private static class NullableType extends AbstractTypeWithKnownNullability {
674
675 private NullableType(@NotNull KotlinType delegate) {
676 super(delegate);
677 }
678
679 @Override
680 public boolean isMarkedNullable() {
681 return true;
682 }
683 }
684
685 private static class NotNullType extends AbstractTypeWithKnownNullability {
686
687 private NotNullType(@NotNull KotlinType delegate) {
688 super(delegate);
689 }
690
691 @Override
692 public boolean isMarkedNullable() {
693 return false;
694 }
695 }
696
697 }