001 /*
002 * Copyright 2010-2016 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.jvm.functions.Function1;
020 import org.jetbrains.annotations.NotNull;
021 import org.jetbrains.annotations.Nullable;
022 import org.jetbrains.kotlin.builtins.DefaultBuiltIns;
023 import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
024 import org.jetbrains.kotlin.descriptors.*;
025 import org.jetbrains.kotlin.descriptors.annotations.Annotations;
026 import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl;
027 import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl;
028 import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl;
029 import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl;
030 import org.jetbrains.kotlin.incremental.components.LookupLocation;
031 import org.jetbrains.kotlin.name.FqName;
032 import org.jetbrains.kotlin.name.Name;
033 import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
034 import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter;
035 import org.jetbrains.kotlin.resolve.scopes.MemberScope;
036 import org.jetbrains.kotlin.types.error.ErrorSimpleFunctionDescriptorImpl;
037 import org.jetbrains.kotlin.utils.Printer;
038
039 import java.util.Collection;
040 import java.util.Collections;
041 import java.util.List;
042 import java.util.Set;
043
044 import static java.util.Collections.emptySet;
045 import static kotlin.collections.CollectionsKt.emptyList;
046 import static kotlin.collections.CollectionsKt.joinToString;
047
048 public class ErrorUtils {
049
050 private static final ModuleDescriptor ERROR_MODULE;
051 static {
052 ERROR_MODULE = new ModuleDescriptor() {
053 @NotNull
054 @Override
055 public SourceKind getSourceKind() {
056 return SourceKind.NONE;
057 }
058
059 @Nullable
060 @Override
061 public <T> T getCapability(@NotNull Capability<T> capability) {
062 return null;
063 }
064
065 @NotNull
066 @Override
067 public Annotations getAnnotations() {
068 return Annotations.Companion.getEMPTY();
069 }
070
071 @NotNull
072 @Override
073 public Collection<FqName> getSubPackagesOf(@NotNull FqName fqName, @NotNull Function1<? super Name, Boolean> nameFilter) {
074 return emptyList();
075 }
076
077 @NotNull
078 @Override
079 public Name getName() {
080 return Name.special("<ERROR MODULE>");
081 }
082
083 @NotNull
084 @Override
085 public PackageViewDescriptor getPackage(@NotNull FqName fqName) {
086 throw new IllegalStateException("Should not be called!");
087 }
088
089 @NotNull
090 @Override
091 public List<ModuleDescriptor> getAllDependencyModules() {
092 return emptyList();
093 }
094
095 @NotNull
096 @Override
097 public Set<ModuleDescriptor> getAllImplementingModules() {
098 return emptySet();
099 }
100
101 @Override
102 public <R, D> R accept(@NotNull DeclarationDescriptorVisitor<R, D> visitor, D data) {
103 return null;
104 }
105
106 @Override
107 public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
108
109 }
110
111 @NotNull
112 @Override
113 public ModuleDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
114 return this;
115 }
116
117 @Override
118 public boolean shouldSeeInternalsOf(@NotNull ModuleDescriptor targetModule) {
119 return false;
120 }
121
122 @NotNull
123 @Override
124 public DeclarationDescriptor getOriginal() {
125 return this;
126 }
127
128 @Nullable
129 @Override
130 public DeclarationDescriptor getContainingDeclaration() {
131 return null;
132 }
133
134 @NotNull
135 @Override
136 public KotlinBuiltIns getBuiltIns() {
137 return DefaultBuiltIns.getInstance();
138 }
139 };
140 }
141
142 public static boolean containsErrorType(@NotNull CallableDescriptor callableDescriptor) {
143 if (callableDescriptor instanceof FunctionDescriptor) {
144 return containsErrorType((FunctionDescriptor) callableDescriptor);
145 }
146 else {
147 return containsErrorType(callableDescriptor.getReturnType());
148 }
149 }
150
151 public static boolean containsErrorType(@NotNull FunctionDescriptor function) {
152 if (containsErrorType(function.getReturnType())) {
153 return true;
154 }
155 ReceiverParameterDescriptor receiverParameter = function.getExtensionReceiverParameter();
156 if (receiverParameter != null && containsErrorType(receiverParameter.getType())) {
157 return true;
158 }
159 for (ValueParameterDescriptor parameter : function.getValueParameters()) {
160 if (containsErrorType(parameter.getType())) {
161 return true;
162 }
163 }
164 for (TypeParameterDescriptor parameter : function.getTypeParameters()) {
165 for (KotlinType upperBound : parameter.getUpperBounds()) {
166 if (containsErrorType(upperBound)) {
167 return true;
168 }
169 }
170 }
171
172 return false;
173 }
174
175 public static class ErrorScope implements MemberScope {
176 private final String debugMessage;
177
178 private ErrorScope(@NotNull String debugMessage) {
179 this.debugMessage = debugMessage;
180 }
181
182 @Nullable
183 @Override
184 public ClassifierDescriptor getContributedClassifier(@NotNull Name name, @NotNull LookupLocation location) {
185 return createErrorClass(name.asString());
186 }
187
188 @NotNull
189 @Override
190 // TODO: Convert to Kotlin or add @JvmWildcard to MemberScope declarations
191 // method is covariantly overridden in Kotlin, but collections in Java are invariant
192 @SuppressWarnings({"unchecked"})
193 public Set getContributedVariables(@NotNull Name name, @NotNull LookupLocation location) {
194 return ERROR_PROPERTY_GROUP;
195 }
196
197 @NotNull
198 @Override
199 // TODO: Convert to Kotlin or add @JvmWildcard to MemberScope declarations
200 // method is covariantly overridden in Kotlin, but collections in Java are invariant
201 @SuppressWarnings({"unchecked"})
202 public Set getContributedFunctions(@NotNull Name name, @NotNull LookupLocation location) {
203 return Collections.singleton(createErrorFunction(this));
204 }
205
206 @NotNull
207 @Override
208 public Set<Name> getFunctionNames() {
209 return emptySet();
210 }
211
212 @NotNull
213 @Override
214 public Set<Name> getVariableNames() {
215 return emptySet();
216 }
217
218 @NotNull
219 @Override
220 public Collection<DeclarationDescriptor> getContributedDescriptors(
221 @NotNull DescriptorKindFilter kindFilter, @NotNull Function1<? super Name, Boolean> nameFilter
222 ) {
223 return Collections.emptyList();
224 }
225
226 @Override
227 public String toString() {
228 return "ErrorScope{" + debugMessage + '}';
229 }
230
231 @Override
232 public void printScopeStructure(@NotNull Printer p) {
233 p.println(getClass().getSimpleName(), ": ", debugMessage);
234 }
235 }
236
237 private static class ThrowingScope implements MemberScope {
238 private final String debugMessage;
239
240 private ThrowingScope(@NotNull String message) {
241 debugMessage = message;
242 }
243
244 @Nullable
245 @Override
246 public ClassifierDescriptor getContributedClassifier(@NotNull Name name, @NotNull LookupLocation location) {
247 throw new IllegalStateException();
248 }
249
250 @NotNull
251 @Override
252 @SuppressWarnings({"unchecked"}) // KT-9898 Impossible implement kotlin interface from java
253 public Collection getContributedVariables(@NotNull Name name, @NotNull LookupLocation location) {
254 throw new IllegalStateException();
255 }
256
257 @NotNull
258 @Override
259 // TODO: Convert to Kotlin or add @JvmWildcard to MemberScope declarations
260 // method is covariantly overridden in Kotlin, but collections in Java are invariant
261 @SuppressWarnings({"unchecked"})
262 public Collection getContributedFunctions(@NotNull Name name, @NotNull LookupLocation location) {
263 throw new IllegalStateException();
264 }
265
266 @NotNull
267 @Override
268 public Collection<DeclarationDescriptor> getContributedDescriptors(
269 @NotNull DescriptorKindFilter kindFilter, @NotNull Function1<? super Name, Boolean> nameFilter
270 ) {
271 throw new IllegalStateException();
272 }
273
274 @NotNull
275 @Override
276 public Set<Name> getFunctionNames() {
277 throw new IllegalStateException();
278 }
279
280 @NotNull
281 @Override
282 public Set<Name> getVariableNames() {
283 throw new IllegalStateException();
284 }
285
286 @Override
287 public String toString() {
288 return "ThrowingScope{" + debugMessage + '}';
289 }
290
291 @Override
292 public void printScopeStructure(@NotNull Printer p) {
293 p.println(getClass().getSimpleName(), ": ", debugMessage);
294 }
295 }
296
297 private static final ErrorClassDescriptor ERROR_CLASS = new ErrorClassDescriptor(null);
298
299 private static class ErrorClassDescriptor extends ClassDescriptorImpl {
300 public ErrorClassDescriptor(@Nullable String name) {
301 super(getErrorModule(), Name.special(name == null ? "<ERROR CLASS>" : "<ERROR CLASS: " + name + ">"),
302 Modality.OPEN, ClassKind.CLASS, Collections.<KotlinType>emptyList(), SourceElement.NO_SOURCE,
303 /* isExternal = */ false
304 );
305
306 ClassConstructorDescriptorImpl
307 errorConstructor = ClassConstructorDescriptorImpl.create(this, Annotations.Companion.getEMPTY(), true, SourceElement.NO_SOURCE);
308 errorConstructor.initialize(Collections.<ValueParameterDescriptor>emptyList(),
309 Visibilities.INTERNAL);
310 MemberScope memberScope = createErrorScope(getName().asString());
311 errorConstructor.setReturnType(
312 new ErrorTypeImpl(
313 createErrorTypeConstructorWithCustomDebugName("<ERROR>", this),
314 memberScope
315 )
316 );
317
318 initialize(memberScope, Collections.<ClassConstructorDescriptor>singleton(errorConstructor), errorConstructor);
319 }
320
321 @NotNull
322 @Override
323 public ClassDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
324 return this;
325 }
326
327 @Override
328 public String toString() {
329 return getName().asString();
330 }
331
332 @NotNull
333 @Override
334 public MemberScope getMemberScope(@NotNull List<? extends TypeProjection> typeArguments) {
335 return createErrorScope("Error scope for class " + getName() + " with arguments: " + typeArguments);
336 }
337
338 @NotNull
339 @Override
340 public MemberScope getMemberScope(@NotNull TypeSubstitution typeSubstitution) {
341 return createErrorScope("Error scope for class " + getName() + " with arguments: " + typeSubstitution);
342 }
343 }
344
345 @NotNull
346 public static ClassDescriptor createErrorClass(@NotNull String debugMessage) {
347 return new ErrorClassDescriptor(debugMessage);
348 }
349
350 @NotNull
351 public static MemberScope createErrorScope(@NotNull String debugMessage) {
352 return createErrorScope(debugMessage, false);
353 }
354
355 @NotNull
356 public static MemberScope createErrorScope(@NotNull String debugMessage, boolean throwExceptions) {
357 if (throwExceptions) {
358 return new ThrowingScope(debugMessage);
359 }
360 return new ErrorScope(debugMessage);
361 }
362
363 // Do not move it into AbstractTypeConstructor.Companion because of cycle in initialization(see KT-13264)
364 public static final SimpleType ERROR_TYPE_FOR_LOOP_IN_SUPERTYPES = createErrorType("<LOOP IN SUPERTYPES>");
365
366 private static final KotlinType ERROR_PROPERTY_TYPE = createErrorType("<ERROR PROPERTY TYPE>");
367 private static final PropertyDescriptor ERROR_PROPERTY = createErrorProperty();
368
369 private static final Set<PropertyDescriptor> ERROR_PROPERTY_GROUP = Collections.singleton(ERROR_PROPERTY);
370
371 @NotNull
372 private static PropertyDescriptorImpl createErrorProperty() {
373 PropertyDescriptorImpl descriptor = PropertyDescriptorImpl.create(
374 ERROR_CLASS,
375 Annotations.Companion.getEMPTY(),
376 Modality.OPEN,
377 Visibilities.PUBLIC,
378 true,
379 Name.special("<ERROR PROPERTY>"),
380 CallableMemberDescriptor.Kind.DECLARATION,
381 SourceElement.NO_SOURCE,
382 false, false, false, false, false, false
383 );
384 descriptor.setType(ERROR_PROPERTY_TYPE,
385 Collections.<TypeParameterDescriptor>emptyList(),
386 null,
387 (KotlinType) null
388 );
389
390 return descriptor;
391 }
392
393 @NotNull
394 private static SimpleFunctionDescriptor createErrorFunction(@NotNull ErrorScope ownerScope) {
395 ErrorSimpleFunctionDescriptorImpl function = new ErrorSimpleFunctionDescriptorImpl(ERROR_CLASS, ownerScope);
396 function.initialize(
397 null,
398 null,
399 Collections.<TypeParameterDescriptorImpl>emptyList(), // TODO
400 Collections.<ValueParameterDescriptor>emptyList(), // TODO
401 createErrorType("<ERROR FUNCTION RETURN TYPE>"),
402 Modality.OPEN,
403 Visibilities.PUBLIC
404 );
405 return function;
406 }
407
408 @NotNull
409 public static SimpleType createErrorType(@NotNull String debugMessage) {
410 return createErrorTypeWithArguments(debugMessage, Collections.<TypeProjection>emptyList());
411 }
412
413 @NotNull
414 public static SimpleType createErrorTypeWithCustomDebugName(@NotNull String debugName) {
415 return createErrorTypeWithCustomConstructor(debugName, createErrorTypeConstructorWithCustomDebugName(debugName));
416 }
417
418 @NotNull
419 public static SimpleType createErrorTypeWithCustomConstructor(@NotNull String debugName, @NotNull TypeConstructor typeConstructor) {
420 return new ErrorTypeImpl(typeConstructor, createErrorScope(debugName));
421 }
422
423 @NotNull
424 public static SimpleType createErrorTypeWithArguments(@NotNull String debugMessage, @NotNull List<TypeProjection> arguments) {
425 return new ErrorTypeImpl(createErrorTypeConstructor(debugMessage), createErrorScope(debugMessage), arguments, false);
426 }
427
428 @NotNull
429 public static TypeConstructor createErrorTypeConstructor(@NotNull String debugMessage) {
430 return createErrorTypeConstructorWithCustomDebugName("[ERROR : " + debugMessage + "]", ERROR_CLASS);
431 }
432
433 @NotNull
434 public static TypeConstructor createErrorTypeConstructorWithCustomDebugName(@NotNull String debugName) {
435 return createErrorTypeConstructorWithCustomDebugName(debugName, ERROR_CLASS);
436 }
437
438 @NotNull
439 private static TypeConstructor createErrorTypeConstructorWithCustomDebugName(
440 @NotNull final String debugName, @NotNull final ErrorClassDescriptor errorClass
441 ) {
442 return new TypeConstructor() {
443 @NotNull
444 @Override
445 public List<TypeParameterDescriptor> getParameters() {
446 return emptyList();
447 }
448
449 @NotNull
450 @Override
451 public Collection<KotlinType> getSupertypes() {
452 return emptyList();
453 }
454
455 @Override
456 public boolean isFinal() {
457 return false;
458 }
459
460 @Override
461 public boolean isDenotable() {
462 return false;
463 }
464
465 @Nullable
466 @Override
467 public ClassifierDescriptor getDeclarationDescriptor() {
468 return errorClass;
469 }
470
471 @NotNull
472 @Override
473 public KotlinBuiltIns getBuiltIns() {
474 return DefaultBuiltIns.getInstance();
475 }
476
477 @Override
478 public String toString() {
479 return debugName;
480 }
481 };
482 }
483
484 public static boolean containsErrorType(@Nullable KotlinType type) {
485 if (type == null) return false;
486 if (type.isError()) return true;
487 for (TypeProjection projection : type.getArguments()) {
488 if (!projection.isStarProjection() && containsErrorType(projection.getType())) return true;
489 }
490 return false;
491 }
492
493 public static boolean isError(@Nullable DeclarationDescriptor candidate) {
494 if (candidate == null) return false;
495 return isErrorClass(candidate) || isErrorClass(candidate.getContainingDeclaration()) || candidate == ERROR_MODULE;
496 }
497
498 private static boolean isErrorClass(@Nullable DeclarationDescriptor candidate) {
499 return candidate instanceof ErrorClassDescriptor;
500 }
501
502 private static class ErrorTypeImpl extends SimpleType {
503 private final TypeConstructor constructor;
504 private final MemberScope memberScope;
505 private final List<TypeProjection> arguments;
506 private final boolean nullability;
507
508 private ErrorTypeImpl(
509 @NotNull TypeConstructor constructor,
510 @NotNull MemberScope memberScope,
511 @NotNull List<TypeProjection> arguments,
512 boolean nullability
513 ) {
514 this.constructor = constructor;
515 this.memberScope = memberScope;
516 this.arguments = arguments;
517 this.nullability = nullability;
518 }
519
520 private ErrorTypeImpl(@NotNull TypeConstructor constructor, @NotNull MemberScope memberScope) {
521 this(constructor, memberScope, Collections.<TypeProjection>emptyList(), false);
522 }
523
524 @NotNull
525 @Override
526 public TypeConstructor getConstructor() {
527 return constructor;
528 }
529
530 @NotNull
531 @Override
532 public List<TypeProjection> getArguments() {
533 return arguments;
534 }
535
536 @Override
537 public boolean isMarkedNullable() {
538 return nullability;
539 }
540
541 @NotNull
542 @Override
543 public MemberScope getMemberScope() {
544 return memberScope;
545 }
546
547 @Override
548 public boolean isError() {
549 return true;
550 }
551
552 @NotNull
553 @Override
554 public Annotations getAnnotations() {
555 return Annotations.Companion.getEMPTY();
556 }
557
558 @Override
559 public String toString() {
560 return constructor.toString() + (arguments.isEmpty() ? "" : joinToString(arguments, ", ", "<", ">", -1, "...", null));
561 }
562
563 @NotNull
564 @Override
565 public SimpleType replaceAnnotations(@NotNull Annotations newAnnotations) {
566 return this;
567 }
568
569 @NotNull
570 @Override
571 public SimpleType makeNullableAsSpecified(boolean newNullability) {
572 return new ErrorTypeImpl(constructor, memberScope, arguments, newNullability);
573 }
574 }
575
576 @NotNull
577 public static ModuleDescriptor getErrorModule() {
578 return ERROR_MODULE;
579 }
580
581 public static boolean isUninferredParameter(@Nullable KotlinType type) {
582 return type != null && type.getConstructor() instanceof UninferredParameterTypeConstructor;
583 }
584
585 public static boolean containsUninferredParameter(@Nullable KotlinType type) {
586 return TypeUtils.contains(type, new Function1<UnwrappedType, Boolean>() {
587 @Override
588 public Boolean invoke(UnwrappedType argumentType) {
589 return isUninferredParameter(argumentType);
590 }
591 });
592 }
593
594 @NotNull
595 public static KotlinType createUninferredParameterType(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
596 return createErrorTypeWithCustomConstructor("Scope for error type for not inferred parameter: " + typeParameterDescriptor.getName(),
597 new UninferredParameterTypeConstructor(typeParameterDescriptor));
598 }
599
600 public static class UninferredParameterTypeConstructor implements TypeConstructor {
601 private final TypeParameterDescriptor typeParameterDescriptor;
602 private final TypeConstructor errorTypeConstructor;
603
604 private UninferredParameterTypeConstructor(@NotNull TypeParameterDescriptor descriptor) {
605 typeParameterDescriptor = descriptor;
606 errorTypeConstructor = createErrorTypeConstructorWithCustomDebugName("CANT_INFER_TYPE_PARAMETER: " + descriptor.getName());
607 }
608
609 @NotNull
610 public TypeParameterDescriptor getTypeParameterDescriptor() {
611 return typeParameterDescriptor;
612 }
613
614 @NotNull
615 @Override
616 public List<TypeParameterDescriptor> getParameters() {
617 return errorTypeConstructor.getParameters();
618 }
619
620 @NotNull
621 @Override
622 public Collection<KotlinType> getSupertypes() {
623 return errorTypeConstructor.getSupertypes();
624 }
625
626 @Override
627 public boolean isFinal() {
628 return errorTypeConstructor.isFinal();
629 }
630
631 @Override
632 public boolean isDenotable() {
633 return errorTypeConstructor.isDenotable();
634 }
635
636 @Nullable
637 @Override
638 public ClassifierDescriptor getDeclarationDescriptor() {
639 return errorTypeConstructor.getDeclarationDescriptor();
640 }
641
642 @NotNull
643 @Override
644 public KotlinBuiltIns getBuiltIns() {
645 return DescriptorUtilsKt.getBuiltIns(typeParameterDescriptor);
646 }
647 }
648
649 private ErrorUtils() {}
650 }