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 kotlin.Function1;
020 import org.jetbrains.annotations.NotNull;
021 import org.jetbrains.annotations.Nullable;
022 import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
023 import org.jetbrains.jet.lang.descriptors.*;
024 import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
025 import org.jetbrains.jet.lang.descriptors.impl.*;
026 import org.jetbrains.jet.lang.resolve.ImportPath;
027 import org.jetbrains.jet.lang.resolve.name.Name;
028 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
029 import org.jetbrains.jet.lang.types.error.ErrorSimpleFunctionDescriptorImpl;
030 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
031 import org.jetbrains.jet.utils.Printer;
032
033 import java.util.Collection;
034 import java.util.Collections;
035 import java.util.List;
036 import java.util.Set;
037
038 public class ErrorUtils {
039
040 private static final ModuleDescriptor ERROR_MODULE;
041 static {
042 ERROR_MODULE = new ModuleDescriptorImpl(
043 Name.special("<ERROR MODULE>"),
044 Collections.<ImportPath>emptyList(),
045 PlatformToKotlinClassMap.EMPTY
046 );
047 }
048
049 public static boolean containsErrorType(@NotNull FunctionDescriptor function) {
050 if (containsErrorType(function.getReturnType())) {
051 return true;
052 }
053 ReceiverParameterDescriptor receiverParameter = function.getExtensionReceiverParameter();
054 if (receiverParameter != null && containsErrorType(receiverParameter.getType())) {
055 return true;
056 }
057 for (ValueParameterDescriptor parameter : function.getValueParameters()) {
058 if (containsErrorType(parameter.getType())) {
059 return true;
060 }
061 }
062 for (TypeParameterDescriptor parameter : function.getTypeParameters()) {
063 for (JetType upperBound : parameter.getUpperBounds()) {
064 if (containsErrorType(upperBound)) {
065 return true;
066 }
067 }
068 }
069
070 return false;
071 }
072
073
074 public static class ErrorScope implements JetScope {
075 private final String debugMessage;
076
077 private ErrorScope(@NotNull String debugMessage) {
078 this.debugMessage = debugMessage;
079 }
080
081 @Override
082 public ClassifierDescriptor getClassifier(@NotNull Name name) {
083 return createErrorClass(name.asString());
084 }
085
086 @NotNull
087 @Override
088 public Set<VariableDescriptor> getProperties(@NotNull Name name) {
089 return ERROR_PROPERTY_GROUP;
090 }
091
092 @Override
093 public VariableDescriptor getLocalVariable(@NotNull Name name) {
094 return ERROR_PROPERTY;
095 }
096
097 @Override
098 public PackageViewDescriptor getPackage(@NotNull Name name) {
099 return null;
100 }
101
102 @NotNull
103 @Override
104 public List<ReceiverParameterDescriptor> getImplicitReceiversHierarchy() {
105 return Collections.emptyList();
106 }
107
108 @NotNull
109 @Override
110 public Set<FunctionDescriptor> getFunctions(@NotNull Name name) {
111 return Collections.<FunctionDescriptor>singleton(createErrorFunction(this));
112 }
113
114 @NotNull
115 @Override
116 public DeclarationDescriptor getContainingDeclaration() {
117 return ERROR_MODULE;
118 }
119
120 @NotNull
121 @Override
122 public Collection<DeclarationDescriptor> getDeclarationsByLabel(@NotNull Name labelName) {
123 return Collections.emptyList();
124 }
125
126 @NotNull
127 @Override
128 public Collection<DeclarationDescriptor> getAllDescriptors() {
129 return Collections.emptyList();
130 }
131
132 @NotNull
133 @Override
134 public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
135 return Collections.emptyList();
136 }
137
138 @Override
139 public String toString() {
140 return "ErrorScope{" + debugMessage + '}';
141 }
142
143 @Override
144 public void printScopeStructure(@NotNull Printer p) {
145 p.println(getClass().getSimpleName(), ": ", debugMessage);
146 }
147 }
148
149 private static class ThrowingScope implements JetScope {
150 private final String debugMessage;
151
152 private ThrowingScope(@NotNull String message) {
153 debugMessage = message;
154 }
155
156 @Nullable
157 @Override
158 public ClassifierDescriptor getClassifier(@NotNull Name name) {
159 throw new IllegalStateException();
160 }
161
162 @Nullable
163 @Override
164 public PackageViewDescriptor getPackage(@NotNull Name name) {
165 throw new IllegalStateException();
166 }
167
168 @NotNull
169 @Override
170 public Collection<VariableDescriptor> getProperties(@NotNull Name name) {
171 throw new IllegalStateException();
172 }
173
174 @Nullable
175 @Override
176 public VariableDescriptor getLocalVariable(@NotNull Name name) {
177 throw new IllegalStateException();
178 }
179
180 @NotNull
181 @Override
182 public Collection<FunctionDescriptor> getFunctions(@NotNull Name name) {
183 throw new IllegalStateException();
184 }
185
186 @NotNull
187 @Override
188 public DeclarationDescriptor getContainingDeclaration() {
189 return ERROR_MODULE;
190 }
191
192 @NotNull
193 @Override
194 public Collection<DeclarationDescriptor> getDeclarationsByLabel(@NotNull Name labelName) {
195 throw new IllegalStateException();
196 }
197
198 @NotNull
199 @Override
200 public Collection<DeclarationDescriptor> getAllDescriptors() {
201 throw new IllegalStateException();
202 }
203
204 @NotNull
205 @Override
206 public List<ReceiverParameterDescriptor> getImplicitReceiversHierarchy() {
207 throw new IllegalStateException();
208 }
209
210 @NotNull
211 @Override
212 public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
213 throw new IllegalStateException();
214 }
215
216 @Override
217 public String toString() {
218 return "ThrowingScope{" + debugMessage + '}';
219 }
220
221 @Override
222 public void printScopeStructure(@NotNull Printer p) {
223 p.println(getClass().getSimpleName(), ": ", debugMessage);
224 }
225 }
226
227 private static final ErrorClassDescriptor ERROR_CLASS = new ErrorClassDescriptor(null);
228
229 private static class ErrorClassDescriptor extends ClassDescriptorImpl {
230 public ErrorClassDescriptor(@Nullable String name) {
231 super(getErrorModule(), Name.special(name == null ? "<ERROR CLASS>" : "<ERROR CLASS: " + name + ">"),
232 Modality.OPEN, Collections.<JetType>emptyList(), SourceElement.NO_SOURCE);
233
234 ConstructorDescriptorImpl errorConstructor = ConstructorDescriptorImpl.create(this, Annotations.EMPTY, true, SourceElement.NO_SOURCE);
235 errorConstructor.initialize(Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>emptyList(),
236 Visibilities.INTERNAL);
237 JetScope memberScope = createErrorScope(getName().asString());
238 errorConstructor.setReturnType(
239 new ErrorTypeImpl(
240 TypeConstructorImpl.createForClass(
241 this, Annotations.EMPTY, false,
242 getName().asString(),
243 Collections.<TypeParameterDescriptorImpl>emptyList(),
244 Collections.singleton(KotlinBuiltIns.getInstance().getAnyType())
245 ),
246 memberScope
247 )
248 );
249
250 initialize(memberScope, Collections.<ConstructorDescriptor>singleton(errorConstructor), errorConstructor);
251 }
252
253 @NotNull
254 @Override
255 public ClassDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
256 return this;
257 }
258
259 @Override
260 public String toString() {
261 return getName().asString();
262 }
263
264 @NotNull
265 @Override
266 public JetScope getMemberScope(@NotNull List<? extends TypeProjection> typeArguments) {
267 return createErrorScope("Error scope for class " + getName() + " with arguments: " + typeArguments);
268 }
269 }
270
271 @NotNull
272 public static ClassDescriptor createErrorClass(@NotNull String debugMessage) {
273 return new ErrorClassDescriptor(debugMessage);
274 }
275
276 @NotNull
277 public static JetScope createErrorScope(@NotNull String debugMessage) {
278 return createErrorScope(debugMessage, false);
279 }
280
281 @NotNull
282 public static JetScope createErrorScope(@NotNull String debugMessage, boolean throwExceptions) {
283 if (throwExceptions) {
284 return new ThrowingScope(debugMessage);
285 }
286 return new ErrorScope(debugMessage);
287 }
288
289 private static final JetType ERROR_PROPERTY_TYPE = createErrorType("<ERROR PROPERTY TYPE>");
290 private static final VariableDescriptor ERROR_PROPERTY = createErrorProperty();
291
292 private static final Set<VariableDescriptor> ERROR_PROPERTY_GROUP = Collections.singleton(ERROR_PROPERTY);
293
294 @NotNull
295 private static PropertyDescriptorImpl createErrorProperty() {
296 PropertyDescriptorImpl descriptor = PropertyDescriptorImpl.create(
297 ERROR_CLASS,
298 Annotations.EMPTY,
299 Modality.OPEN,
300 Visibilities.INTERNAL,
301 true,
302 Name.special("<ERROR PROPERTY>"),
303 CallableMemberDescriptor.Kind.DECLARATION,
304 SourceElement.NO_SOURCE
305 );
306 descriptor.setType(ERROR_PROPERTY_TYPE,
307 Collections.<TypeParameterDescriptor>emptyList(),
308 ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER,
309 (JetType) null
310 );
311
312 return descriptor;
313 }
314
315 @NotNull
316 private static SimpleFunctionDescriptor createErrorFunction(@NotNull ErrorScope ownerScope) {
317 ErrorSimpleFunctionDescriptorImpl function = new ErrorSimpleFunctionDescriptorImpl(ERROR_CLASS, ownerScope);
318 function.initialize(
319 null,
320 ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER,
321 Collections.<TypeParameterDescriptorImpl>emptyList(), // TODO
322 Collections.<ValueParameterDescriptor>emptyList(), // TODO
323 createErrorType("<ERROR FUNCTION RETURN TYPE>"),
324 Modality.OPEN,
325 Visibilities.INTERNAL
326 );
327 return function;
328 }
329
330 @NotNull
331 public static JetType createErrorType(@NotNull String debugMessage) {
332 return new ErrorTypeImpl(createErrorTypeConstructor(debugMessage), createErrorScope(debugMessage));
333 }
334
335 @NotNull
336 public static JetType createErrorTypeWithCustomDebugName(@NotNull String debugName) {
337 return new ErrorTypeImpl(createErrorTypeConstructorWithCustomDebugName(debugName), createErrorScope(debugName));
338 }
339
340 @NotNull
341 public static TypeConstructor createErrorTypeConstructor(@NotNull String debugMessage) {
342 return createErrorTypeConstructorWithCustomDebugName("[ERROR : " + debugMessage + "]");
343 }
344
345 @NotNull
346 private static TypeConstructor createErrorTypeConstructorWithCustomDebugName(@NotNull String debugName) {
347 return TypeConstructorImpl.createForClass(ERROR_CLASS, Annotations.EMPTY, false, debugName,
348 Collections.<TypeParameterDescriptorImpl>emptyList(),
349 Collections.singleton(KotlinBuiltIns.getInstance().getAnyType()));
350 }
351
352 public static boolean containsErrorType(@Nullable JetType type) {
353 if (type == null) return false;
354 if (type.isError()) return true;
355 for (TypeProjection projection : type.getArguments()) {
356 if (containsErrorType(projection.getType())) return true;
357 }
358 return false;
359 }
360
361 public static boolean isError(@NotNull DeclarationDescriptor candidate) {
362 return isErrorClass(candidate) || isErrorClass(candidate.getContainingDeclaration()) || candidate == ERROR_MODULE;
363 }
364
365 private static boolean isErrorClass(@Nullable DeclarationDescriptor candidate) {
366 return candidate instanceof ErrorClassDescriptor;
367 }
368
369 @NotNull
370 public static TypeParameterDescriptor createErrorTypeParameter(int index, @NotNull String debugMessage) {
371 return TypeParameterDescriptorImpl.createWithDefaultBound(
372 ERROR_CLASS,
373 Annotations.EMPTY,
374 false,
375 Variance.INVARIANT,
376 Name.special("<ERROR: " + debugMessage + ">"),
377 index
378 );
379 }
380
381 private static class ErrorTypeImpl implements JetType {
382 private final TypeConstructor constructor;
383 private final JetScope memberScope;
384
385 private ErrorTypeImpl(@NotNull TypeConstructor constructor, @NotNull JetScope memberScope) {
386 this.constructor = constructor;
387 this.memberScope = memberScope;
388 }
389
390 @NotNull
391 @Override
392 public TypeConstructor getConstructor() {
393 return constructor;
394 }
395
396 @NotNull
397 @Override
398 public List<TypeProjection> getArguments() {
399 return Collections.emptyList();
400 }
401
402 @Override
403 public boolean isNullable() {
404 return false;
405 }
406
407 @NotNull
408 @Override
409 public JetScope getMemberScope() {
410 return memberScope;
411 }
412
413 @Override
414 public boolean isError() {
415 return true;
416 }
417
418 @NotNull
419 @Override
420 public Annotations getAnnotations() {
421 return Annotations.EMPTY;
422 }
423
424 @Nullable
425 @Override
426 public <T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass) {
427 return null;
428 }
429
430 @Override
431 public String toString() {
432 return constructor.toString();
433 }
434 }
435
436 @NotNull
437 public static ModuleDescriptor getErrorModule() {
438 return ERROR_MODULE;
439 }
440
441 public static boolean isUninferredParameter(@Nullable JetType type) {
442 return type != null && type.getConstructor() instanceof UninferredParameterTypeConstructor;
443 }
444
445 public static boolean containsUninferredParameter(@Nullable JetType type) {
446 return TypeUtils.containsSpecialType(type, new Function1<JetType, Boolean>() {
447 @Override
448 public Boolean invoke(JetType argumentType) {
449 return isUninferredParameter(argumentType);
450 }
451 });
452 }
453
454 @NotNull
455 public static JetType createUninferredParameterType(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
456 return new ErrorTypeImpl(
457 new UninferredParameterTypeConstructor(typeParameterDescriptor),
458 createErrorScope("Scope for error type for not inferred parameter: " + typeParameterDescriptor.getName()));
459 }
460
461 public static class UninferredParameterTypeConstructor implements TypeConstructor {
462 private final TypeParameterDescriptor typeParameterDescriptor;
463 private final TypeConstructor errorTypeConstructor;
464
465 public UninferredParameterTypeConstructor(@NotNull TypeParameterDescriptor descriptor) {
466 typeParameterDescriptor = descriptor;
467 errorTypeConstructor = createErrorTypeConstructorWithCustomDebugName("CANT_INFER_TYPE_PARAMETER: " + descriptor.getName());
468 }
469
470 @NotNull
471 public TypeParameterDescriptor getTypeParameterDescriptor() {
472 return typeParameterDescriptor;
473 }
474
475 @NotNull
476 @Override
477 public List<TypeParameterDescriptor> getParameters() {
478 return errorTypeConstructor.getParameters();
479 }
480
481 @NotNull
482 @Override
483 public Collection<JetType> getSupertypes() {
484 return errorTypeConstructor.getSupertypes();
485 }
486
487 @Override
488 public boolean isFinal() {
489 return errorTypeConstructor.isFinal();
490 }
491
492 @Override
493 public boolean isDenotable() {
494 return errorTypeConstructor.isDenotable();
495 }
496
497 @Nullable
498 @Override
499 public ClassifierDescriptor getDeclarationDescriptor() {
500 return errorTypeConstructor.getDeclarationDescriptor();
501 }
502
503 @NotNull
504 @Override
505 public Annotations getAnnotations() {
506 return errorTypeConstructor.getAnnotations();
507 }
508 }
509
510 private ErrorUtils() {}
511 }