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