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