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.getReceiverParameter();
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, false);
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 instanceof PackageType) return false;
355 if (type.isError()) return true;
356 for (TypeProjection projection : type.getArguments()) {
357 if (containsErrorType(projection.getType())) return true;
358 }
359 return false;
360 }
361
362 public static boolean isError(@NotNull DeclarationDescriptor candidate) {
363 return isErrorClass(candidate) || isErrorClass(candidate.getContainingDeclaration()) || candidate == ERROR_MODULE;
364 }
365
366 private static boolean isErrorClass(@Nullable DeclarationDescriptor candidate) {
367 return candidate instanceof ErrorClassDescriptor;
368 }
369
370 @NotNull
371 public static TypeParameterDescriptor createErrorTypeParameter(int index, @NotNull String debugMessage) {
372 return TypeParameterDescriptorImpl.createWithDefaultBound(
373 ERROR_CLASS,
374 Annotations.EMPTY,
375 false,
376 Variance.INVARIANT,
377 Name.special("<ERROR: " + debugMessage + ">"),
378 index
379 );
380 }
381
382 private static class ErrorTypeImpl implements JetType {
383 private final TypeConstructor constructor;
384 private final JetScope memberScope;
385
386 private ErrorTypeImpl(@NotNull TypeConstructor constructor, @NotNull JetScope memberScope) {
387 this.constructor = constructor;
388 this.memberScope = memberScope;
389 }
390
391 @NotNull
392 @Override
393 public TypeConstructor getConstructor() {
394 return constructor;
395 }
396
397 @NotNull
398 @Override
399 public List<TypeProjection> getArguments() {
400 return Collections.emptyList();
401 }
402
403 @Override
404 public boolean isNullable() {
405 return false;
406 }
407
408 @NotNull
409 @Override
410 public JetScope getMemberScope() {
411 return memberScope;
412 }
413
414 @Override
415 public boolean isError() {
416 return true;
417 }
418
419 @NotNull
420 @Override
421 public Annotations getAnnotations() {
422 return Annotations.EMPTY;
423 }
424
425 @Override
426 public String toString() {
427 return constructor.toString();
428 }
429 }
430
431 @NotNull
432 public static ModuleDescriptor getErrorModule() {
433 return ERROR_MODULE;
434 }
435
436 public static boolean isUninferredParameter(@Nullable JetType type) {
437 return type instanceof UninferredParameterType;
438 }
439
440 public static boolean containsUninferredParameter(@Nullable JetType type) {
441 return TypeUtils.containsSpecialType(type, new Function1<JetType, Boolean>() {
442 @Override
443 public Boolean invoke(JetType argumentType) {
444 return isUninferredParameter(argumentType);
445 }
446 });
447 }
448
449 public static UninferredParameterType createUninferredParameterType(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
450 return new UninferredParameterType(typeParameterDescriptor);
451 }
452
453 public static class UninferredParameterType extends ErrorTypeImpl {
454 private final TypeParameterDescriptor typeParameterDescriptor;
455
456 private UninferredParameterType(
457 @NotNull TypeParameterDescriptor descriptor
458 ) {
459 super(createErrorTypeConstructorWithCustomDebugName("CANT_INFER_TYPE_PARAMETER: " + descriptor.getName()),
460 createErrorScope("Scope for error type for not inferred parameter: " + descriptor.getName()));
461 typeParameterDescriptor = descriptor;
462 }
463
464 @NotNull
465 public TypeParameterDescriptor getTypeParameterDescriptor() {
466 return typeParameterDescriptor;
467 }
468 }
469
470 private ErrorUtils() {}
471 }