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.KotlinPackage;
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.JetScope;
030 import org.jetbrains.kotlin.types.checker.JetTypeChecker;
031 import org.jetbrains.kotlin.utils.DFS;
032 import org.jetbrains.kotlin.utils.UtilsPackage;
033
034 import java.util.*;
035
036 public class TypeUtils {
037 public static final JetType DONT_CARE = ErrorUtils.createErrorTypeWithCustomDebugName("DONT_CARE");
038 public static final JetType PLACEHOLDER_FUNCTION_TYPE = ErrorUtils.createErrorTypeWithCustomDebugName("PLACEHOLDER_FUNCTION_TYPE");
039
040 public static final JetType CANT_INFER_FUNCTION_PARAM_TYPE = ErrorUtils.createErrorType("Cannot be inferred");
041
042 public static class SpecialType implements JetType {
043 private final String name;
044
045 public SpecialType(String name) {
046 this.name = name;
047 }
048
049 @NotNull
050 @Override
051 public TypeConstructor getConstructor() {
052 throw new IllegalStateException(name);
053 }
054
055 @NotNull
056 @Override
057 public List<TypeProjection> getArguments() {
058 throw new IllegalStateException(name);
059 }
060
061 @NotNull
062 @Override
063 public TypeSubstitution getSubstitution() {
064 throw new IllegalStateException(name);
065 }
066
067 @Override
068 public boolean isMarkedNullable() {
069 throw new IllegalStateException(name);
070 }
071
072 @NotNull
073 @Override
074 public JetScope getMemberScope() {
075 throw new IllegalStateException(name);
076 }
077
078 @Override
079 public boolean isError() {
080 return false;
081 }
082
083 @NotNull
084 @Override
085 public Annotations getAnnotations() {
086 throw new IllegalStateException(name);
087 }
088
089 @Nullable
090 @Override
091 public <T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass) {
092 return null;
093 }
094
095 @NotNull
096 @Override
097 public TypeCapabilities getCapabilities() {
098 return TypeCapabilities.NONE.INSTANCE$;
099 }
100
101 @Override
102 public String toString() {
103 return name;
104 }
105 }
106
107 public static final JetType NO_EXPECTED_TYPE = new SpecialType("NO_EXPECTED_TYPE");
108
109 public static final JetType UNIT_EXPECTED_TYPE = new SpecialType("UNIT_EXPECTED_TYPE");
110
111 public static boolean noExpectedType(@NotNull JetType type) {
112 return type == NO_EXPECTED_TYPE || type == UNIT_EXPECTED_TYPE;
113 }
114
115 public static boolean isDontCarePlaceholder(@Nullable JetType type) {
116 return type != null && type.getConstructor() == DONT_CARE.getConstructor();
117 }
118
119 @NotNull
120 public static JetType makeNullable(@NotNull JetType type) {
121 return makeNullableAsSpecified(type, true);
122 }
123
124 @NotNull
125 public static JetType makeNotNullable(@NotNull JetType type) {
126 return makeNullableAsSpecified(type, false);
127 }
128
129 @NotNull
130 public static JetType makeNullableAsSpecified(@NotNull JetType 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 JetType makeNullableIfNeeded(@NotNull JetType type, boolean nullable) {
155 if (nullable) {
156 return makeNullable(type);
157 }
158 return type;
159 }
160
161 public static boolean canHaveSubtypes(JetTypeChecker typeChecker, @NotNull JetType 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 JetType 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(JetTypeChecker typeChecker, JetType argument, TypeParameterDescriptor parameterDescriptor) {
227 for (JetType 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 JetType makeUnsubstitutedType(ClassDescriptor classDescriptor, JetScope 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 JetTypeImpl.create(
245 Annotations.EMPTY,
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 UtilsPackage.toReadOnlyList(result);
260 }
261
262 @NotNull
263 public static List<JetType> getImmediateSupertypes(@NotNull JetType type) {
264 boolean isNullable = type.isMarkedNullable();
265 TypeSubstitutor substitutor = TypeSubstitutor.create(type);
266 Collection<JetType> originalSupertypes = type.getConstructor().getSupertypes();
267 List<JetType> result = new ArrayList<JetType>(originalSupertypes.size());
268 for (JetType supertype : originalSupertypes) {
269 JetType 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 JetType type, @NotNull Set<JetType> result) {
278 List<JetType> immediateSupertypes = getImmediateSupertypes(type);
279 result.addAll(immediateSupertypes);
280 for (JetType supertype : immediateSupertypes) {
281 collectAllSupertypes(supertype, result);
282 }
283 }
284
285
286 @NotNull
287 public static Set<JetType> getAllSupertypes(@NotNull JetType 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<JetType> result = new LinkedHashSet<JetType>(15);
291 collectAllSupertypes(type, result);
292 return result;
293 }
294
295 public static boolean hasNullableLowerBound(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
296 for (JetType 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 JetType type) {
310 if (type.isMarkedNullable()) {
311 return true;
312 }
313 if (TypesPackage.isFlexible(type) && isNullableType(TypesPackage.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 JetType type) {
328 if (type.isMarkedNullable()) {
329 return true;
330 }
331 if (TypesPackage.isFlexible(type) && acceptsNullable(TypesPackage.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 JetType type) {
341 if (type.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) {
342 // A class/trait cannot have a nullable supertype
343 return false;
344 }
345
346 for (JetType 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 JetType 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 JetType substituteParameters(@NotNull ClassDescriptor clazz, @NotNull List<JetType> typeArguments) {
365 List<TypeProjection> projections = KotlinPackage.map(typeArguments, new Function1<JetType, TypeProjection>() {
366 @Override
367 public TypeProjection invoke(JetType type) {
368 return new TypeProjectionImpl(type);
369 }
370 });
371
372 return substituteProjectionsForParameters(clazz, projections);
373 }
374
375 @NotNull
376 public static JetType 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 = UtilsPackage.newHashMapWithExpectedSize(clazzTypeParameters.size());
383
384 for (int i = 0; i < clazzTypeParameters.size(); ++i) {
385 TypeConstructor typeConstructor = clazzTypeParameters.get(i).getTypeConstructor();
386 substitutions.put(typeConstructor, projections.get(i));
387 }
388
389 return TypeSubstitutor.create(substitutions).substitute(clazz.getDefaultType(), Variance.INVARIANT);
390 }
391
392 public static boolean equalTypes(@NotNull JetType a, @NotNull JetType b) {
393 return JetTypeChecker.DEFAULT.isSubtypeOf(a, b) && JetTypeChecker.DEFAULT.isSubtypeOf(b, a);
394 }
395
396 public static boolean dependsOnTypeParameters(@NotNull JetType type, @NotNull Collection<TypeParameterDescriptor> typeParameters) {
397 return dependsOnTypeConstructors(type, KotlinPackage.map(
398 typeParameters,
399 new Function1<TypeParameterDescriptor, TypeConstructor>() {
400 @Override
401 public TypeConstructor invoke(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
402 return typeParameterDescriptor.getTypeConstructor();
403 }
404 }
405 ));
406 }
407
408 public static boolean dependsOnTypeConstructors(@NotNull JetType type, @NotNull Collection<TypeConstructor> typeParameterConstructors) {
409 if (typeParameterConstructors.contains(type.getConstructor())) return true;
410 for (TypeProjection typeProjection : type.getArguments()) {
411 if (!typeProjection.isStarProjection() && dependsOnTypeConstructors(typeProjection.getType(), typeParameterConstructors)) {
412 return true;
413 }
414 }
415 return false;
416 }
417
418 public static boolean containsSpecialType(@Nullable JetType type, @NotNull final JetType specialType) {
419 return containsSpecialType(type, new Function1<JetType, Boolean>() {
420 @Override
421 public Boolean invoke(JetType type) {
422 return specialType.equals(type);
423 }
424 });
425 }
426
427 public static boolean containsSpecialType(
428 @Nullable JetType type,
429 @NotNull Function1<JetType, Boolean> isSpecialType
430 ) {
431 if (type == null) return false;
432 if (isSpecialType.invoke(type)) return true;
433 Flexibility flexibility = type.getCapability(Flexibility.class);
434 if (flexibility != null
435 && (containsSpecialType(flexibility.getLowerBound(), isSpecialType) || containsSpecialType(flexibility.getUpperBound(), isSpecialType))) {
436 return true;
437 }
438 for (TypeProjection projection : type.getArguments()) {
439 if (!projection.isStarProjection() && containsSpecialType(projection.getType(), isSpecialType)) return true;
440 }
441 return false;
442 }
443
444 @NotNull
445 public static TypeProjection makeStarProjection(@NotNull TypeParameterDescriptor parameterDescriptor) {
446 return new StarProjectionImpl(parameterDescriptor);
447 }
448
449 @Nullable
450 public static JetType commonSupertypeForNumberTypes(@NotNull Collection<JetType> numberLowerBounds) {
451 if (numberLowerBounds.isEmpty()) return null;
452 Set<JetType> intersectionOfSupertypes = getIntersectionOfSupertypes(numberLowerBounds);
453 JetType primitiveNumberType = getDefaultPrimitiveNumberType(intersectionOfSupertypes);
454 if (primitiveNumberType != null) {
455 return primitiveNumberType;
456 }
457 return CommonSupertypes.commonSupertype(numberLowerBounds);
458 }
459
460 @NotNull
461 private static Set<JetType> getIntersectionOfSupertypes(@NotNull Collection<JetType> types) {
462 Set<JetType> upperBounds = new HashSet<JetType>();
463 for (JetType type : types) {
464 Collection<JetType> supertypes = type.getConstructor().getSupertypes();
465 if (upperBounds.isEmpty()) {
466 upperBounds.addAll(supertypes);
467 }
468 else {
469 upperBounds.retainAll(supertypes);
470 }
471 }
472 return upperBounds;
473 }
474
475 @NotNull
476 public static JetType getDefaultPrimitiveNumberType(@NotNull IntegerValueTypeConstructor numberValueTypeConstructor) {
477 JetType type = getDefaultPrimitiveNumberType(numberValueTypeConstructor.getSupertypes());
478 assert type != null : "Strange number value type constructor: " + numberValueTypeConstructor + ". " +
479 "Super types doesn't contain double, int or long: " + numberValueTypeConstructor.getSupertypes();
480 return type;
481 }
482
483 @Nullable
484 private static JetType getDefaultPrimitiveNumberType(@NotNull Collection<JetType> supertypes) {
485 JetType doubleType = KotlinBuiltIns.getInstance().getDoubleType();
486 if (supertypes.contains(doubleType)) {
487 return doubleType;
488 }
489 JetType intType = KotlinBuiltIns.getInstance().getIntType();
490 if (supertypes.contains(intType)) {
491 return intType;
492 }
493 JetType longType = KotlinBuiltIns.getInstance().getLongType();
494 if (supertypes.contains(longType)) {
495 return longType;
496 }
497 return null;
498 }
499
500 @NotNull
501 public static JetType getPrimitiveNumberType(
502 @NotNull IntegerValueTypeConstructor numberValueTypeConstructor,
503 @NotNull JetType expectedType
504 ) {
505 if (noExpectedType(expectedType) || expectedType.isError()) {
506 return getDefaultPrimitiveNumberType(numberValueTypeConstructor);
507 }
508 for (JetType primitiveNumberType : numberValueTypeConstructor.getSupertypes()) {
509 if (JetTypeChecker.DEFAULT.isSubtypeOf(primitiveNumberType, expectedType)) {
510 return primitiveNumberType;
511 }
512 }
513 return getDefaultPrimitiveNumberType(numberValueTypeConstructor);
514 }
515
516 public static List<TypeConstructor> topologicallySortSuperclassesAndRecordAllInstances(
517 @NotNull JetType type,
518 @NotNull final Map<TypeConstructor, Set<JetType>> constructorToAllInstances,
519 @NotNull final Set<TypeConstructor> visited
520 ) {
521 return DFS.dfs(
522 Collections.singletonList(type),
523 new DFS.Neighbors<JetType>() {
524 @NotNull
525 @Override
526 public Iterable<JetType> getNeighbors(JetType current) {
527 TypeSubstitutor substitutor = TypeSubstitutor.create(current);
528 Collection<JetType> supertypes = current.getConstructor().getSupertypes();
529 List<JetType> result = new ArrayList<JetType>(supertypes.size());
530 for (JetType supertype : supertypes) {
531 if (visited.contains(supertype.getConstructor())) {
532 continue;
533 }
534 result.add(substitutor.safeSubstitute(supertype, Variance.INVARIANT));
535 }
536 return result;
537 }
538 },
539 new DFS.Visited<JetType>() {
540 @Override
541 public boolean checkAndMarkVisited(JetType current) {
542 return visited.add(current.getConstructor());
543 }
544 },
545 new DFS.NodeHandlerWithListResult<JetType, TypeConstructor>() {
546 @Override
547 public boolean beforeChildren(JetType current) {
548 TypeConstructor constructor = current.getConstructor();
549
550 Set<JetType> instances = constructorToAllInstances.get(constructor);
551 if (instances == null) {
552 instances = new HashSet<JetType>();
553 constructorToAllInstances.put(constructor, instances);
554 }
555 instances.add(current);
556
557 return true;
558 }
559
560 @Override
561 public void afterChildren(JetType current) {
562 result.addFirst(current.getConstructor());
563 }
564 }
565 );
566 }
567
568 public static TypeSubstitutor makeConstantSubstitutor(Collection<TypeParameterDescriptor> typeParameterDescriptors, JetType type) {
569 final Set<TypeConstructor> constructors = UtilsPackage.newHashSetWithExpectedSize(typeParameterDescriptors.size());
570 for (TypeParameterDescriptor typeParameterDescriptor : typeParameterDescriptors) {
571 constructors.add(typeParameterDescriptor.getTypeConstructor());
572 }
573 final TypeProjection projection = new TypeProjectionImpl(type);
574
575 return TypeSubstitutor.create(new TypeConstructorSubstitution() {
576 @Override
577 public TypeProjection get(@NotNull TypeConstructor key) {
578 if (constructors.contains(key)) {
579 return projection;
580 }
581 return null;
582 }
583
584 @Override
585 public boolean isEmpty() {
586 return false;
587 }
588 });
589 }
590
591 public static boolean isTypeParameter(@NotNull JetType type) {
592 return getTypeParameterDescriptorOrNull(type) != null;
593 }
594
595 public static boolean isNonReifiedTypeParemeter(@NotNull JetType type) {
596 TypeParameterDescriptor typeParameterDescriptor = getTypeParameterDescriptorOrNull(type);
597 return typeParameterDescriptor != null && !typeParameterDescriptor.isReified();
598 }
599
600 @Nullable
601 public static TypeParameterDescriptor getTypeParameterDescriptorOrNull(@NotNull JetType type) {
602 if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
603 return (TypeParameterDescriptor) type.getConstructor().getDeclarationDescriptor();
604 }
605 return null;
606 }
607
608 private static abstract class AbstractTypeWithKnownNullability extends AbstractJetType {
609 private final JetType delegate;
610
611 private AbstractTypeWithKnownNullability(@NotNull JetType delegate) {
612 this.delegate = delegate;
613 }
614
615 @Override
616 @NotNull
617 public TypeConstructor getConstructor() {
618 return delegate.getConstructor();
619 }
620
621 @Override
622 @NotNull
623 public List<TypeProjection> getArguments() {
624 return delegate.getArguments();
625 }
626
627 @Override
628 public abstract boolean isMarkedNullable();
629
630 @Override
631 @NotNull
632 public JetScope getMemberScope() {
633 return delegate.getMemberScope();
634 }
635
636 @Override
637 public boolean isError() {
638 return delegate.isError();
639 }
640
641 @Override
642 @NotNull
643 public Annotations getAnnotations() {
644 return delegate.getAnnotations();
645 }
646
647 @NotNull
648 @Override
649 public TypeSubstitution getSubstitution() {
650 return delegate.getSubstitution();
651 }
652
653 @Nullable
654 @Override
655 public <T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass) {
656 return delegate.getCapability(capabilityClass);
657 }
658
659 @NotNull
660 @Override
661 public TypeCapabilities getCapabilities() {
662 return delegate.getCapabilities();
663 }
664 }
665
666 private static class NullableType extends AbstractTypeWithKnownNullability {
667
668 private NullableType(@NotNull JetType delegate) {
669 super(delegate);
670 }
671
672 @Override
673 public boolean isMarkedNullable() {
674 return true;
675 }
676 }
677
678 private static class NotNullType extends AbstractTypeWithKnownNullability {
679
680 private NotNullType(@NotNull JetType delegate) {
681 super(delegate);
682 }
683
684 @Override
685 public boolean isMarkedNullable() {
686 return false;
687 }
688 }
689
690 }