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    }