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    }