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