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 }