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.KotlinBuiltIns;
023    import org.jetbrains.kotlin.descriptors.*;
024    import org.jetbrains.kotlin.descriptors.annotations.Annotations;
025    import org.jetbrains.kotlin.descriptors.impl.*;
026    import org.jetbrains.kotlin.incremental.components.LookupLocation;
027    import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
028    import org.jetbrains.kotlin.name.Name;
029    import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter;
030    import org.jetbrains.kotlin.resolve.scopes.JetScope;
031    import org.jetbrains.kotlin.storage.LockBasedStorageManager;
032    import org.jetbrains.kotlin.types.error.ErrorSimpleFunctionDescriptorImpl;
033    import org.jetbrains.kotlin.utils.Printer;
034    
035    import java.util.Collection;
036    import java.util.Collections;
037    import java.util.List;
038    import java.util.Set;
039    
040    import static kotlin.KotlinPackage.joinToString;
041    
042    public class ErrorUtils {
043    
044        private static final ModuleDescriptor ERROR_MODULE;
045        static {
046            ERROR_MODULE = new ModuleDescriptorImpl(
047                    Name.special("<ERROR MODULE>"),
048                    LockBasedStorageManager.NO_LOCKS,
049                    ModuleParameters.Empty.INSTANCE$
050            );
051        }
052    
053        public static boolean containsErrorType(@NotNull FunctionDescriptor function) {
054            if (containsErrorType(function.getReturnType())) {
055                return true;
056            }
057            ReceiverParameterDescriptor receiverParameter = function.getExtensionReceiverParameter();
058            if (receiverParameter != null && containsErrorType(receiverParameter.getType())) {
059                return true;
060            }
061            for (ValueParameterDescriptor parameter : function.getValueParameters()) {
062                if (containsErrorType(parameter.getType())) {
063                    return true;
064                }
065            }
066            for (TypeParameterDescriptor parameter : function.getTypeParameters()) {
067                for (JetType upperBound : parameter.getUpperBounds()) {
068                    if (containsErrorType(upperBound)) {
069                        return true;
070                    }
071                }
072            }
073    
074            return false;
075        }
076    
077        private static abstract class AbstractErrorScope implements JetScope {
078            @Nullable
079            @Override
080            public ClassifierDescriptor getClassifier(@NotNull Name name) {
081                return getClassifier(name, NoLookupLocation.UNSORTED);
082            }
083        }
084    
085        public static class ErrorScope extends AbstractErrorScope {
086            private final String debugMessage;
087    
088            private ErrorScope(@NotNull String debugMessage) {
089                this.debugMessage = debugMessage;
090            }
091    
092            @Nullable
093            @Override
094            public ClassifierDescriptor getClassifier(@NotNull Name name, @NotNull LookupLocation location) {
095                return createErrorClass(name.asString());
096            }
097    
098            @NotNull
099            @Override
100            public Set<VariableDescriptor> getProperties(@NotNull Name name, @NotNull LookupLocation location) {
101                return ERROR_VARIABLE_GROUP;
102            }
103    
104            @NotNull
105            @Override
106            public Collection<PropertyDescriptor> getSyntheticExtensionProperties(
107                    @NotNull Collection<? extends JetType> receiverTypes, @NotNull Name name,
108                    @NotNull LookupLocation location
109            ) {
110                return ERROR_PROPERTY_GROUP;
111            }
112    
113            @NotNull
114            @Override
115            public Collection<FunctionDescriptor> getSyntheticExtensionFunctions(
116                    @NotNull Collection<? extends JetType> receiverTypes, @NotNull Name name,
117                    @NotNull LookupLocation location
118            ) {
119                return Collections.<FunctionDescriptor>singleton(createErrorFunction(this));
120            }
121    
122            @NotNull
123            @Override
124            public Collection<PropertyDescriptor> getSyntheticExtensionProperties(@NotNull Collection<? extends JetType> receiverTypes) {
125                return ERROR_PROPERTY_GROUP;
126            }
127    
128            @NotNull
129            @Override
130            public Collection<FunctionDescriptor> getSyntheticExtensionFunctions(
131                    @NotNull Collection<? extends JetType> receiverTypes
132            ) {
133                return Collections.<FunctionDescriptor>singleton(createErrorFunction(this));
134            }
135    
136            @Override
137            public VariableDescriptor getLocalVariable(@NotNull Name name) {
138                return ERROR_PROPERTY;
139            }
140    
141            @Override
142            public PackageViewDescriptor getPackage(@NotNull Name name) {
143                return null;
144            }
145    
146            @NotNull
147            @Override
148            public List<ReceiverParameterDescriptor> getImplicitReceiversHierarchy() {
149                return Collections.emptyList();
150            }
151    
152            @NotNull
153            @Override
154            public Set<FunctionDescriptor> getFunctions(@NotNull Name name, @NotNull LookupLocation location) {
155                return Collections.<FunctionDescriptor>singleton(createErrorFunction(this));
156            }
157    
158            @NotNull
159            @Override
160            public DeclarationDescriptor getContainingDeclaration() {
161                return ERROR_MODULE;
162            }
163    
164            @NotNull
165            @Override
166            public Collection<DeclarationDescriptor> getDeclarationsByLabel(@NotNull Name labelName) {
167                return Collections.emptyList();
168            }
169    
170            @NotNull
171            @Override
172            public Collection<DeclarationDescriptor> getDescriptors(
173                    @NotNull DescriptorKindFilter kindFilter, @NotNull Function1<? super Name, ? extends Boolean> nameFilter
174            ) {
175                return Collections.emptyList();
176            }
177    
178            @NotNull
179            @Override
180            public Collection<DeclarationDescriptor> getAllDescriptors() {
181                return Collections.emptyList();
182            }
183    
184            @NotNull
185            @Override
186            public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
187                return Collections.emptyList();
188            }
189    
190            @Override
191            public String toString() {
192                return "ErrorScope{" + debugMessage + '}';
193            }
194    
195            @Override
196            public void printScopeStructure(@NotNull Printer p) {
197                p.println(getClass().getSimpleName(), ": ", debugMessage);
198            }
199        }
200    
201        private static class ThrowingScope extends AbstractErrorScope {
202            private final String debugMessage;
203    
204            private ThrowingScope(@NotNull String message) {
205                debugMessage = message;
206            }
207    
208            @Nullable
209            @Override
210            public ClassifierDescriptor getClassifier(@NotNull Name name, @NotNull LookupLocation location) {
211                throw new IllegalStateException();
212            }
213    
214            @Nullable
215            @Override
216            public PackageViewDescriptor getPackage(@NotNull Name name) {
217                throw new IllegalStateException();
218            }
219    
220            @NotNull
221            @Override
222            public Collection<VariableDescriptor> getProperties(@NotNull Name name, @NotNull LookupLocation location) {
223                throw new IllegalStateException();
224            }
225    
226            @Nullable
227            @Override
228            public VariableDescriptor getLocalVariable(@NotNull Name name) {
229                throw new IllegalStateException();
230            }
231    
232            @NotNull
233            @Override
234            public Collection<FunctionDescriptor> getFunctions(@NotNull Name name, @NotNull LookupLocation location) {
235                throw new IllegalStateException();
236            }
237    
238            @NotNull
239            @Override
240            public Collection<PropertyDescriptor> getSyntheticExtensionProperties(
241                    @NotNull Collection<? extends JetType> receiverTypes, @NotNull Name name,
242                    @NotNull LookupLocation location
243            ) {
244                throw new IllegalStateException();
245            }
246    
247            @NotNull
248            @Override
249            public Collection<FunctionDescriptor> getSyntheticExtensionFunctions(
250                    @NotNull Collection<? extends JetType> receiverTypes, @NotNull Name name,
251                    @NotNull LookupLocation location
252            ) {
253                throw new IllegalStateException();
254            }
255    
256            @NotNull
257            @Override
258            public Collection<PropertyDescriptor> getSyntheticExtensionProperties(@NotNull Collection<? extends JetType> receiverTypes) {
259                throw new IllegalStateException();
260            }
261    
262            @NotNull
263            @Override
264            public Collection<FunctionDescriptor> getSyntheticExtensionFunctions(
265                    @NotNull Collection<? extends JetType> receiverTypes
266            ) {
267                throw new IllegalStateException();
268            }
269    
270            @NotNull
271            @Override
272            public DeclarationDescriptor getContainingDeclaration() {
273                return ERROR_MODULE;
274            }
275    
276            @NotNull
277            @Override
278            public Collection<DeclarationDescriptor> getDeclarationsByLabel(@NotNull Name labelName) {
279                throw new IllegalStateException();
280            }
281    
282            @NotNull
283            @Override
284            public Collection<DeclarationDescriptor> getDescriptors(
285                    @NotNull DescriptorKindFilter kindFilter, @NotNull Function1<? super Name, ? extends Boolean> nameFilter
286            ) {
287                throw new IllegalStateException();
288            }
289    
290            @NotNull
291            @Override
292            public Collection<DeclarationDescriptor> getAllDescriptors() {
293                throw new IllegalStateException();
294            }
295    
296            @NotNull
297            @Override
298            public List<ReceiverParameterDescriptor> getImplicitReceiversHierarchy() {
299                throw new IllegalStateException();
300            }
301    
302            @NotNull
303            @Override
304            public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
305                throw new IllegalStateException();
306            }
307    
308            @Override
309            public String toString() {
310                return "ThrowingScope{" + debugMessage + '}';
311            }
312    
313            @Override
314            public void printScopeStructure(@NotNull Printer p) {
315                p.println(getClass().getSimpleName(), ": ", debugMessage);
316            }
317        }
318    
319        private static final ErrorClassDescriptor ERROR_CLASS = new ErrorClassDescriptor(null);
320    
321        private static class ErrorClassDescriptor extends ClassDescriptorImpl {
322            public ErrorClassDescriptor(@Nullable String name) {
323                super(getErrorModule(), Name.special(name == null ? "<ERROR CLASS>" : "<ERROR CLASS: " + name + ">"),
324                      Modality.OPEN, Collections.<JetType>emptyList(), SourceElement.NO_SOURCE);
325    
326                ConstructorDescriptorImpl errorConstructor = ConstructorDescriptorImpl.create(this, Annotations.EMPTY, true, SourceElement.NO_SOURCE);
327                errorConstructor.initialize(Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>emptyList(),
328                                            Visibilities.INTERNAL);
329                JetScope memberScope = createErrorScope(getName().asString());
330                errorConstructor.setReturnType(
331                        new ErrorTypeImpl(
332                                TypeConstructorImpl.createForClass(
333                                        this, Annotations.EMPTY, false,
334                                        getName().asString(),
335                                        Collections.<TypeParameterDescriptorImpl>emptyList(),
336                                        Collections.singleton(KotlinBuiltIns.getInstance().getAnyType())
337                                ),
338                                memberScope
339                        )
340                );
341    
342                initialize(memberScope, Collections.<ConstructorDescriptor>singleton(errorConstructor), errorConstructor);
343            }
344    
345            @NotNull
346            @Override
347            public ClassDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
348                return this;
349            }
350    
351            @Override
352            public String toString() {
353                return getName().asString();
354            }
355    
356            @NotNull
357            @Override
358            public JetScope getMemberScope(@NotNull List<? extends TypeProjection> typeArguments) {
359                return createErrorScope("Error scope for class " + getName() + " with arguments: " + typeArguments);
360            }
361    
362            @NotNull
363            @Override
364            public JetScope getMemberScope(@NotNull TypeSubstitution typeSubstitution) {
365                return createErrorScope("Error scope for class " + getName() + " with arguments: " + typeSubstitution);
366            }
367        }
368    
369        @NotNull
370        public static ClassDescriptor createErrorClass(@NotNull String debugMessage) {
371            return new ErrorClassDescriptor(debugMessage);
372        }
373    
374        @NotNull
375        public static JetScope createErrorScope(@NotNull String debugMessage) {
376            return createErrorScope(debugMessage, false);
377        }
378    
379        @NotNull
380        public static JetScope createErrorScope(@NotNull String debugMessage, boolean throwExceptions) {
381            if (throwExceptions) {
382                return new ThrowingScope(debugMessage);
383            }
384            return new ErrorScope(debugMessage);
385        }
386    
387        private static final JetType ERROR_PROPERTY_TYPE = createErrorType("<ERROR PROPERTY TYPE>");
388        private static final PropertyDescriptor ERROR_PROPERTY = createErrorProperty();
389    
390        private static final Set<VariableDescriptor> ERROR_VARIABLE_GROUP = Collections.<VariableDescriptor>singleton(ERROR_PROPERTY);
391        private static final Set<PropertyDescriptor> ERROR_PROPERTY_GROUP = Collections.singleton(ERROR_PROPERTY);
392    
393        @NotNull
394        private static PropertyDescriptorImpl createErrorProperty() {
395            PropertyDescriptorImpl descriptor = PropertyDescriptorImpl.create(
396                    ERROR_CLASS,
397                    Annotations.EMPTY,
398                    Modality.OPEN,
399                    Visibilities.INTERNAL,
400                    true,
401                    Name.special("<ERROR PROPERTY>"),
402                    CallableMemberDescriptor.Kind.DECLARATION,
403                    SourceElement.NO_SOURCE,
404                    /*lateInit =*/ false
405            );
406            descriptor.setType(ERROR_PROPERTY_TYPE,
407                               Collections.<TypeParameterDescriptor>emptyList(),
408                               null,
409                               (JetType) null
410            );
411    
412            return descriptor;
413        }
414    
415        @NotNull
416        private static SimpleFunctionDescriptor createErrorFunction(@NotNull ErrorScope ownerScope) {
417            ErrorSimpleFunctionDescriptorImpl function = new ErrorSimpleFunctionDescriptorImpl(ERROR_CLASS, ownerScope);
418            function.initialize(
419                    null,
420                    null,
421                    Collections.<TypeParameterDescriptorImpl>emptyList(), // TODO
422                    Collections.<ValueParameterDescriptor>emptyList(), // TODO
423                    createErrorType("<ERROR FUNCTION RETURN TYPE>"),
424                    Modality.OPEN,
425                    Visibilities.INTERNAL
426            );
427            return function;
428        }
429    
430        @NotNull
431        public static JetType createErrorType(@NotNull String debugMessage) {
432            return createErrorTypeWithArguments(debugMessage, Collections.<TypeProjection>emptyList());
433        }
434    
435        @NotNull
436        public static JetType createErrorTypeWithCustomDebugName(@NotNull String debugName) {
437            return new ErrorTypeImpl(createErrorTypeConstructorWithCustomDebugName(debugName), createErrorScope(debugName));
438        }
439    
440        @NotNull
441        public static JetType createErrorTypeWithArguments(@NotNull String debugMessage, @NotNull List<TypeProjection> arguments) {
442            return new ErrorTypeImpl(createErrorTypeConstructor(debugMessage), createErrorScope(debugMessage), arguments);
443        }
444    
445        @NotNull
446        public static TypeConstructor createErrorTypeConstructor(@NotNull String debugMessage) {
447            return createErrorTypeConstructorWithCustomDebugName("[ERROR : " + debugMessage + "]");
448        }
449    
450        @NotNull
451        private static TypeConstructor createErrorTypeConstructorWithCustomDebugName(@NotNull String debugName) {
452            return TypeConstructorImpl.createForClass(ERROR_CLASS, Annotations.EMPTY, false, debugName,
453                                    Collections.<TypeParameterDescriptorImpl>emptyList(),
454                                    Collections.singleton(KotlinBuiltIns.getInstance().getAnyType()));
455        }
456    
457        public static boolean containsErrorType(@Nullable JetType type) {
458            if (type == null) return false;
459            if (type.isError()) return true;
460            for (TypeProjection projection : type.getArguments()) {
461                if (!projection.isStarProjection() && containsErrorType(projection.getType())) return true;
462            }
463            return false;
464        }
465    
466        public static boolean isError(@NotNull DeclarationDescriptor candidate) {
467            return isErrorClass(candidate) || isErrorClass(candidate.getContainingDeclaration()) || candidate == ERROR_MODULE;
468        }
469    
470        private static boolean isErrorClass(@Nullable DeclarationDescriptor candidate) {
471            return candidate instanceof ErrorClassDescriptor;
472        }
473    
474        @NotNull
475        public static TypeParameterDescriptor createErrorTypeParameter(int index, @NotNull String debugMessage) {
476            return TypeParameterDescriptorImpl.createWithDefaultBound(
477                    ERROR_CLASS,
478                    Annotations.EMPTY,
479                    false,
480                    Variance.INVARIANT,
481                    Name.special("<ERROR: " + debugMessage + ">"),
482                    index
483            );
484        }
485    
486        private static class ErrorTypeImpl implements JetType {
487            private final TypeConstructor constructor;
488            private final JetScope memberScope;
489            private final List<TypeProjection> arguments;
490    
491            private ErrorTypeImpl(
492                    @NotNull TypeConstructor constructor,
493                    @NotNull JetScope memberScope,
494                    @NotNull List<TypeProjection> arguments
495            ) {
496                this.constructor = constructor;
497                this.memberScope = memberScope;
498                this.arguments = arguments;
499            }
500    
501            private ErrorTypeImpl(@NotNull TypeConstructor constructor, @NotNull JetScope memberScope) {
502                this(constructor, memberScope, Collections.<TypeProjection>emptyList());
503            }
504    
505            @NotNull
506            @Override
507            public TypeConstructor getConstructor() {
508                return constructor;
509            }
510    
511            @NotNull
512            @Override
513            public List<TypeProjection> getArguments() {
514                return arguments;
515            }
516    
517            @NotNull
518            @Override
519            public TypeSubstitution getSubstitution() {
520                return new IndexedParametersSubstitution(constructor, arguments);
521            }
522    
523            @Override
524            public boolean isMarkedNullable() {
525                return false;
526            }
527    
528            @NotNull
529            @Override
530            public JetScope getMemberScope() {
531                return memberScope;
532            }
533    
534            @Override
535            public boolean isError() {
536                return true;
537            }
538    
539            @NotNull
540            @Override
541            public Annotations getAnnotations() {
542                return Annotations.EMPTY;
543            }
544    
545            @Nullable
546            @Override
547            public <T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass) {
548                return null;
549            }
550    
551            @NotNull
552            @Override
553            public TypeCapabilities getCapabilities() {
554                return TypeCapabilities.NONE.INSTANCE$;
555            }
556    
557            @Override
558            public String toString() {
559                return constructor.toString() + (arguments.isEmpty() ? "" : joinToString(arguments, ", ", "<", ">", -1, "...", null));
560            }
561        }
562    
563        @NotNull
564        public static ModuleDescriptor getErrorModule() {
565            return ERROR_MODULE;
566        }
567    
568        public static boolean isUninferredParameter(@Nullable JetType type) {
569            return type != null && type.getConstructor() instanceof UninferredParameterTypeConstructor;
570        }
571    
572        public static boolean containsUninferredParameter(@Nullable JetType type) {
573            return TypeUtils.containsSpecialType(type, new Function1<JetType, Boolean>() {
574                @Override
575                public Boolean invoke(JetType argumentType) {
576                    return isUninferredParameter(argumentType);
577                }
578            });
579        }
580    
581        @NotNull
582        public static JetType createUninferredParameterType(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
583            return new ErrorTypeImpl(
584                    new UninferredParameterTypeConstructor(typeParameterDescriptor),
585                    createErrorScope("Scope for error type for not inferred parameter: " + typeParameterDescriptor.getName()));
586        }
587    
588        public static class UninferredParameterTypeConstructor implements TypeConstructor {
589            private final TypeParameterDescriptor typeParameterDescriptor;
590            private final TypeConstructor errorTypeConstructor;
591    
592            private UninferredParameterTypeConstructor(@NotNull TypeParameterDescriptor descriptor) {
593                typeParameterDescriptor = descriptor;
594                errorTypeConstructor = createErrorTypeConstructorWithCustomDebugName("CANT_INFER_TYPE_PARAMETER: " + descriptor.getName());
595            }
596    
597            @NotNull
598            public TypeParameterDescriptor getTypeParameterDescriptor() {
599                return typeParameterDescriptor;
600            }
601    
602            @NotNull
603            @Override
604            public List<TypeParameterDescriptor> getParameters() {
605                return errorTypeConstructor.getParameters();
606            }
607    
608            @NotNull
609            @Override
610            public Collection<JetType> getSupertypes() {
611                return errorTypeConstructor.getSupertypes();
612            }
613    
614            @Override
615            public boolean isFinal() {
616                return errorTypeConstructor.isFinal();
617            }
618    
619            @Override
620            public boolean isDenotable() {
621                return errorTypeConstructor.isDenotable();
622            }
623    
624            @Nullable
625            @Override
626            public ClassifierDescriptor getDeclarationDescriptor() {
627                return errorTypeConstructor.getDeclarationDescriptor();
628            }
629    
630            @NotNull
631            @Override
632            public Annotations getAnnotations() {
633                return errorTypeConstructor.getAnnotations();
634            }
635        }
636    
637        public static boolean isFunctionPlaceholder(@Nullable JetType type) {
638            return type != null && type.getConstructor() instanceof FunctionPlaceholderTypeConstructor;
639        }
640    
641        @NotNull
642        public static JetType createFunctionPlaceholderType(@NotNull List<JetType> argumentTypes, boolean hasDeclaredArguments) {
643            return new ErrorTypeImpl(
644                    new FunctionPlaceholderTypeConstructor(argumentTypes, hasDeclaredArguments),
645                    createErrorScope("Scope for function placeholder type"));
646        }
647    
648        public static class FunctionPlaceholderTypeConstructor implements TypeConstructor {
649            private final TypeConstructor errorTypeConstructor;
650            private final List<JetType> argumentTypes;
651            private final boolean hasDeclaredArguments;
652    
653            private FunctionPlaceholderTypeConstructor(@NotNull List<JetType> argumentTypes, boolean hasDeclaredArguments) {
654                errorTypeConstructor = createErrorTypeConstructorWithCustomDebugName("PLACEHOLDER_FUNCTION_TYPE" + argumentTypes);
655                this.argumentTypes = argumentTypes;
656                this.hasDeclaredArguments = hasDeclaredArguments;
657            }
658    
659            @NotNull
660            public List<JetType> getArgumentTypes() {
661                return argumentTypes;
662            }
663    
664            public boolean hasDeclaredArguments() {
665                return hasDeclaredArguments;
666            }
667    
668            @NotNull
669            @Override
670            public List<TypeParameterDescriptor> getParameters() {
671                return errorTypeConstructor.getParameters();
672            }
673    
674            @NotNull
675            @Override
676            public Collection<JetType> getSupertypes() {
677                return errorTypeConstructor.getSupertypes();
678            }
679    
680            @Override
681            public boolean isFinal() {
682                return errorTypeConstructor.isFinal();
683            }
684    
685            @Override
686            public boolean isDenotable() {
687                return errorTypeConstructor.isDenotable();
688            }
689    
690            @Nullable
691            @Override
692            public ClassifierDescriptor getDeclarationDescriptor() {
693                return errorTypeConstructor.getDeclarationDescriptor();
694            }
695    
696            @NotNull
697            @Override
698            public Annotations getAnnotations() {
699                return errorTypeConstructor.getAnnotations();
700            }
701    
702            @Override
703            public String toString() {
704                return errorTypeConstructor.toString();
705            }
706        }
707    
708        private ErrorUtils() {}
709    }