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                    /* isConst = */ false
406            );
407            descriptor.setType(ERROR_PROPERTY_TYPE,
408                               Collections.<TypeParameterDescriptor>emptyList(),
409                               null,
410                               (JetType) null
411            );
412    
413            return descriptor;
414        }
415    
416        @NotNull
417        private static SimpleFunctionDescriptor createErrorFunction(@NotNull ErrorScope ownerScope) {
418            ErrorSimpleFunctionDescriptorImpl function = new ErrorSimpleFunctionDescriptorImpl(ERROR_CLASS, ownerScope);
419            function.initialize(
420                    null,
421                    null,
422                    Collections.<TypeParameterDescriptorImpl>emptyList(), // TODO
423                    Collections.<ValueParameterDescriptor>emptyList(), // TODO
424                    createErrorType("<ERROR FUNCTION RETURN TYPE>"),
425                    Modality.OPEN,
426                    Visibilities.INTERNAL,
427                    false
428            );
429            return function;
430        }
431    
432        @NotNull
433        public static JetType createErrorType(@NotNull String debugMessage) {
434            return createErrorTypeWithArguments(debugMessage, Collections.<TypeProjection>emptyList());
435        }
436    
437        @NotNull
438        public static JetType createErrorTypeWithCustomDebugName(@NotNull String debugName) {
439            return new ErrorTypeImpl(createErrorTypeConstructorWithCustomDebugName(debugName), createErrorScope(debugName));
440        }
441    
442        @NotNull
443        public static JetType createErrorTypeWithArguments(@NotNull String debugMessage, @NotNull List<TypeProjection> arguments) {
444            return new ErrorTypeImpl(createErrorTypeConstructor(debugMessage), createErrorScope(debugMessage), arguments);
445        }
446    
447        @NotNull
448        public static TypeConstructor createErrorTypeConstructor(@NotNull String debugMessage) {
449            return createErrorTypeConstructorWithCustomDebugName("[ERROR : " + debugMessage + "]");
450        }
451    
452        @NotNull
453        private static TypeConstructor createErrorTypeConstructorWithCustomDebugName(@NotNull String debugName) {
454            return TypeConstructorImpl.createForClass(ERROR_CLASS, Annotations.EMPTY, false, debugName,
455                                    Collections.<TypeParameterDescriptorImpl>emptyList(),
456                                    Collections.singleton(KotlinBuiltIns.getInstance().getAnyType()));
457        }
458    
459        public static boolean containsErrorType(@Nullable JetType type) {
460            if (type == null) return false;
461            if (type.isError()) return true;
462            for (TypeProjection projection : type.getArguments()) {
463                if (!projection.isStarProjection() && containsErrorType(projection.getType())) return true;
464            }
465            return false;
466        }
467    
468        public static boolean isError(@NotNull DeclarationDescriptor candidate) {
469            return isErrorClass(candidate) || isErrorClass(candidate.getContainingDeclaration()) || candidate == ERROR_MODULE;
470        }
471    
472        private static boolean isErrorClass(@Nullable DeclarationDescriptor candidate) {
473            return candidate instanceof ErrorClassDescriptor;
474        }
475    
476        @NotNull
477        public static TypeParameterDescriptor createErrorTypeParameter(int index, @NotNull String debugMessage) {
478            return TypeParameterDescriptorImpl.createWithDefaultBound(
479                    ERROR_CLASS,
480                    Annotations.EMPTY,
481                    false,
482                    Variance.INVARIANT,
483                    Name.special("<ERROR: " + debugMessage + ">"),
484                    index
485            );
486        }
487    
488        private static class ErrorTypeImpl implements JetType {
489            private final TypeConstructor constructor;
490            private final JetScope memberScope;
491            private final List<TypeProjection> arguments;
492    
493            private ErrorTypeImpl(
494                    @NotNull TypeConstructor constructor,
495                    @NotNull JetScope memberScope,
496                    @NotNull List<TypeProjection> arguments
497            ) {
498                this.constructor = constructor;
499                this.memberScope = memberScope;
500                this.arguments = arguments;
501            }
502    
503            private ErrorTypeImpl(@NotNull TypeConstructor constructor, @NotNull JetScope memberScope) {
504                this(constructor, memberScope, Collections.<TypeProjection>emptyList());
505            }
506    
507            @NotNull
508            @Override
509            public TypeConstructor getConstructor() {
510                return constructor;
511            }
512    
513            @NotNull
514            @Override
515            public List<TypeProjection> getArguments() {
516                return arguments;
517            }
518    
519            @NotNull
520            @Override
521            public TypeSubstitution getSubstitution() {
522                return new IndexedParametersSubstitution(constructor, arguments);
523            }
524    
525            @Override
526            public boolean isMarkedNullable() {
527                return false;
528            }
529    
530            @NotNull
531            @Override
532            public JetScope getMemberScope() {
533                return memberScope;
534            }
535    
536            @Override
537            public boolean isError() {
538                return true;
539            }
540    
541            @NotNull
542            @Override
543            public Annotations getAnnotations() {
544                return Annotations.EMPTY;
545            }
546    
547            @Nullable
548            @Override
549            public <T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass) {
550                return null;
551            }
552    
553            @NotNull
554            @Override
555            public TypeCapabilities getCapabilities() {
556                return TypeCapabilities.NONE.INSTANCE$;
557            }
558    
559            @Override
560            public String toString() {
561                return constructor.toString() + (arguments.isEmpty() ? "" : joinToString(arguments, ", ", "<", ">", -1, "...", null));
562            }
563        }
564    
565        @NotNull
566        public static ModuleDescriptor getErrorModule() {
567            return ERROR_MODULE;
568        }
569    
570        public static boolean isUninferredParameter(@Nullable JetType type) {
571            return type != null && type.getConstructor() instanceof UninferredParameterTypeConstructor;
572        }
573    
574        public static boolean containsUninferredParameter(@Nullable JetType type) {
575            return TypeUtils.containsSpecialType(type, new Function1<JetType, Boolean>() {
576                @Override
577                public Boolean invoke(JetType argumentType) {
578                    return isUninferredParameter(argumentType);
579                }
580            });
581        }
582    
583        @NotNull
584        public static JetType createUninferredParameterType(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
585            return new ErrorTypeImpl(
586                    new UninferredParameterTypeConstructor(typeParameterDescriptor),
587                    createErrorScope("Scope for error type for not inferred parameter: " + typeParameterDescriptor.getName()));
588        }
589    
590        public static class UninferredParameterTypeConstructor implements TypeConstructor {
591            private final TypeParameterDescriptor typeParameterDescriptor;
592            private final TypeConstructor errorTypeConstructor;
593    
594            private UninferredParameterTypeConstructor(@NotNull TypeParameterDescriptor descriptor) {
595                typeParameterDescriptor = descriptor;
596                errorTypeConstructor = createErrorTypeConstructorWithCustomDebugName("CANT_INFER_TYPE_PARAMETER: " + descriptor.getName());
597            }
598    
599            @NotNull
600            public TypeParameterDescriptor getTypeParameterDescriptor() {
601                return typeParameterDescriptor;
602            }
603    
604            @NotNull
605            @Override
606            public List<TypeParameterDescriptor> getParameters() {
607                return errorTypeConstructor.getParameters();
608            }
609    
610            @NotNull
611            @Override
612            public Collection<JetType> getSupertypes() {
613                return errorTypeConstructor.getSupertypes();
614            }
615    
616            @Override
617            public boolean isFinal() {
618                return errorTypeConstructor.isFinal();
619            }
620    
621            @Override
622            public boolean isDenotable() {
623                return errorTypeConstructor.isDenotable();
624            }
625    
626            @Nullable
627            @Override
628            public ClassifierDescriptor getDeclarationDescriptor() {
629                return errorTypeConstructor.getDeclarationDescriptor();
630            }
631    
632            @NotNull
633            @Override
634            public Annotations getAnnotations() {
635                return errorTypeConstructor.getAnnotations();
636            }
637        }
638    
639        public static boolean isFunctionPlaceholder(@Nullable JetType type) {
640            return type != null && type.getConstructor() instanceof FunctionPlaceholderTypeConstructor;
641        }
642    
643        @NotNull
644        public static JetType createFunctionPlaceholderType(@NotNull List<JetType> argumentTypes, boolean hasDeclaredArguments) {
645            return new ErrorTypeImpl(
646                    new FunctionPlaceholderTypeConstructor(argumentTypes, hasDeclaredArguments),
647                    createErrorScope("Scope for function placeholder type"));
648        }
649    
650        public static class FunctionPlaceholderTypeConstructor implements TypeConstructor {
651            private final TypeConstructor errorTypeConstructor;
652            private final List<JetType> argumentTypes;
653            private final boolean hasDeclaredArguments;
654    
655            private FunctionPlaceholderTypeConstructor(@NotNull List<JetType> argumentTypes, boolean hasDeclaredArguments) {
656                errorTypeConstructor = createErrorTypeConstructorWithCustomDebugName("PLACEHOLDER_FUNCTION_TYPE" + argumentTypes);
657                this.argumentTypes = argumentTypes;
658                this.hasDeclaredArguments = hasDeclaredArguments;
659            }
660    
661            @NotNull
662            public List<JetType> getArgumentTypes() {
663                return argumentTypes;
664            }
665    
666            public boolean hasDeclaredArguments() {
667                return hasDeclaredArguments;
668            }
669    
670            @NotNull
671            @Override
672            public List<TypeParameterDescriptor> getParameters() {
673                return errorTypeConstructor.getParameters();
674            }
675    
676            @NotNull
677            @Override
678            public Collection<JetType> getSupertypes() {
679                return errorTypeConstructor.getSupertypes();
680            }
681    
682            @Override
683            public boolean isFinal() {
684                return errorTypeConstructor.isFinal();
685            }
686    
687            @Override
688            public boolean isDenotable() {
689                return errorTypeConstructor.isDenotable();
690            }
691    
692            @Nullable
693            @Override
694            public ClassifierDescriptor getDeclarationDescriptor() {
695                return errorTypeConstructor.getDeclarationDescriptor();
696            }
697    
698            @NotNull
699            @Override
700            public Annotations getAnnotations() {
701                return errorTypeConstructor.getAnnotations();
702            }
703    
704            @Override
705            public String toString() {
706                return errorTypeConstructor.toString();
707            }
708        }
709    
710        private ErrorUtils() {}
711    }