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.PropertyDescriptorImpl;
026    import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
027    import org.jetbrains.jet.lang.resolve.ImportPath;
028    import org.jetbrains.jet.lang.resolve.name.LabelName;
029    import org.jetbrains.jet.lang.resolve.name.Name;
030    import org.jetbrains.jet.lang.resolve.scopes.JetScope;
031    import org.jetbrains.jet.lang.types.error.ErrorClassDescriptor;
032    import org.jetbrains.jet.lang.types.error.ErrorSimpleFunctionDescriptorImpl;
033    import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
034    import org.jetbrains.jet.utils.Printer;
035    
036    import java.util.Collection;
037    import java.util.Collections;
038    import java.util.List;
039    import java.util.Set;
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            private final String debugMessage;
081    
082            private ErrorScope(@NotNull String debugMessage) {
083                this.debugMessage = debugMessage;
084            }
085    
086            @Override
087            public ClassifierDescriptor getClassifier(@NotNull Name name) {
088                return ERROR_CLASS;
089            }
090    
091            @NotNull
092            @Override
093            public Set<VariableDescriptor> getProperties(@NotNull Name name) {
094                return ERROR_PROPERTY_GROUP;
095            }
096    
097            @Override
098            public VariableDescriptor getLocalVariable(@NotNull Name name) {
099                return ERROR_PROPERTY;
100            }
101    
102            @Override
103            public NamespaceDescriptor getNamespace(@NotNull Name name) {
104                return null; // TODO : review
105            }
106    
107            @NotNull
108            @Override
109            public List<ReceiverParameterDescriptor> getImplicitReceiversHierarchy() {
110                return Collections.emptyList();
111            }
112    
113            @NotNull
114            @Override
115            public Set<FunctionDescriptor> getFunctions(@NotNull Name name) {
116                return Collections.<FunctionDescriptor>singleton(createErrorFunction(this));
117            }
118    
119            @NotNull
120            @Override
121            public DeclarationDescriptor getContainingDeclaration() {
122                return ERROR_MODULE;
123            }
124    
125            @NotNull
126            @Override
127            public Collection<DeclarationDescriptor> getDeclarationsByLabel(@NotNull LabelName labelName) {
128                return Collections.emptyList();
129            }
130    
131            @NotNull
132            @Override
133            public Collection<DeclarationDescriptor> getAllDescriptors() {
134                return Collections.emptyList();
135            }
136    
137            @NotNull
138            @Override
139            public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
140                return Collections.emptyList();
141            }
142    
143            @Override
144            public String toString() {
145                return "ErrorScope{" + debugMessage + '}';
146            }
147    
148            @Override
149            public void printScopeStructure(@NotNull Printer p) {
150                p.println(getClass().getSimpleName(), ": ", debugMessage);
151            }
152        }
153    
154        private static class ThrowingScope implements JetScope {
155            private final String debugMessage;
156    
157            private ThrowingScope(@NotNull String message) {
158                debugMessage = message;
159            }
160    
161            @Nullable
162            @Override
163            public ClassifierDescriptor getClassifier(@NotNull Name name) {
164                throw new IllegalStateException();
165            }
166    
167            @Nullable
168            @Override
169            public NamespaceDescriptor getNamespace(@NotNull Name name) {
170                throw new IllegalStateException();
171            }
172    
173            @NotNull
174            @Override
175            public Collection<VariableDescriptor> getProperties(@NotNull Name name) {
176                throw new IllegalStateException();
177            }
178    
179            @Nullable
180            @Override
181            public VariableDescriptor getLocalVariable(@NotNull Name name) {
182                throw new IllegalStateException();
183            }
184    
185            @NotNull
186            @Override
187            public Collection<FunctionDescriptor> getFunctions(@NotNull Name name) {
188                throw new IllegalStateException();
189            }
190    
191            @NotNull
192            @Override
193            public DeclarationDescriptor getContainingDeclaration() {
194                return ERROR_MODULE;
195            }
196    
197            @NotNull
198            @Override
199            public Collection<DeclarationDescriptor> getDeclarationsByLabel(@NotNull LabelName labelName) {
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            @Override
227            public void printScopeStructure(@NotNull Printer p) {
228                p.println(getClass().getSimpleName(), ": ", debugMessage);
229            }
230        }
231    
232        private static final ErrorClassDescriptor ERROR_CLASS = new ErrorClassDescriptor("");
233    
234        @NotNull
235        public static JetScope createErrorScope(@NotNull String debugMessage) {
236            return createErrorScope(debugMessage, false);
237        }
238    
239        @NotNull
240        public static JetScope createErrorScope(@NotNull String debugMessage, boolean throwExceptions) {
241            if (throwExceptions) {
242                return new ThrowingScope(debugMessage);
243            }
244            return new ErrorScope(debugMessage);
245        }
246    
247        private static final JetType ERROR_PROPERTY_TYPE = createErrorType("<ERROR PROPERTY TYPE>");
248        private static final VariableDescriptor ERROR_PROPERTY = new PropertyDescriptorImpl(
249                ERROR_CLASS,
250                Collections.<AnnotationDescriptor>emptyList(),
251                Modality.OPEN,
252                Visibilities.INTERNAL,
253                true,
254                null,
255                ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER,
256                Name.special("<ERROR PROPERTY>"),
257                ERROR_PROPERTY_TYPE,
258                CallableMemberDescriptor.Kind.DECLARATION);
259        private static final Set<VariableDescriptor> ERROR_PROPERTY_GROUP = Collections.singleton(ERROR_PROPERTY);
260    
261        @NotNull
262        private static SimpleFunctionDescriptor createErrorFunction(@NotNull ErrorScope ownerScope) {
263            ErrorSimpleFunctionDescriptorImpl function = new ErrorSimpleFunctionDescriptorImpl(ownerScope);
264            function.initialize(
265                    null,
266                    ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER,
267                    Collections.<TypeParameterDescriptorImpl>emptyList(), // TODO
268                    Collections.<ValueParameterDescriptor>emptyList(), // TODO
269                    createErrorType("<ERROR FUNCTION RETURN TYPE>"),
270                    Modality.OPEN,
271                    Visibilities.INTERNAL
272            );
273            return function;
274        }
275    
276        @NotNull
277        public static JetType createErrorType(@NotNull String debugMessage) {
278            return new ErrorTypeImpl(createErrorTypeConstructor(debugMessage), createErrorScope(debugMessage));
279        }
280    
281        @NotNull
282        public static JetType createErrorTypeWithCustomDebugName(@NotNull String debugName) {
283            return new ErrorTypeImpl(createErrorTypeConstructorWithCustomDebugName(debugName), createErrorScope(debugName));
284        }
285    
286        @NotNull
287        public static TypeConstructor createErrorTypeConstructor(@NotNull String debugMessage) {
288            return createErrorTypeConstructorWithCustomDebugName("[ERROR : " + debugMessage + "]");
289        }
290    
291        @NotNull
292        private static TypeConstructor createErrorTypeConstructorWithCustomDebugName(@NotNull String debugName) {
293            return new TypeConstructorImpl(ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), false, debugName,
294                                    Collections.<TypeParameterDescriptorImpl>emptyList(),
295                                    Collections.singleton(KotlinBuiltIns.getInstance().getAnyType()));
296        }
297    
298        @NotNull
299        public static ClassDescriptor getErrorClass() {
300            return ERROR_CLASS;
301        }
302    
303        public static boolean containsErrorType(@Nullable JetType type) {
304            if (type == null) return false;
305            if (type instanceof NamespaceType) return false;
306            if (type.isError()) return true;
307            for (TypeProjection projection : type.getArguments()) {
308                if (containsErrorType(projection.getType())) return true;
309            }
310            return false;
311        }
312    
313        public static boolean isError(@NotNull DeclarationDescriptor candidate) {
314            return isErrorClass(candidate) || isErrorClass(candidate.getContainingDeclaration()) || candidate == ERROR_MODULE;
315        }
316    
317        private static boolean isErrorClass(@Nullable DeclarationDescriptor candidate) {
318            return candidate instanceof ErrorClassDescriptor;
319        }
320    
321        private static class ErrorTypeImpl implements JetType {
322            private final TypeConstructor constructor;
323            private final JetScope memberScope;
324    
325            private ErrorTypeImpl(@NotNull TypeConstructor constructor, @NotNull JetScope memberScope) {
326                this.constructor = constructor;
327                this.memberScope = memberScope;
328            }
329    
330            @NotNull
331            @Override
332            public TypeConstructor getConstructor() {
333                return constructor;
334            }
335    
336            @NotNull
337            @Override
338            public List<TypeProjection> getArguments() {
339                return Collections.emptyList();
340            }
341    
342            @Override
343            public boolean isNullable() {
344                return false;
345            }
346    
347            @NotNull
348            @Override
349            public JetScope getMemberScope() {
350                return memberScope;
351            }
352    
353            @Override
354            public boolean isError() {
355                return true;
356            }
357    
358            @NotNull
359            @Override
360            public List<AnnotationDescriptor> getAnnotations() {
361                return Collections.emptyList();
362            }
363    
364            @Override
365            public String toString() {
366                return constructor.toString();
367            }
368        }
369    
370        @NotNull
371        public static ModuleDescriptor getErrorModule() {
372            return ERROR_MODULE;
373        }
374    
375        private ErrorUtils() {}
376    }