001    /*
002     * Copyright 2010-2013 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.jet.lang.types;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.annotations.Nullable;
021    import org.jetbrains.jet.lang.ModuleConfiguration;
022    import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
023    import org.jetbrains.jet.lang.descriptors.*;
024    import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
025    import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl;
026    import org.jetbrains.jet.lang.descriptors.impl.PropertyDescriptorImpl;
027    import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
028    import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl;
029    import org.jetbrains.jet.lang.resolve.ImportPath;
030    import org.jetbrains.jet.lang.resolve.name.LabelName;
031    import org.jetbrains.jet.lang.resolve.name.Name;
032    import org.jetbrains.jet.lang.resolve.scopes.JetScope;
033    import org.jetbrains.jet.lang.types.error.ErrorClassDescriptor;
034    import org.jetbrains.jet.lang.types.error.ErrorSimpleFunctionDescriptorImpl;
035    import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
036    
037    import java.util.*;
038    
039    import static org.jetbrains.jet.lang.types.TypeUtils.noExpectedType;
040    
041    public class ErrorUtils {
042    
043        private static final ModuleDescriptor ERROR_MODULE;
044        static {
045            ModuleDescriptorImpl module = new ModuleDescriptorImpl(
046                    Name.special("<ERROR MODULE>"),
047                    Collections.<ImportPath>emptyList(),
048                    PlatformToKotlinClassMap.EMPTY
049            );
050            module.setModuleConfiguration(ModuleConfiguration.EMPTY);
051            ERROR_MODULE = module;
052        }
053    
054        public static boolean containsErrorType(@NotNull FunctionDescriptor function) {
055            if (containsErrorType(function.getReturnType())) {
056                return true;
057            }
058            ReceiverParameterDescriptor receiverParameter = function.getReceiverParameter();
059            if (receiverParameter != null && containsErrorType(receiverParameter.getType())) {
060                return true;
061            }
062            for (ValueParameterDescriptor parameter : function.getValueParameters()) {
063                if (containsErrorType(parameter.getType())) {
064                    return true;
065                }
066            }
067            for (TypeParameterDescriptor parameter : function.getTypeParameters()) {
068                for (JetType upperBound : parameter.getUpperBounds()) {
069                    if (containsErrorType(upperBound)) {
070                        return true;
071                    }
072                }
073            }
074    
075            return false;
076        }
077    
078    
079        public static class ErrorScope implements JetScope {
080    
081            private final String debugMessage;
082    
083            private ErrorScope(String debugMessage) {
084                this.debugMessage = debugMessage;
085            }
086    
087            @Override
088            public ClassifierDescriptor getClassifier(@NotNull Name name) {
089                return ERROR_CLASS;
090            }
091    
092            @Override
093            public ClassDescriptor getObjectDescriptor(@NotNull Name name) {
094                return ERROR_CLASS;
095            }
096    
097            @NotNull
098            @Override
099            public Set<ClassDescriptor> getObjectDescriptors() {
100                return Collections.emptySet();
101            }
102    
103            @NotNull
104            @Override
105            public Set<VariableDescriptor> getProperties(@NotNull Name name) {
106                return ERROR_PROPERTY_GROUP;
107            }
108    
109            @Override
110            public VariableDescriptor getLocalVariable(@NotNull Name name) {
111                return ERROR_PROPERTY;
112            }
113    
114            @Override
115            public NamespaceDescriptor getNamespace(@NotNull Name name) {
116                return null; // TODO : review
117            }
118    
119            @NotNull
120            @Override
121            public List<ReceiverParameterDescriptor> getImplicitReceiversHierarchy() {
122                return Collections.emptyList();
123            }
124    
125            @NotNull
126            @Override
127            public Set<FunctionDescriptor> getFunctions(@NotNull Name name) {
128                return Collections.<FunctionDescriptor>singleton(createErrorFunction(this));
129            }
130    
131            @NotNull
132            @Override
133            public DeclarationDescriptor getContainingDeclaration() {
134                return ERROR_MODULE;
135            }
136    
137            @NotNull
138            @Override
139            public Collection<DeclarationDescriptor> getDeclarationsByLabel(LabelName labelName) {
140                return Collections.emptyList();
141            }
142    
143            @Override
144            public PropertyDescriptor getPropertyByFieldReference(@NotNull Name fieldName) {
145                return null; // TODO : review
146            }
147    
148            @NotNull
149            @Override
150            public Collection<DeclarationDescriptor> getAllDescriptors() {
151                return Collections.emptyList();
152            }
153    
154            @NotNull
155            @Override
156            public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
157                return Collections.emptyList();
158            }
159    
160            @Override
161            public String toString() {
162                return "ErrorScope{" + debugMessage + '}';
163            }
164        }
165    
166        private static class ThrowingScope implements JetScope {
167            private final String debugMessage;
168    
169            private ThrowingScope(String message) {
170                debugMessage = message;
171            }
172    
173            @Nullable
174            @Override
175            public ClassifierDescriptor getClassifier(@NotNull Name name) {
176                throw new IllegalStateException();
177            }
178    
179            @Nullable
180            @Override
181            public ClassDescriptor getObjectDescriptor(@NotNull Name name) {
182                throw new IllegalStateException();
183            }
184    
185            @NotNull
186            @Override
187            public Collection<ClassDescriptor> getObjectDescriptors() {
188                throw new IllegalStateException();
189            }
190    
191            @Nullable
192            @Override
193            public NamespaceDescriptor getNamespace(@NotNull Name name) {
194                throw new IllegalStateException();
195            }
196    
197            @NotNull
198            @Override
199            public Collection<VariableDescriptor> getProperties(@NotNull Name name) {
200                throw new IllegalStateException();
201            }
202    
203            @Nullable
204            @Override
205            public VariableDescriptor getLocalVariable(@NotNull Name name) {
206                throw new IllegalStateException();
207            }
208    
209            @NotNull
210            @Override
211            public Collection<FunctionDescriptor> getFunctions(@NotNull Name name) {
212                throw new IllegalStateException();
213            }
214    
215            @NotNull
216            @Override
217            public DeclarationDescriptor getContainingDeclaration() {
218                return ERROR_MODULE;
219            }
220    
221            @NotNull
222            @Override
223            public Collection<DeclarationDescriptor> getDeclarationsByLabel(@NotNull LabelName labelName) {
224                throw new IllegalStateException();
225            }
226    
227            @Nullable
228            @Override
229            public PropertyDescriptor getPropertyByFieldReference(@NotNull Name fieldName) {
230                throw new IllegalStateException();
231            }
232    
233            @NotNull
234            @Override
235            public Collection<DeclarationDescriptor> getAllDescriptors() {
236                throw new IllegalStateException();
237            }
238    
239            @NotNull
240            @Override
241            public List<ReceiverParameterDescriptor> getImplicitReceiversHierarchy() {
242                throw new IllegalStateException();
243            }
244    
245            @NotNull
246            @Override
247            public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
248                throw new IllegalStateException();
249            }
250    
251            @Override
252            public String toString() {
253                return "ThrowingScope{" + debugMessage + '}';
254            }
255        }
256    
257        private static final ErrorClassDescriptor ERROR_CLASS = new ErrorClassDescriptor("");
258    
259        private static final class ErrorTypeConstructor extends TypeConstructorImpl {
260            private ErrorTypeConstructor(
261                    @Nullable ClassifierDescriptor classifierDescriptor,
262                    @NotNull List<AnnotationDescriptor> annotations,
263                    boolean sealed,
264                    @NotNull String debugName,
265                    @NotNull List<? extends TypeParameterDescriptor> parameters,
266                    @NotNull Collection<JetType> supertypes
267            ) {
268                super(classifierDescriptor, annotations, sealed, debugName, parameters, supertypes);
269            }
270        }
271    
272        private static final Set<ConstructorDescriptor> ERROR_CONSTRUCTOR_GROUP = Collections.singleton(createErrorConstructor(0, Collections.<JetType>emptyList()));
273    
274        private static final ConstructorDescriptor ERROR_CONSTRUCTOR = new ConstructorDescriptorImpl(ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), true);
275    
276        static {
277            ERROR_CLASS.initializeErrorClass();
278        }
279        @NotNull
280        public static Set<ConstructorDescriptor> getErrorConstructorGroup() {
281            return ERROR_CONSTRUCTOR_GROUP;
282        }
283    
284        public static ConstructorDescriptor getErrorConstructor() {
285            return ERROR_CONSTRUCTOR;
286        }
287    
288        public static JetScope createErrorScope(String debugMessage) {
289            return createErrorScope(debugMessage, false);
290        }
291    
292        public static JetScope createErrorScope(String debugMessage, boolean throwExceptions) {
293            if (throwExceptions) {
294                return new ThrowingScope(debugMessage);
295            }
296            return new ErrorScope(debugMessage);
297        }
298    
299        private static final JetType ERROR_PROPERTY_TYPE = createErrorType("<ERROR PROPERTY TYPE>");
300        private static final VariableDescriptor ERROR_PROPERTY = new PropertyDescriptorImpl(
301                ERROR_CLASS,
302                Collections.<AnnotationDescriptor>emptyList(),
303                Modality.OPEN,
304                Visibilities.INTERNAL,
305                true,
306                null,
307                ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER,
308                Name.special("<ERROR PROPERTY>"),
309                ERROR_PROPERTY_TYPE,
310                CallableMemberDescriptor.Kind.DECLARATION);
311        private static final Set<VariableDescriptor> ERROR_PROPERTY_GROUP = Collections.singleton(ERROR_PROPERTY);
312    
313        private static SimpleFunctionDescriptor createErrorFunction(ErrorScope ownerScope) {
314            ErrorSimpleFunctionDescriptorImpl function = new ErrorSimpleFunctionDescriptorImpl(ownerScope);
315            function.initialize(
316                    null,
317                    ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER,
318                    Collections.<TypeParameterDescriptorImpl>emptyList(), // TODO
319                    Collections.<ValueParameterDescriptor>emptyList(), // TODO
320                    createErrorType("<ERROR FUNCTION RETURN TYPE>"),
321                    Modality.OPEN,
322                    Visibilities.INTERNAL,
323                    /*isInline = */ false
324            );
325            return function;
326        }
327    
328        public static ConstructorDescriptor createErrorConstructor(int typeParameterCount, List<JetType> positionedValueParameterTypes) {
329            ConstructorDescriptorImpl r = new ConstructorDescriptorImpl(ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), false);
330            r.initialize(
331                    Collections.<TypeParameterDescriptor>emptyList(), // TODO
332                    Collections.<ValueParameterDescriptor>emptyList(), // TODO
333                    Visibilities.INTERNAL
334            );
335            r.setReturnType(createErrorType("<ERROR RETURN TYPE>"));
336            return r;
337        }
338    
339        private static final JetType ERROR_PARAMETER_TYPE = createErrorType("<ERROR VALUE_PARAMETER TYPE>");
340        private static List<ValueParameterDescriptor> getValueParameters(FunctionDescriptor functionDescriptor, List<JetType> argumentTypes) {
341            List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
342            for (int i = 0, argumentTypesSize = argumentTypes.size(); i < argumentTypesSize; i++) {
343                result.add(new ValueParameterDescriptorImpl(
344                        functionDescriptor,
345                        i,
346                        Collections.<AnnotationDescriptor>emptyList(),
347                        Name.special("<ERROR VALUE_PARAMETER>"),
348                        ERROR_PARAMETER_TYPE,
349                        false,
350                        null));
351            }
352            return result;
353        }
354    
355        @NotNull
356        public static JetType createErrorType(String debugMessage) {
357            return createErrorType(debugMessage, createErrorScope(debugMessage));
358        }
359    
360        private static JetType createErrorType(String debugMessage, JetScope memberScope) {
361            return createErrorTypeWithCustomDebugName(memberScope, "[ERROR : " + debugMessage + "]");
362        }
363    
364        @NotNull
365        public static JetType createErrorTypeWithCustomDebugName(String debugName) {
366            return createErrorTypeWithCustomDebugName(createErrorScope(debugName), debugName);
367        }
368    
369        private static JetType createErrorTypeWithCustomDebugName(JetScope memberScope, String debugName) {
370            TypeConstructorImpl constructor =
371                    new ErrorTypeConstructor(ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), false, debugName,
372                                            Collections.<TypeParameterDescriptorImpl>emptyList(),
373                                            Collections.singleton(KotlinBuiltIns.getInstance().getAnyType()));
374            return new ErrorTypeImpl(constructor, memberScope);
375        }
376    
377        public static JetType createWrongVarianceErrorType(TypeProjection value) {
378            return createErrorType(value + " is not allowed here", value.getType().getMemberScope());
379        }
380    
381        @NotNull
382        public static ClassDescriptor getErrorClass() {
383            return ERROR_CLASS;
384        }
385    
386        public static boolean isError(@NotNull TypeConstructor typeConstructor) {
387            return typeConstructor == ERROR_CLASS.getTypeConstructor() || typeConstructor instanceof ErrorTypeConstructor;
388        }
389    
390        public static boolean isErrorType(@NotNull JetType type) {
391            return !noExpectedType(type) && !(type instanceof NamespaceType) &&
392                   (
393                        (type instanceof DeferredType && (((DeferredType) type).getActualType() == null
394                                                          || isErrorType(((DeferredType) type).getActualType()))) ||
395                        type instanceof ErrorTypeImpl ||
396                        isError(type.getConstructor())
397                   );
398        }
399    
400        public static boolean containsErrorType(@Nullable JetType type) {
401            if (type == null) return false;
402            if (type instanceof NamespaceType) return false;
403            if (isErrorType(type)) return true;
404            for (TypeProjection projection : type.getArguments()) {
405                if (containsErrorType(projection.getType())) return true;
406            }
407            return false;
408        }
409    
410        public static boolean isError(@NotNull DeclarationDescriptor candidate) {
411            return isErrorClass(candidate) || isErrorClass(candidate.getContainingDeclaration()) || candidate == ERROR_MODULE;
412        }
413    
414        private static boolean isErrorClass(@Nullable DeclarationDescriptor candidate) {
415            return candidate instanceof ErrorClassDescriptor;
416        }
417    
418        @NotNull
419        public static ErrorClassDescriptor createErrorClass(@NotNull String debugMessage) {
420            ErrorClassDescriptor result = new ErrorClassDescriptor(debugMessage);
421            result.initializeErrorClass();
422            return result;
423        }
424    
425        private static class ErrorTypeImpl implements JetType {
426    
427            private final TypeConstructor constructor;
428    
429            private final JetScope memberScope;
430            private ErrorTypeImpl(TypeConstructor constructor, JetScope memberScope) {
431                this.constructor = constructor;
432                this.memberScope = memberScope;
433            }
434    
435            @NotNull
436            @Override
437            public TypeConstructor getConstructor() {
438                return constructor;
439            }
440    
441            @NotNull
442            @Override
443            public List<TypeProjection> getArguments() {
444                return Collections.emptyList();
445            }
446    
447            @Override
448            public boolean isNullable() {
449                return false;
450            }
451    
452            @NotNull
453            @Override
454            public JetScope getMemberScope() {
455                return memberScope;
456            }
457    
458            @Override
459            public List<AnnotationDescriptor> getAnnotations() {
460                return Collections.emptyList();
461            }
462    
463            @Override
464            public String toString() {
465                return constructor.toString();
466            }
467        }
468    
469        public static ModuleDescriptor getErrorModule() {
470            return ERROR_MODULE;
471        }
472    
473        private ErrorUtils() {}
474    }