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.resolve;
018
019 import com.google.common.collect.Lists;
020 import com.google.common.collect.Maps;
021 import com.intellij.lang.ASTNode;
022 import com.intellij.psi.PsiElement;
023 import com.intellij.psi.util.PsiTreeUtil;
024 import org.jetbrains.annotations.NotNull;
025 import org.jetbrains.annotations.Nullable;
026 import org.jetbrains.jet.lang.descriptors.*;
027 import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
028 import org.jetbrains.jet.lang.descriptors.impl.*;
029 import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory1;
030 import org.jetbrains.jet.lang.psi.*;
031 import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
032 import org.jetbrains.jet.lang.resolve.name.Name;
033 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
034 import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils;
035 import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
036 import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
037 import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
038 import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
039 import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
040 import org.jetbrains.jet.lang.types.*;
041 import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
042 import org.jetbrains.jet.lang.types.expressions.DelegatedPropertyUtils;
043 import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
044 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
045 import org.jetbrains.jet.lexer.JetKeywordToken;
046 import org.jetbrains.jet.lexer.JetTokens;
047 import org.jetbrains.jet.util.lazy.RecursionIntolerantLazyValue;
048 import org.jetbrains.jet.util.lazy.RecursionIntolerantLazyValueWithDefault;
049
050 import javax.inject.Inject;
051 import java.util.*;
052
053 import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
054 import static org.jetbrains.jet.lang.diagnostics.Errors.*;
055 import static org.jetbrains.jet.lang.resolve.BindingContext.CONSTRUCTOR;
056 import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
057 import static org.jetbrains.jet.lang.resolve.ModifiersChecker.*;
058 import static org.jetbrains.jet.lexer.JetTokens.OVERRIDE_KEYWORD;
059
060 public class DescriptorResolver {
061 public static final Name VALUE_OF_METHOD_NAME = Name.identifier("valueOf");
062 public static final Name VALUES_METHOD_NAME = Name.identifier("values");
063 public static final Name COPY_METHOD_NAME = Name.identifier("copy");
064 public static final String COMPONENT_FUNCTION_NAME_PREFIX = "component";
065
066 @NotNull
067 private TypeResolver typeResolver;
068 @NotNull
069 private AnnotationResolver annotationResolver;
070 @NotNull
071 private ExpressionTypingServices expressionTypingServices;
072
073 public static ReceiverParameterDescriptor resolveReceiverParameterFor(@NotNull CallableDescriptor owner, @Nullable JetType receiverParameterType) {
074 return receiverParameterType == null
075 ? NO_RECEIVER_PARAMETER
076 : new ReceiverParameterDescriptorImpl(owner, receiverParameterType, new ExtensionReceiver(owner, receiverParameterType));
077 }
078
079 @Inject
080 public void setTypeResolver(@NotNull TypeResolver typeResolver) {
081 this.typeResolver = typeResolver;
082 }
083
084 @Inject
085 public void setAnnotationResolver(@NotNull AnnotationResolver annotationResolver) {
086 this.annotationResolver = annotationResolver;
087 }
088
089 @Inject
090 public void setExpressionTypingServices(@NotNull ExpressionTypingServices expressionTypingServices) {
091 this.expressionTypingServices = expressionTypingServices;
092 }
093
094
095 public void resolveMutableClassDescriptor(
096 @NotNull JetClass classElement,
097 @NotNull MutableClassDescriptor descriptor,
098 BindingTrace trace
099 ) {
100 // TODO : Where-clause
101 List<TypeParameterDescriptor> typeParameters = Lists.newArrayList();
102 int index = 0;
103 for (JetTypeParameter typeParameter : classElement.getTypeParameters()) {
104 TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
105 descriptor,
106 annotationResolver.getResolvedAnnotations(typeParameter.getModifierList(), trace),
107 typeParameter.hasModifier(JetTokens.REIFIED_KEYWORD),
108 typeParameter.getVariance(),
109 JetPsiUtil.safeName(typeParameter.getName()),
110 index
111 );
112 trace.record(BindingContext.TYPE_PARAMETER, typeParameter, typeParameterDescriptor);
113 typeParameters.add(typeParameterDescriptor);
114 index++;
115 }
116 descriptor.setTypeParameterDescriptors(typeParameters);
117 Modality defaultModality = descriptor.getKind() == ClassKind.TRAIT ? Modality.ABSTRACT : Modality.FINAL;
118 descriptor.setModality(resolveModalityFromModifiers(classElement, defaultModality));
119 descriptor.setVisibility(resolveVisibilityFromModifiers(classElement, getDefaultClassVisibility(descriptor)));
120
121 trace.record(BindingContext.CLASS, classElement, descriptor);
122 }
123
124 public void resolveSupertypesForMutableClassDescriptor(
125 @NotNull JetClassOrObject jetClass,
126 @NotNull MutableClassDescriptor descriptor,
127 BindingTrace trace
128 ) {
129 for (JetType supertype : resolveSupertypes(descriptor.getScopeForSupertypeResolution(), descriptor, jetClass, trace)) {
130 descriptor.addSupertype(supertype);
131 }
132 }
133
134 public List<JetType> resolveSupertypes(
135 @NotNull JetScope scope,
136 @NotNull ClassDescriptor classDescriptor,
137 @NotNull JetClassOrObject jetClass,
138 BindingTrace trace
139 ) {
140 List<JetType> supertypes = Lists.newArrayList();
141 List<JetDelegationSpecifier> delegationSpecifiers = jetClass.getDelegationSpecifiers();
142 Collection<JetType> declaredSupertypes = resolveDelegationSpecifiers(
143 scope,
144 delegationSpecifiers,
145 typeResolver, trace, false);
146
147 for (JetType declaredSupertype : declaredSupertypes) {
148 addValidSupertype(supertypes, declaredSupertype);
149 }
150
151 if (classDescriptor.getKind() == ClassKind.ENUM_CLASS && !containsClass(supertypes)) {
152 supertypes.add(0, KotlinBuiltIns.getInstance().getEnumType(classDescriptor.getDefaultType()));
153 }
154
155 if (supertypes.isEmpty()) {
156 JetType defaultSupertype = getDefaultSupertype(jetClass, trace);
157 addValidSupertype(supertypes, defaultSupertype);
158 }
159
160 return supertypes;
161 }
162
163 private static void addValidSupertype(List<JetType> supertypes, JetType declaredSupertype) {
164 if (!ErrorUtils.isErrorType(declaredSupertype)) {
165 supertypes.add(declaredSupertype);
166 }
167 }
168
169 private boolean containsClass(Collection<JetType> result) {
170 for (JetType type : result) {
171 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
172 if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() != ClassKind.TRAIT) {
173 return true;
174 }
175 }
176 return false;
177 }
178
179 private JetType getDefaultSupertype(JetClassOrObject jetClass, BindingTrace trace) {
180 // TODO : beautify
181 if (jetClass instanceof JetEnumEntry) {
182 JetClassOrObject parent = PsiTreeUtil.getParentOfType(jetClass, JetClassOrObject.class);
183 ClassDescriptor parentDescriptor = trace.getBindingContext().get(BindingContext.CLASS, parent);
184 if (parentDescriptor.getTypeConstructor().getParameters().isEmpty()) {
185 return parentDescriptor.getDefaultType();
186 }
187 else {
188 trace.report(NO_GENERICS_IN_SUPERTYPE_SPECIFIER.on(jetClass.getNameIdentifier()));
189 return ErrorUtils.createErrorType("Supertype not specified");
190 }
191 }
192 else if (jetClass instanceof JetClass && ((JetClass) jetClass).isAnnotation()) {
193 return KotlinBuiltIns.getInstance().getAnnotationType();
194 }
195 return KotlinBuiltIns.getInstance().getAnyType();
196 }
197
198 public Collection<JetType> resolveDelegationSpecifiers(
199 JetScope extensibleScope,
200 List<JetDelegationSpecifier> delegationSpecifiers,
201 @NotNull TypeResolver resolver,
202 BindingTrace trace,
203 boolean checkBounds
204 ) {
205 if (delegationSpecifiers.isEmpty()) {
206 return Collections.emptyList();
207 }
208 Collection<JetType> result = Lists.newArrayList();
209 for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) {
210 JetTypeReference typeReference = delegationSpecifier.getTypeReference();
211 if (typeReference != null) {
212 result.add(resolver.resolveType(extensibleScope, typeReference, trace, checkBounds));
213 JetTypeElement bareSuperType = checkNullableSupertypeAndStripQuestionMarks(trace, typeReference.getTypeElement());
214 checkProjectionsInImmediateArguments(trace, bareSuperType);
215 }
216 else {
217 result.add(ErrorUtils.createErrorType("No type reference"));
218 }
219 }
220 return result;
221 }
222
223 @Nullable
224 private static JetTypeElement checkNullableSupertypeAndStripQuestionMarks(@NotNull BindingTrace trace, @Nullable JetTypeElement typeElement) {
225 while (typeElement instanceof JetNullableType) {
226 JetNullableType nullableType = (JetNullableType) typeElement;
227 typeElement = nullableType.getInnerType();
228 // report only for innermost '?', the rest gets a 'redundant' warning
229 if (!(typeElement instanceof JetNullableType)) {
230 trace.report(NULLABLE_SUPERTYPE.on(nullableType));
231 }
232 }
233 return typeElement;
234 }
235
236 private static void checkProjectionsInImmediateArguments(@NotNull BindingTrace trace, @Nullable JetTypeElement typeElement) {
237 if (typeElement instanceof JetUserType) {
238 JetUserType userType = (JetUserType) typeElement;
239 List<JetTypeProjection> typeArguments = userType.getTypeArguments();
240 for (JetTypeProjection typeArgument : typeArguments) {
241 if (typeArgument.getProjectionKind() != JetProjectionKind.NONE) {
242 trace.report(PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE.on(typeArgument));
243 }
244 }
245 }
246 }
247
248 @NotNull
249 public SimpleFunctionDescriptor resolveFunctionDescriptorWithAnnotationArguments(
250 @NotNull DeclarationDescriptor containingDescriptor,
251 @NotNull JetScope scope,
252 @NotNull JetNamedFunction function,
253 @NotNull BindingTrace trace,
254 @NotNull DataFlowInfo dataFlowInfo
255 ) {
256 return resolveFunctionDescriptor(containingDescriptor, scope, function, trace, dataFlowInfo,
257 annotationResolver.resolveAnnotationsWithArguments(scope, function.getModifierList(), trace));
258 }
259
260 @NotNull
261 public SimpleFunctionDescriptor resolveFunctionDescriptor(
262 @NotNull DeclarationDescriptor containingDescriptor,
263 @NotNull JetScope scope,
264 @NotNull JetNamedFunction function,
265 @NotNull BindingTrace trace,
266 @NotNull DataFlowInfo dataFlowInfo
267 ) {
268 return resolveFunctionDescriptor(containingDescriptor, scope, function, trace, dataFlowInfo,
269 annotationResolver.resolveAnnotations(scope, function.getModifierList(), trace));
270 }
271
272 @NotNull
273 private SimpleFunctionDescriptor resolveFunctionDescriptor(
274 @NotNull DeclarationDescriptor containingDescriptor,
275 @NotNull final JetScope scope,
276 @NotNull final JetNamedFunction function,
277 @NotNull final BindingTrace trace,
278 @NotNull final DataFlowInfo dataFlowInfo,
279 @NotNull List<AnnotationDescriptor> annotations
280 ) {
281 final SimpleFunctionDescriptorImpl functionDescriptor = new SimpleFunctionDescriptorImpl(
282 containingDescriptor,
283 annotations,
284 JetPsiUtil.safeName(function.getName()),
285 CallableMemberDescriptor.Kind.DECLARATION
286 );
287 WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, new TraceBasedRedeclarationHandler(trace),
288 "Function descriptor header scope");
289 innerScope.addLabeledDeclaration(functionDescriptor);
290
291 List<TypeParameterDescriptorImpl> typeParameterDescriptors =
292 resolveTypeParametersForCallableDescriptor(functionDescriptor, innerScope, function.getTypeParameters(), trace);
293 innerScope.changeLockLevel(WritableScope.LockLevel.BOTH);
294 resolveGenericBounds(function, innerScope, typeParameterDescriptors, trace);
295
296 JetType receiverType = null;
297 JetTypeReference receiverTypeRef = function.getReceiverTypeRef();
298 if (receiverTypeRef != null) {
299 JetScope scopeForReceiver =
300 function.hasTypeParameterListBeforeFunctionName()
301 ? innerScope
302 : scope;
303 receiverType = typeResolver.resolveType(scopeForReceiver, receiverTypeRef, trace, true);
304 }
305
306 List<ValueParameterDescriptor> valueParameterDescriptors =
307 resolveValueParameters(functionDescriptor, innerScope, function.getValueParameters(), trace);
308
309 innerScope.changeLockLevel(WritableScope.LockLevel.READING);
310
311 JetTypeReference returnTypeRef = function.getReturnTypeRef();
312 JetType returnType;
313 if (returnTypeRef != null) {
314 returnType = typeResolver.resolveType(innerScope, returnTypeRef, trace, true);
315 }
316 else if (function.hasBlockBody()) {
317 returnType = KotlinBuiltIns.getInstance().getUnitType();
318 }
319 else {
320 JetExpression bodyExpression = function.getBodyExpression();
321 if (bodyExpression != null) {
322 returnType =
323 DeferredType.create(trace, new RecursionIntolerantLazyValueWithDefault<JetType>(ErrorUtils.createErrorType("Recursive dependency")) {
324 @Override
325 protected JetType compute() {
326 JetType type = expressionTypingServices.getBodyExpressionType(trace, scope, dataFlowInfo, function, functionDescriptor);
327 return transformAnonymousTypeIfNeeded(functionDescriptor, function, type, trace);
328 }
329 });
330 }
331 else {
332 returnType = ErrorUtils.createErrorType("No type, no body");
333 }
334 }
335 boolean hasBody = function.getBodyExpression() != null;
336 Modality modality = resolveModalityFromModifiers(function, getDefaultModality(containingDescriptor, hasBody));
337 Visibility visibility = resolveVisibilityFromModifiers(function, getDefaultVisibility(function, containingDescriptor));
338 JetModifierList modifierList = function.getModifierList();
339 boolean isInline = (modifierList != null) && modifierList.hasModifier(JetTokens.INLINE_KEYWORD);
340 functionDescriptor.initialize(
341 receiverType,
342 getExpectedThisObjectIfNeeded(containingDescriptor),
343 typeParameterDescriptors,
344 valueParameterDescriptors,
345 returnType,
346 modality,
347 visibility,
348 isInline);
349
350 BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, function, functionDescriptor);
351 return functionDescriptor;
352 }
353
354 @NotNull
355 public static SimpleFunctionDescriptor createComponentFunctionDescriptor(
356 int parameterIndex,
357 @NotNull PropertyDescriptor property,
358 @NotNull ValueParameterDescriptor parameter,
359 @NotNull ClassDescriptor classDescriptor,
360 @NotNull BindingTrace trace
361 ) {
362 String functionName = COMPONENT_FUNCTION_NAME_PREFIX + parameterIndex;
363 JetType returnType = property.getType();
364
365 SimpleFunctionDescriptorImpl functionDescriptor = new SimpleFunctionDescriptorImpl(
366 classDescriptor,
367 Collections.<AnnotationDescriptor>emptyList(),
368 Name.identifier(functionName),
369 CallableMemberDescriptor.Kind.SYNTHESIZED
370 );
371
372 functionDescriptor.initialize(
373 null,
374 classDescriptor.getThisAsReceiverParameter(),
375 Collections.<TypeParameterDescriptor>emptyList(),
376 Collections.<ValueParameterDescriptor>emptyList(),
377 returnType,
378 Modality.FINAL,
379 property.getVisibility(),
380 true
381 );
382
383 trace.record(BindingContext.DATA_CLASS_COMPONENT_FUNCTION, parameter, functionDescriptor);
384
385 return functionDescriptor;
386 }
387
388 @NotNull
389 public static SimpleFunctionDescriptor createCopyFunctionDescriptor(
390 @NotNull Collection<ValueParameterDescriptor> constructorParameters,
391 @NotNull ClassDescriptor classDescriptor,
392 @NotNull BindingTrace trace
393 ) {
394 JetType returnType = classDescriptor.getDefaultType();
395
396 SimpleFunctionDescriptorImpl functionDescriptor = new SimpleFunctionDescriptorImpl(
397 classDescriptor,
398 Collections.<AnnotationDescriptor>emptyList(),
399 COPY_METHOD_NAME,
400 CallableMemberDescriptor.Kind.SYNTHESIZED
401 );
402
403 List<ValueParameterDescriptor> parameterDescriptors = Lists.newArrayList();
404
405 for (ValueParameterDescriptor parameter : constructorParameters) {
406 PropertyDescriptor propertyDescriptor = trace.getBindingContext().get(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter);
407 // If parameter hasn't corresponding property, so it mustn't have default value as a parameter in copy function for data class
408 boolean declaresDefaultValue = propertyDescriptor != null;
409 ValueParameterDescriptorImpl parameterDescriptor =
410 new ValueParameterDescriptorImpl(functionDescriptor, parameter.getIndex(), parameter.getAnnotations(),
411 parameter.getName(), parameter.getType(),
412 declaresDefaultValue,
413 parameter.getVarargElementType());
414 parameterDescriptors.add(parameterDescriptor);
415 if (declaresDefaultValue) {
416 trace.record(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameterDescriptor, propertyDescriptor);
417 }
418 }
419
420 functionDescriptor.initialize(
421 null,
422 classDescriptor.getThisAsReceiverParameter(),
423 Collections.<TypeParameterDescriptor>emptyList(),
424 parameterDescriptors,
425 returnType,
426 Modality.FINAL,
427 classDescriptor.getVisibility(),
428 true
429 );
430
431 trace.record(BindingContext.DATA_CLASS_COPY_FUNCTION, classDescriptor, functionDescriptor);
432 return functionDescriptor;
433 }
434
435 public static Visibility getDefaultVisibility(JetModifierListOwner modifierListOwner, DeclarationDescriptor containingDescriptor) {
436 Visibility defaultVisibility;
437 if (containingDescriptor instanceof ClassDescriptor) {
438 JetModifierList modifierList = modifierListOwner.getModifierList();
439 defaultVisibility = modifierList != null && modifierList.hasModifier(OVERRIDE_KEYWORD)
440 ? Visibilities.INHERITED
441 : Visibilities.INTERNAL;
442 }
443 else if (containingDescriptor instanceof FunctionDescriptor) {
444 defaultVisibility = Visibilities.LOCAL;
445 }
446 else {
447 defaultVisibility = Visibilities.INTERNAL;
448 }
449 return defaultVisibility;
450 }
451
452 public static Modality getDefaultModality(DeclarationDescriptor containingDescriptor, boolean isBodyPresent) {
453 Modality defaultModality;
454 if (containingDescriptor instanceof ClassDescriptor) {
455 boolean isTrait = ((ClassDescriptor) containingDescriptor).getKind() == ClassKind.TRAIT;
456 boolean isDefinitelyAbstract = isTrait && !isBodyPresent;
457 Modality basicModality = isTrait ? Modality.OPEN : Modality.FINAL;
458 defaultModality = isDefinitelyAbstract ? Modality.ABSTRACT : basicModality;
459 }
460 else {
461 defaultModality = Modality.FINAL;
462 }
463 return defaultModality;
464 }
465
466 @NotNull
467 private List<ValueParameterDescriptor> resolveValueParameters(
468 FunctionDescriptor functionDescriptor,
469 WritableScope parameterScope,
470 List<JetParameter> valueParameters,
471 BindingTrace trace
472 ) {
473 List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
474 for (int i = 0; i < valueParameters.size(); i++) {
475 JetParameter valueParameter = valueParameters.get(i);
476 JetTypeReference typeReference = valueParameter.getTypeReference();
477
478 JetType type;
479 if (typeReference == null) {
480 trace.report(VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION.on(valueParameter));
481 type = ErrorUtils.createErrorType("Type annotation was missing");
482 }
483 else {
484 type = typeResolver.resolveType(parameterScope, typeReference, trace, true);
485 }
486
487 if (!(functionDescriptor instanceof ConstructorDescriptor)) {
488 checkParameterHasNoValOrVar(trace, valueParameter, VAL_OR_VAR_ON_FUN_PARAMETER);
489 }
490
491 ValueParameterDescriptor valueParameterDescriptor =
492 resolveValueParameterDescriptor(parameterScope, functionDescriptor, valueParameter, i, type, trace);
493 parameterScope.addVariableDescriptor(valueParameterDescriptor);
494 result.add(valueParameterDescriptor);
495 }
496 return result;
497 }
498
499 @NotNull
500 public MutableValueParameterDescriptor resolveValueParameterDescriptor(
501 JetScope scope, DeclarationDescriptor declarationDescriptor,
502 JetParameter valueParameter, int index, JetType type, BindingTrace trace
503 ) {
504 return resolveValueParameterDescriptor(declarationDescriptor, valueParameter, index, type, trace,
505 annotationResolver.resolveAnnotations(scope, valueParameter.getModifierList(), trace));
506 }
507
508 @NotNull
509 public MutableValueParameterDescriptor resolveValueParameterDescriptorWithAnnotationArguments(
510 JetScope scope, DeclarationDescriptor declarationDescriptor,
511 JetParameter valueParameter, int index, JetType type, BindingTrace trace
512 ) {
513 return resolveValueParameterDescriptor(declarationDescriptor, valueParameter, index, type, trace,
514 annotationResolver.resolveAnnotationsWithArguments(scope, valueParameter.getModifierList(),
515 trace));
516 }
517
518 @NotNull
519 private MutableValueParameterDescriptor resolveValueParameterDescriptor(
520 DeclarationDescriptor declarationDescriptor,
521 JetParameter valueParameter, int index, JetType type, BindingTrace trace,
522 List<AnnotationDescriptor> annotations
523 ) {
524 JetType varargElementType = null;
525 JetType variableType = type;
526 if (valueParameter.hasModifier(JetTokens.VARARG_KEYWORD)) {
527 varargElementType = type;
528 variableType = DescriptorUtils.getVarargParameterType(type);
529 }
530 MutableValueParameterDescriptor valueParameterDescriptor = new ValueParameterDescriptorImpl(
531 declarationDescriptor,
532 index,
533 annotations,
534 JetPsiUtil.safeName(valueParameter.getName()),
535 variableType,
536 valueParameter.getDefaultValue() != null,
537 varargElementType
538 );
539
540 trace.record(BindingContext.VALUE_PARAMETER, valueParameter, valueParameterDescriptor);
541 return valueParameterDescriptor;
542 }
543
544 public List<TypeParameterDescriptorImpl> resolveTypeParametersForCallableDescriptor(
545 DeclarationDescriptor containingDescriptor,
546 WritableScope extensibleScope,
547 List<JetTypeParameter> typeParameters,
548 BindingTrace trace
549 ) {
550 List<TypeParameterDescriptorImpl> result = new ArrayList<TypeParameterDescriptorImpl>();
551 for (int i = 0, typeParametersSize = typeParameters.size(); i < typeParametersSize; i++) {
552 JetTypeParameter typeParameter = typeParameters.get(i);
553 result.add(resolveTypeParameterForCallableDescriptor(containingDescriptor, extensibleScope, typeParameter, i, trace));
554 }
555 return result;
556 }
557
558 private TypeParameterDescriptorImpl resolveTypeParameterForCallableDescriptor(
559 DeclarationDescriptor containingDescriptor,
560 WritableScope extensibleScope,
561 JetTypeParameter typeParameter,
562 int index,
563 BindingTrace trace
564 ) {
565 if (typeParameter.getVariance() != Variance.INVARIANT) {
566 assert !(containingDescriptor instanceof ClassifierDescriptor) : "This method is intended for functions/properties";
567 trace.report(VARIANCE_ON_TYPE_PARAMETER_OF_FUNCTION_OR_PROPERTY.on(typeParameter));
568 }
569
570 // TODO: Annotations are not resolved!
571 TypeParameterDescriptorImpl typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
572 containingDescriptor,
573 annotationResolver.getResolvedAnnotations(typeParameter.getModifierList(), trace),
574 typeParameter.hasModifier(JetTokens.REIFIED_KEYWORD),
575 typeParameter.getVariance(),
576 JetPsiUtil.safeName(typeParameter.getName()),
577 index
578 );
579 trace.record(BindingContext.TYPE_PARAMETER, typeParameter, typeParameterDescriptor);
580 extensibleScope.addTypeParameterDescriptor(typeParameterDescriptor);
581 return typeParameterDescriptor;
582 }
583
584 @NotNull
585 public static ConstructorDescriptorImpl createAndRecordPrimaryConstructorForObject(
586 @Nullable PsiElement object,
587 @NotNull ClassDescriptor classDescriptor,
588 @NotNull BindingTrace trace
589 ) {
590 ConstructorDescriptorImpl constructorDescriptor = createPrimaryConstructorForObject(classDescriptor);
591 if (object != null) {
592 trace.record(CONSTRUCTOR, object, constructorDescriptor);
593 }
594 return constructorDescriptor;
595 }
596
597 @NotNull
598 public static ConstructorDescriptorImpl createPrimaryConstructorForObject(@NotNull ClassDescriptor containingClass) {
599 ConstructorDescriptorImpl constructorDescriptor =
600 new ConstructorDescriptorImpl(containingClass, Collections.<AnnotationDescriptor>emptyList(), true);
601 constructorDescriptor.initialize(Collections.<TypeParameterDescriptor>emptyList(),
602 Collections.<ValueParameterDescriptor>emptyList(),
603 getDefaultConstructorVisibility(containingClass));
604 return constructorDescriptor;
605 }
606
607 static final class UpperBoundCheckerTask {
608 JetTypeReference upperBound;
609 JetType upperBoundType;
610 boolean isClassObjectConstraint;
611
612 private UpperBoundCheckerTask(JetTypeReference upperBound, JetType upperBoundType, boolean classObjectConstraint) {
613 this.upperBound = upperBound;
614 this.upperBoundType = upperBoundType;
615 isClassObjectConstraint = classObjectConstraint;
616 }
617 }
618
619 public void resolveGenericBounds(
620 @NotNull JetTypeParameterListOwner declaration,
621 JetScope scope,
622 List<TypeParameterDescriptorImpl> parameters,
623 BindingTrace trace
624 ) {
625 List<UpperBoundCheckerTask> deferredUpperBoundCheckerTasks = Lists.newArrayList();
626
627 List<JetTypeParameter> typeParameters = declaration.getTypeParameters();
628 Map<Name, TypeParameterDescriptorImpl> parameterByName = Maps.newHashMap();
629 for (int i = 0; i < typeParameters.size(); i++) {
630 JetTypeParameter jetTypeParameter = typeParameters.get(i);
631 TypeParameterDescriptorImpl typeParameterDescriptor = parameters.get(i);
632
633 parameterByName.put(typeParameterDescriptor.getName(), typeParameterDescriptor);
634
635 JetTypeReference extendsBound = jetTypeParameter.getExtendsBound();
636 if (extendsBound != null) {
637 JetType type = typeResolver.resolveType(scope, extendsBound, trace, false);
638 typeParameterDescriptor.addUpperBound(type);
639 deferredUpperBoundCheckerTasks.add(new UpperBoundCheckerTask(extendsBound, type, false));
640 }
641 }
642 for (JetTypeConstraint constraint : declaration.getTypeConstraints()) {
643 JetSimpleNameExpression subjectTypeParameterName = constraint.getSubjectTypeParameterName();
644 if (subjectTypeParameterName == null) {
645 continue;
646 }
647 Name referencedName = subjectTypeParameterName.getReferencedNameAsName();
648 TypeParameterDescriptorImpl typeParameterDescriptor = parameterByName.get(referencedName);
649 JetTypeReference boundTypeReference = constraint.getBoundTypeReference();
650 JetType bound = null;
651 if (boundTypeReference != null) {
652 bound = typeResolver.resolveType(scope, boundTypeReference, trace, false);
653 deferredUpperBoundCheckerTasks
654 .add(new UpperBoundCheckerTask(boundTypeReference, bound, constraint.isClassObjectContraint()));
655 }
656
657 if (typeParameterDescriptor == null) {
658 // To tell the user that we look only for locally defined type parameters
659 ClassifierDescriptor classifier = scope.getClassifier(referencedName);
660 if (classifier != null) {
661 trace.report(NAME_IN_CONSTRAINT_IS_NOT_A_TYPE_PARAMETER.on(subjectTypeParameterName, constraint, declaration));
662 trace.record(BindingContext.REFERENCE_TARGET, subjectTypeParameterName, classifier);
663 }
664 else {
665 trace.report(UNRESOLVED_REFERENCE.on(subjectTypeParameterName, subjectTypeParameterName));
666 }
667 }
668 else {
669 trace.record(BindingContext.REFERENCE_TARGET, subjectTypeParameterName, typeParameterDescriptor);
670 if (bound != null) {
671 if (constraint.isClassObjectContraint()) {
672 typeParameterDescriptor.addClassObjectBound(bound);
673 }
674 else {
675 typeParameterDescriptor.addUpperBound(bound);
676 }
677 }
678 }
679 }
680
681 for (TypeParameterDescriptorImpl parameter : parameters) {
682 parameter.addDefaultUpperBound();
683
684 parameter.setInitialized();
685
686 if (KotlinBuiltIns.getInstance().isNothing(parameter.getUpperBoundsAsType())) {
687 PsiElement nameIdentifier = typeParameters.get(parameter.getIndex()).getNameIdentifier();
688 if (nameIdentifier != null) {
689 trace.report(CONFLICTING_UPPER_BOUNDS.on(nameIdentifier, parameter));
690 }
691 }
692
693 JetType classObjectType = parameter.getClassObjectType();
694 if (classObjectType != null && KotlinBuiltIns.getInstance().isNothing(classObjectType)) {
695 PsiElement nameIdentifier = typeParameters.get(parameter.getIndex()).getNameIdentifier();
696 if (nameIdentifier != null) {
697 trace.report(CONFLICTING_CLASS_OBJECT_UPPER_BOUNDS.on(nameIdentifier, parameter));
698 }
699 }
700 }
701
702 for (UpperBoundCheckerTask checkerTask : deferredUpperBoundCheckerTasks) {
703 checkUpperBoundType(checkerTask.upperBound, checkerTask.upperBoundType, checkerTask.isClassObjectConstraint, trace);
704 }
705 }
706
707 private static void checkUpperBoundType(
708 JetTypeReference upperBound,
709 JetType upperBoundType,
710 boolean isClassObjectConstraint,
711 BindingTrace trace
712 ) {
713 if (!TypeUtils.canHaveSubtypes(JetTypeChecker.INSTANCE, upperBoundType)) {
714 if (isClassObjectConstraint) {
715 trace.report(FINAL_CLASS_OBJECT_UPPER_BOUND.on(upperBound, upperBoundType));
716 }
717 else {
718 trace.report(FINAL_UPPER_BOUND.on(upperBound, upperBoundType));
719 }
720 }
721 }
722
723 @NotNull
724 public VariableDescriptor resolveLocalVariableDescriptor(
725 @NotNull JetScope scope,
726 @NotNull JetParameter parameter,
727 BindingTrace trace
728 ) {
729 JetType type = resolveParameterType(scope, parameter, trace);
730 return resolveLocalVariableDescriptor(parameter, type, trace, scope);
731 }
732
733 private JetType resolveParameterType(JetScope scope, JetParameter parameter, BindingTrace trace) {
734 JetTypeReference typeReference = parameter.getTypeReference();
735 JetType type;
736 if (typeReference != null) {
737 type = typeResolver.resolveType(scope, typeReference, trace, true);
738 }
739 else {
740 // Error is reported by the parser
741 type = ErrorUtils.createErrorType("Annotation is absent");
742 }
743 if (parameter.hasModifier(JetTokens.VARARG_KEYWORD)) {
744 return DescriptorUtils.getVarargParameterType(type);
745 }
746 return type;
747 }
748
749 public VariableDescriptor resolveLocalVariableDescriptor(
750 @NotNull JetParameter parameter,
751 @NotNull JetType type,
752 BindingTrace trace,
753 @NotNull JetScope scope
754 ) {
755 VariableDescriptor variableDescriptor = new LocalVariableDescriptor(
756 scope.getContainingDeclaration(),
757 annotationResolver.resolveAnnotationsWithArguments(scope, parameter.getModifierList(), trace),
758 JetPsiUtil.safeName(parameter.getName()),
759 type,
760 false);
761 trace.record(BindingContext.VALUE_PARAMETER, parameter, variableDescriptor);
762 return variableDescriptor;
763 }
764
765 @NotNull
766 public VariableDescriptor resolveLocalVariableDescriptor(
767 JetScope scope,
768 JetVariableDeclaration variable,
769 DataFlowInfo dataFlowInfo,
770 BindingTrace trace
771 ) {
772 DeclarationDescriptor containingDeclaration = scope.getContainingDeclaration();
773 if (JetPsiUtil.isScriptDeclaration(variable)) {
774 PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl(
775 containingDeclaration,
776 annotationResolver.resolveAnnotationsWithArguments(scope, variable.getModifierList(), trace),
777 Modality.FINAL,
778 Visibilities.INTERNAL,
779 variable.isVar(),
780 JetPsiUtil.safeName(variable.getName()),
781 CallableMemberDescriptor.Kind.DECLARATION
782 );
783
784 JetType type =
785 getVariableType(propertyDescriptor, scope, variable, dataFlowInfo, false, trace); // For a local variable the type must not be deferred
786
787 ReceiverParameterDescriptor receiverParameter = ((ScriptDescriptor) containingDeclaration).getThisAsReceiverParameter();
788 propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(), receiverParameter, (JetType) null);
789 trace.record(BindingContext.VARIABLE, variable, propertyDescriptor);
790 return propertyDescriptor;
791 }
792 else {
793 VariableDescriptorImpl variableDescriptor =
794 resolveLocalVariableDescriptorWithType(scope, variable, null, trace);
795
796 JetType type =
797 getVariableType(variableDescriptor, scope, variable, dataFlowInfo, false, trace); // For a local variable the type must not be deferred
798 variableDescriptor.setOutType(type);
799 return variableDescriptor;
800 }
801 }
802
803 @NotNull
804 public VariableDescriptorImpl resolveLocalVariableDescriptorWithType(
805 @NotNull JetScope scope,
806 @NotNull JetVariableDeclaration variable,
807 @Nullable JetType type,
808 @NotNull BindingTrace trace
809 ) {
810 VariableDescriptorImpl variableDescriptor = new LocalVariableDescriptor(
811 scope.getContainingDeclaration(),
812 annotationResolver.resolveAnnotationsWithArguments(scope, variable.getModifierList(), trace),
813 JetPsiUtil.safeName(variable.getName()),
814 type,
815 variable.isVar());
816 trace.record(BindingContext.VARIABLE, variable, variableDescriptor);
817 return variableDescriptor;
818 }
819
820 @NotNull
821 public VariableDescriptor resolveObjectDeclaration(
822 @NotNull DeclarationDescriptor containingDeclaration,
823 @NotNull JetClassOrObject objectDeclaration,
824 @NotNull ClassDescriptor classDescriptor, BindingTrace trace
825 ) {
826 boolean isProperty = (containingDeclaration instanceof NamespaceDescriptor)
827 || (containingDeclaration instanceof ClassDescriptor);
828 if (isProperty) {
829 return resolveObjectDeclarationAsPropertyDescriptor(containingDeclaration, objectDeclaration, classDescriptor, trace);
830 }
831 else {
832 return resolveObjectDeclarationAsLocalVariable(containingDeclaration, objectDeclaration, classDescriptor, trace);
833 }
834 }
835
836 @NotNull
837 public PropertyDescriptor resolveObjectDeclarationAsPropertyDescriptor(
838 @NotNull DeclarationDescriptor containingDeclaration,
839 @NotNull JetClassOrObject objectDeclaration,
840 @NotNull ClassDescriptor classDescriptor, BindingTrace trace
841 ) {
842 JetModifierList modifierList = objectDeclaration.getModifierList();
843 PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl(
844 containingDeclaration,
845 annotationResolver.getResolvedAnnotations(modifierList, trace),
846 Modality.FINAL,
847 resolveVisibilityFromModifiers(objectDeclaration, getDefaultVisibilityForObjectPropertyDescriptor(classDescriptor)),
848 false,
849 JetPsiUtil.safeName(objectDeclaration.getName()),
850 CallableMemberDescriptor.Kind.DECLARATION
851 );
852 propertyDescriptor.setType(getTypeForObjectDeclaration(classDescriptor), Collections.<TypeParameterDescriptor>emptyList(),
853 getExpectedThisObjectIfNeeded(containingDeclaration), NO_RECEIVER_PARAMETER);
854 propertyDescriptor.initialize(null, null);
855 trace.record(BindingContext.OBJECT_DECLARATION_CLASS, propertyDescriptor, classDescriptor);
856 JetObjectDeclarationName nameAsDeclaration = objectDeclaration.getNameAsDeclaration();
857 if (nameAsDeclaration != null) {
858 trace.record(BindingContext.OBJECT_DECLARATION, nameAsDeclaration, propertyDescriptor);
859 }
860 return propertyDescriptor;
861 }
862
863 @NotNull
864 private static JetType getTypeForObjectDeclaration(@NotNull ClassDescriptor objectClassDescriptor) {
865 if (objectClassDescriptor.getKind() == ClassKind.ENUM_ENTRY) {
866 DeclarationDescriptor containingDeclaration = objectClassDescriptor.getContainingDeclaration().getContainingDeclaration();
867 assert containingDeclaration instanceof ClassDescriptor;
868 ClassDescriptor enumClass = (ClassDescriptor) containingDeclaration;
869 assert enumClass.getKind() == ClassKind.ENUM_CLASS;
870 return enumClass.getDefaultType();
871 }
872 return objectClassDescriptor.getDefaultType();
873 }
874
875 @NotNull
876 private VariableDescriptor resolveObjectDeclarationAsLocalVariable(
877 @NotNull DeclarationDescriptor containingDeclaration,
878 @NotNull JetClassOrObject objectDeclaration,
879 @NotNull ClassDescriptor classDescriptor, BindingTrace trace
880 ) {
881 VariableDescriptorImpl variableDescriptor = new LocalVariableDescriptor(
882 containingDeclaration,
883 annotationResolver.getResolvedAnnotations(objectDeclaration.getModifierList(), trace),
884 JetPsiUtil.safeName(objectDeclaration.getName()),
885 classDescriptor.getDefaultType(),
886 /*isVar =*/ false);
887 trace.record(BindingContext.OBJECT_DECLARATION_CLASS, variableDescriptor, classDescriptor);
888 JetObjectDeclarationName nameAsDeclaration = objectDeclaration.getNameAsDeclaration();
889 if (nameAsDeclaration != null) {
890 trace.record(BindingContext.VARIABLE, nameAsDeclaration, variableDescriptor);
891 }
892 return variableDescriptor;
893 }
894
895 public JetScope getPropertyDeclarationInnerScope(
896 @NotNull PropertyDescriptor propertyDescriptor,
897 @NotNull JetScope outerScope,
898 @NotNull List<? extends TypeParameterDescriptor> typeParameters,
899 @Nullable ReceiverParameterDescriptor receiver,
900 BindingTrace trace
901 ) {
902 return getPropertyDeclarationInnerScope(propertyDescriptor, outerScope, typeParameters, receiver, trace, true);
903 }
904
905 public JetScope getPropertyDeclarationInnerScopeForInitializer(
906 @NotNull JetScope outerScope,
907 @NotNull List<? extends TypeParameterDescriptor> typeParameters,
908 @Nullable ReceiverParameterDescriptor receiver,
909 BindingTrace trace
910 ) {
911 return getPropertyDeclarationInnerScope(null, outerScope, typeParameters, receiver, trace, false);
912 }
913
914 private JetScope getPropertyDeclarationInnerScope(
915 @Nullable PropertyDescriptor propertyDescriptor, // PropertyDescriptor can be null for property scope which hasn't label to property (in this case addLabelForProperty parameter must be false
916 @NotNull JetScope outerScope,
917 @NotNull List<? extends TypeParameterDescriptor> typeParameters,
918 @Nullable ReceiverParameterDescriptor receiver,
919 BindingTrace trace,
920 boolean addLabelForProperty
921 ) {
922 WritableScopeImpl result = new WritableScopeImpl(
923 outerScope, outerScope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(trace),
924 "Property declaration inner scope");
925 if (addLabelForProperty) {
926 assert propertyDescriptor != null : "PropertyDescriptor can be null for property scope which hasn't label to property";
927 result.addLabeledDeclaration(propertyDescriptor);
928 }
929 for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
930 result.addTypeParameterDescriptor(typeParameterDescriptor);
931 }
932 if (receiver != null) {
933 result.setImplicitReceiver(receiver);
934 }
935 result.changeLockLevel(WritableScope.LockLevel.READING);
936 return result;
937 }
938
939 @NotNull
940 public PropertyDescriptor resolvePropertyDescriptor(
941 @NotNull DeclarationDescriptor containingDeclaration,
942 @NotNull JetScope scope,
943 @NotNull JetProperty property,
944 @NotNull BindingTrace trace,
945 @NotNull DataFlowInfo dataFlowInfo
946 ) {
947
948 JetModifierList modifierList = property.getModifierList();
949 boolean isVar = property.isVar();
950
951 boolean hasBody = hasBody(property);
952 Modality modality = containingDeclaration instanceof ClassDescriptor
953 ? resolveModalityFromModifiers(property, getDefaultModality(containingDeclaration, hasBody))
954 : Modality.FINAL;
955 Visibility visibility = resolveVisibilityFromModifiers(property, getDefaultVisibility(property, containingDeclaration));
956 PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl(
957 containingDeclaration,
958 annotationResolver.resolveAnnotations(scope, modifierList, trace),
959 modality,
960 visibility,
961 isVar,
962 JetPsiUtil.safeName(property.getName()),
963 CallableMemberDescriptor.Kind.DECLARATION
964 );
965
966 List<TypeParameterDescriptorImpl> typeParameterDescriptors;
967 JetScope scopeWithTypeParameters;
968 JetType receiverType = null;
969
970 {
971 List<JetTypeParameter> typeParameters = property.getTypeParameters();
972 if (typeParameters.isEmpty()) {
973 scopeWithTypeParameters = scope;
974 typeParameterDescriptors = Collections.emptyList();
975 }
976 else {
977 WritableScope writableScope = new WritableScopeImpl(
978 scope, containingDeclaration, new TraceBasedRedeclarationHandler(trace),
979 "Scope with type parameters of a property");
980 typeParameterDescriptors = resolveTypeParametersForCallableDescriptor(containingDeclaration, writableScope, typeParameters,
981 trace);
982 writableScope.changeLockLevel(WritableScope.LockLevel.READING);
983 resolveGenericBounds(property, writableScope, typeParameterDescriptors, trace);
984 scopeWithTypeParameters = writableScope;
985 }
986
987 JetTypeReference receiverTypeRef = property.getReceiverTypeRef();
988 if (receiverTypeRef != null) {
989 receiverType = typeResolver.resolveType(scopeWithTypeParameters, receiverTypeRef, trace, true);
990 }
991 }
992
993 ReceiverParameterDescriptor receiverDescriptor = resolveReceiverParameterFor(propertyDescriptor, receiverType);
994
995 JetScope propertyScope = getPropertyDeclarationInnerScope(propertyDescriptor, scope, typeParameterDescriptors,
996 NO_RECEIVER_PARAMETER, trace);
997
998 JetType type = getVariableType(propertyDescriptor, propertyScope, property, dataFlowInfo, true, trace);
999
1000 propertyDescriptor.setType(type, typeParameterDescriptors, getExpectedThisObjectIfNeeded(containingDeclaration),
1001 receiverDescriptor);
1002
1003 PropertyGetterDescriptorImpl getter = resolvePropertyGetterDescriptor(scopeWithTypeParameters, property, propertyDescriptor, trace);
1004 PropertySetterDescriptor setter = resolvePropertySetterDescriptor(scopeWithTypeParameters, property, propertyDescriptor, trace);
1005
1006 propertyDescriptor.initialize(getter, setter);
1007
1008 trace.record(BindingContext.VARIABLE, property, propertyDescriptor);
1009 return propertyDescriptor;
1010 }
1011
1012 /*package*/
1013 static boolean hasBody(JetProperty property) {
1014 boolean hasBody = property.getDelegateExpressionOrInitializer() != null;
1015 if (!hasBody) {
1016 JetPropertyAccessor getter = property.getGetter();
1017 if (getter != null && getter.getBodyExpression() != null) {
1018 hasBody = true;
1019 }
1020 JetPropertyAccessor setter = property.getSetter();
1021 if (!hasBody && setter != null && setter.getBodyExpression() != null) {
1022 hasBody = true;
1023 }
1024 }
1025 return hasBody;
1026 }
1027
1028 @NotNull
1029 private JetType getVariableType(
1030 @NotNull final VariableDescriptor variableDescriptor,
1031 @NotNull final JetScope scope,
1032 @NotNull final JetVariableDeclaration variable,
1033 @NotNull final DataFlowInfo dataFlowInfo,
1034 boolean notLocal,
1035 @NotNull final BindingTrace trace
1036 ) {
1037 JetTypeReference propertyTypeRef = variable.getTypeRef();
1038
1039 boolean hasDelegate = variable instanceof JetProperty && ((JetProperty) variable).getDelegateExpression() != null;
1040 if (propertyTypeRef == null) {
1041 final JetExpression initializer = variable.getInitializer();
1042 if (initializer == null) {
1043 if (hasDelegate && variableDescriptor instanceof PropertyDescriptor) {
1044 final JetExpression propertyDelegateExpression = ((JetProperty) variable).getDelegateExpression();
1045 if (propertyDelegateExpression != null) {
1046 return DeferredType.create(trace, new RecursionIntolerantLazyValueWithDefault<JetType>(ErrorUtils.createErrorType("Recursive dependency")) {
1047 @Override
1048 protected JetType compute() {
1049 return resolveDelegatedPropertyType((PropertyDescriptor) variableDescriptor, scope,
1050 propertyDelegateExpression, dataFlowInfo, trace);
1051 }
1052 });
1053 }
1054 }
1055 if (!notLocal) {
1056 trace.report(VARIABLE_WITH_NO_TYPE_NO_INITIALIZER.on(variable));
1057 }
1058 return ErrorUtils.createErrorType("No type, no body");
1059 }
1060 else {
1061 if (notLocal) {
1062 return DeferredType.create(trace, new RecursionIntolerantLazyValueWithDefault<JetType>(ErrorUtils.createErrorType("Recursive dependency")) {
1063 @Override
1064 protected JetType compute() {
1065 JetType type = resolveInitializerType(scope, initializer, dataFlowInfo, trace);
1066
1067 return transformAnonymousTypeIfNeeded(variableDescriptor, variable, type, trace);
1068 }
1069 });
1070 }
1071 else {
1072 return resolveInitializerType(scope, initializer, dataFlowInfo, trace);
1073 }
1074 }
1075 }
1076 else {
1077 return typeResolver.resolveType(scope, propertyTypeRef, trace, true);
1078 }
1079 }
1080
1081 @NotNull
1082 private JetType resolveDelegatedPropertyType(
1083 @NotNull PropertyDescriptor propertyDescriptor,
1084 @NotNull JetScope scope,
1085 @NotNull JetExpression delegateExpression,
1086 @NotNull DataFlowInfo dataFlowInfo,
1087 @NotNull BindingTrace trace
1088 ) {
1089 JetType type = expressionTypingServices.safeGetType(scope, delegateExpression, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, trace);
1090
1091 JetScope accessorScope = JetScopeUtils.makeScopeForPropertyAccessor(propertyDescriptor, scope, this, trace);
1092 JetType getterReturnType = DelegatedPropertyUtils
1093 .getDelegatedPropertyGetMethodReturnType(propertyDescriptor, delegateExpression, type, expressionTypingServices, trace,
1094 accessorScope);
1095 if (getterReturnType != null) {
1096 return getterReturnType;
1097 }
1098 return ErrorUtils.createErrorType("Type from delegate");
1099 }
1100
1101 @Nullable
1102 private JetType transformAnonymousTypeIfNeeded(
1103 @NotNull DeclarationDescriptorWithVisibility descriptor,
1104 @NotNull JetNamedDeclaration declaration,
1105 @NotNull JetType type,
1106 @NotNull BindingTrace trace
1107 ) {
1108 ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor();
1109 if (!DescriptorUtils.isAnonymous(classifierDescriptor)) {
1110 return type;
1111 }
1112
1113 boolean definedInClass = DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class) != null;
1114 boolean isLocal = descriptor.getContainingDeclaration() instanceof CallableDescriptor;
1115 Visibility visibility = descriptor.getVisibility();
1116 boolean transformNeeded = !isLocal && !visibility.isPublicAPI()
1117 && !(definedInClass && Visibilities.PRIVATE.equals(visibility));
1118 if (transformNeeded) {
1119 if (type.getConstructor().getSupertypes().size() == 1) {
1120 assert type.getArguments().isEmpty() : "Object expression couldn't have any type parameters!";
1121 return type.getConstructor().getSupertypes().iterator().next();
1122 }
1123 else {
1124 trace.report(AMBIGUOUS_ANONYMOUS_TYPE_INFERRED.on(declaration, type.getConstructor().getSupertypes()));
1125 }
1126 }
1127 return type;
1128 }
1129
1130 @NotNull
1131 private JetType resolveInitializerType(
1132 @NotNull JetScope scope,
1133 @NotNull JetExpression initializer,
1134 @NotNull DataFlowInfo dataFlowInfo,
1135 @NotNull BindingTrace trace
1136 ) {
1137 return expressionTypingServices.safeGetType(scope, initializer, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, trace);
1138 }
1139
1140 @Nullable
1141 private PropertySetterDescriptor resolvePropertySetterDescriptor(
1142 @NotNull JetScope scope,
1143 @NotNull JetProperty property,
1144 @NotNull PropertyDescriptor propertyDescriptor,
1145 BindingTrace trace
1146 ) {
1147 JetPropertyAccessor setter = property.getSetter();
1148 PropertySetterDescriptorImpl setterDescriptor = null;
1149 if (setter != null) {
1150 List<AnnotationDescriptor> annotations = annotationResolver.resolveAnnotations(scope, setter.getModifierList(), trace);
1151 JetParameter parameter = setter.getParameter();
1152
1153 setterDescriptor = new PropertySetterDescriptorImpl(
1154 propertyDescriptor, annotations,
1155 resolveModalityFromModifiers(setter, propertyDescriptor.getModality()),
1156 resolveVisibilityFromModifiers(setter, propertyDescriptor.getVisibility()),
1157 setter.getBodyExpression() != null, false, CallableMemberDescriptor.Kind.DECLARATION);
1158 if (parameter != null) {
1159
1160 // This check is redundant: the parser does not allow a default value, but we'll keep it just in case
1161 JetExpression defaultValue = parameter.getDefaultValue();
1162 if (defaultValue != null) {
1163 trace.report(SETTER_PARAMETER_WITH_DEFAULT_VALUE.on(defaultValue));
1164 }
1165
1166 JetType type;
1167 JetTypeReference typeReference = parameter.getTypeReference();
1168 if (typeReference == null) {
1169 type = propertyDescriptor.getType(); // TODO : this maybe unknown at this point
1170 }
1171 else {
1172 type = typeResolver.resolveType(scope, typeReference, trace, true);
1173 JetType inType = propertyDescriptor.getType();
1174 if (inType != null) {
1175 if (!TypeUtils.equalTypes(type, inType)) {
1176 trace.report(WRONG_SETTER_PARAMETER_TYPE.on(typeReference, inType, type));
1177 }
1178 }
1179 else {
1180 // TODO : the same check may be needed later???
1181 }
1182 }
1183
1184 MutableValueParameterDescriptor valueParameterDescriptor =
1185 resolveValueParameterDescriptor(scope, setterDescriptor, parameter, 0, type, trace);
1186 setterDescriptor.initialize(valueParameterDescriptor);
1187 }
1188 else {
1189 setterDescriptor.initializeDefault();
1190 }
1191
1192 trace.record(BindingContext.PROPERTY_ACCESSOR, setter, setterDescriptor);
1193 }
1194 else if (property.isVar()) {
1195 if (property.getDelegateExpression() != null) {
1196 setterDescriptor = createSetterForDelegatedProperty(propertyDescriptor);
1197 }
1198 else {
1199 setterDescriptor = createDefaultSetter(propertyDescriptor);
1200 }
1201 }
1202
1203 if (!property.isVar()) {
1204 if (setter != null) {
1205 // trace.getErrorHandler().genericError(setter.asElement().getNode(), "A 'val'-property cannot have a setter");
1206 trace.report(VAL_WITH_SETTER.on(setter));
1207 }
1208 }
1209 return setterDescriptor;
1210 }
1211
1212 @NotNull
1213 public static PropertySetterDescriptorImpl createDefaultSetter(@NotNull PropertyDescriptor propertyDescriptor) {
1214 return createSetter(propertyDescriptor, false, true);
1215 }
1216
1217 @NotNull
1218 public static PropertySetterDescriptorImpl createSetterForDelegatedProperty(@NotNull PropertyDescriptor propertyDescriptor) {
1219 return createSetter(propertyDescriptor, true, false);
1220 }
1221
1222 @NotNull
1223 private static PropertySetterDescriptorImpl createSetter(@NotNull PropertyDescriptor propertyDescriptor, boolean hasBody, boolean isDefault) {
1224 PropertySetterDescriptorImpl setterDescriptor;
1225 setterDescriptor = new PropertySetterDescriptorImpl(
1226 propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), propertyDescriptor.getModality(),
1227 propertyDescriptor.getVisibility(),
1228 hasBody, isDefault, CallableMemberDescriptor.Kind.DECLARATION);
1229 setterDescriptor.initializeDefault();
1230 return setterDescriptor;
1231 }
1232
1233 @Nullable
1234 private PropertyGetterDescriptorImpl resolvePropertyGetterDescriptor(
1235 @NotNull JetScope scope,
1236 @NotNull JetProperty property,
1237 @NotNull PropertyDescriptor propertyDescriptor,
1238 BindingTrace trace
1239 ) {
1240 PropertyGetterDescriptorImpl getterDescriptor;
1241 JetPropertyAccessor getter = property.getGetter();
1242 if (getter != null) {
1243 List<AnnotationDescriptor> annotations = annotationResolver.resolveAnnotations(scope, getter.getModifierList(), trace);
1244
1245 JetType outType = propertyDescriptor.getType();
1246 JetType returnType = outType;
1247 JetTypeReference returnTypeReference = getter.getReturnTypeReference();
1248 if (returnTypeReference != null) {
1249 returnType = typeResolver.resolveType(scope, returnTypeReference, trace, true);
1250 if (outType != null && !TypeUtils.equalTypes(returnType, outType)) {
1251 trace.report(WRONG_GETTER_RETURN_TYPE.on(returnTypeReference, propertyDescriptor.getReturnType(), outType));
1252 }
1253 }
1254
1255 getterDescriptor = new PropertyGetterDescriptorImpl(
1256 propertyDescriptor, annotations,
1257 resolveModalityFromModifiers(getter, propertyDescriptor.getModality()),
1258 resolveVisibilityFromModifiers(getter, propertyDescriptor.getVisibility()),
1259 getter.getBodyExpression() != null, false, CallableMemberDescriptor.Kind.DECLARATION);
1260 getterDescriptor.initialize(returnType);
1261 trace.record(BindingContext.PROPERTY_ACCESSOR, getter, getterDescriptor);
1262 }
1263 else {
1264 if (property.getDelegateExpression() != null) {
1265 getterDescriptor = createGetterForDelegatedProperty(propertyDescriptor);
1266 }
1267 else {
1268 getterDescriptor = createDefaultGetter(propertyDescriptor);
1269 }
1270 getterDescriptor.initialize(propertyDescriptor.getType());
1271 }
1272 return getterDescriptor;
1273 }
1274
1275 @NotNull
1276 public static PropertyGetterDescriptorImpl createDefaultGetter(@NotNull PropertyDescriptor propertyDescriptor) {
1277 return createGetter(propertyDescriptor, false, true);
1278 }
1279
1280 @NotNull
1281 public static PropertyGetterDescriptorImpl createGetterForDelegatedProperty(@NotNull PropertyDescriptor propertyDescriptor) {
1282 return createGetter(propertyDescriptor, true, false);
1283 }
1284
1285 private static PropertyGetterDescriptorImpl createGetter(@NotNull PropertyDescriptor propertyDescriptor, boolean hasBody, boolean isDefault) {
1286 PropertyGetterDescriptorImpl getterDescriptor;
1287 getterDescriptor = new PropertyGetterDescriptorImpl(
1288 propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), propertyDescriptor.getModality(),
1289 propertyDescriptor.getVisibility(),
1290 hasBody, isDefault, CallableMemberDescriptor.Kind.DECLARATION);
1291 return getterDescriptor;
1292 }
1293
1294 @NotNull
1295 private ConstructorDescriptorImpl createConstructorDescriptor(
1296 @NotNull JetScope scope,
1297 @NotNull ClassDescriptor classDescriptor,
1298 boolean isPrimary,
1299 @Nullable JetModifierList modifierList,
1300 @NotNull JetDeclaration declarationToTrace,
1301 List<TypeParameterDescriptor> typeParameters, @NotNull List<JetParameter> valueParameters, BindingTrace trace
1302 ) {
1303 ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
1304 classDescriptor,
1305 annotationResolver.resolveAnnotations(scope, modifierList, trace),
1306 isPrimary
1307 );
1308 trace.record(BindingContext.CONSTRUCTOR, declarationToTrace, constructorDescriptor);
1309 WritableScopeImpl parameterScope = new WritableScopeImpl(
1310 scope, constructorDescriptor, new TraceBasedRedeclarationHandler(trace), "Scope with value parameters of a constructor");
1311 parameterScope.changeLockLevel(WritableScope.LockLevel.BOTH);
1312 ConstructorDescriptorImpl constructor = constructorDescriptor.initialize(
1313 typeParameters,
1314 resolveValueParameters(
1315 constructorDescriptor,
1316 parameterScope,
1317 valueParameters, trace),
1318 resolveVisibilityFromModifiers(modifierList, getDefaultConstructorVisibility(classDescriptor)),
1319 DescriptorUtils.isConstructorOfStaticNestedClass(constructorDescriptor));
1320 if (isAnnotationClass(classDescriptor)) {
1321 AnnotationUtils.checkConstructorParametersType(valueParameters, trace);
1322 }
1323 return constructor;
1324 }
1325
1326 @Nullable
1327 public ConstructorDescriptorImpl resolvePrimaryConstructorDescriptor(
1328 @NotNull JetScope scope,
1329 @NotNull ClassDescriptor classDescriptor,
1330 @NotNull JetClass classElement,
1331 BindingTrace trace
1332 ) {
1333 if (classDescriptor.getKind() == ClassKind.ENUM_ENTRY) return null;
1334 return createConstructorDescriptor(
1335 scope,
1336 classDescriptor,
1337 true,
1338 classElement.getPrimaryConstructorModifierList(),
1339 classElement,
1340 classDescriptor.getTypeConstructor().getParameters(), classElement.getPrimaryConstructorParameters(), trace);
1341 }
1342
1343 @NotNull
1344 public PropertyDescriptor resolvePrimaryConstructorParameterToAProperty(
1345 @NotNull ClassDescriptor classDescriptor,
1346 @NotNull ValueParameterDescriptor valueParameter,
1347 @NotNull JetScope scope,
1348 @NotNull JetParameter parameter, BindingTrace trace
1349 ) {
1350 JetType type = resolveParameterType(scope, parameter, trace);
1351 Name name = parameter.getNameAsSafeName();
1352 boolean isMutable = parameter.isMutable();
1353 JetModifierList modifierList = parameter.getModifierList();
1354
1355 if (modifierList != null) {
1356 ASTNode abstractNode = modifierList.getModifierNode(JetTokens.ABSTRACT_KEYWORD);
1357 if (abstractNode != null) {
1358 trace.report(ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS.on(parameter));
1359 }
1360 }
1361
1362 PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl(
1363 classDescriptor,
1364 valueParameter.getAnnotations(),
1365 resolveModalityFromModifiers(parameter, Modality.FINAL),
1366 resolveVisibilityFromModifiers(parameter),
1367 isMutable,
1368 name,
1369 CallableMemberDescriptor.Kind.DECLARATION
1370 );
1371 propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(),
1372 getExpectedThisObjectIfNeeded(classDescriptor), NO_RECEIVER_PARAMETER);
1373
1374 PropertyGetterDescriptorImpl getter = createDefaultGetter(propertyDescriptor);
1375 PropertySetterDescriptor setter = propertyDescriptor.isVar() ? createDefaultSetter(propertyDescriptor) : null;
1376
1377 propertyDescriptor.initialize(getter, setter);
1378 getter.initialize(propertyDescriptor.getType());
1379
1380 trace.record(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter, propertyDescriptor);
1381 trace.record(BindingContext.VALUE_PARAMETER_AS_PROPERTY, valueParameter, propertyDescriptor);
1382 return propertyDescriptor;
1383 }
1384
1385 public static void checkBounds(@NotNull JetTypeReference typeReference, @NotNull JetType type, BindingTrace trace) {
1386 if (ErrorUtils.isErrorType(type)) return;
1387
1388 JetTypeElement typeElement = typeReference.getTypeElement();
1389 if (typeElement == null) return;
1390
1391 List<TypeParameterDescriptor> parameters = type.getConstructor().getParameters();
1392 List<TypeProjection> arguments = type.getArguments();
1393 assert parameters.size() == arguments.size();
1394
1395 List<JetTypeReference> jetTypeArguments = typeElement.getTypeArgumentsAsTypes();
1396 assert jetTypeArguments.size() == arguments.size() : typeElement.getText();
1397
1398 TypeSubstitutor substitutor = TypeSubstitutor.create(type);
1399 for (int i = 0; i < jetTypeArguments.size(); i++) {
1400 JetTypeReference jetTypeArgument = jetTypeArguments.get(i);
1401
1402 if (jetTypeArgument == null) continue;
1403
1404 JetType typeArgument = arguments.get(i).getType();
1405 checkBounds(jetTypeArgument, typeArgument, trace);
1406
1407 TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
1408 checkBounds(jetTypeArgument, typeArgument, typeParameterDescriptor, substitutor, trace);
1409 }
1410 }
1411
1412 public static void checkBounds(
1413 @NotNull JetTypeReference jetTypeArgument,
1414 @NotNull JetType typeArgument,
1415 @NotNull TypeParameterDescriptor typeParameterDescriptor,
1416 @NotNull TypeSubstitutor substitutor, BindingTrace trace
1417 ) {
1418 for (JetType bound : typeParameterDescriptor.getUpperBounds()) {
1419 JetType substitutedBound = substitutor.safeSubstitute(bound, Variance.INVARIANT);
1420 if (!JetTypeChecker.INSTANCE.isSubtypeOf(typeArgument, substitutedBound)) {
1421 trace.report(UPPER_BOUND_VIOLATED.on(jetTypeArgument, substitutedBound, typeArgument));
1422 }
1423 }
1424 }
1425
1426 public static SimpleFunctionDescriptor createEnumClassObjectValuesMethod(
1427 @NotNull ClassDescriptor classObjectDescriptor,
1428 BindingTrace trace
1429 ) {
1430 final ClassDescriptor enumClassDescriptor = (ClassDescriptor) classObjectDescriptor.getContainingDeclaration();
1431 assert enumClassDescriptor.getKind() == ClassKind.ENUM_CLASS;
1432 List<AnnotationDescriptor> annotations = Collections.<AnnotationDescriptor>emptyList();
1433 SimpleFunctionDescriptorImpl values =
1434 new SimpleFunctionDescriptorImpl(classObjectDescriptor, annotations,
1435 VALUES_METHOD_NAME,
1436 CallableMemberDescriptor.Kind.DECLARATION);
1437 JetType type = DeferredType.create(trace, new RecursionIntolerantLazyValue<JetType>() {
1438 @Override
1439 protected JetType compute() {
1440 return KotlinBuiltIns.getInstance().getArrayType(enumClassDescriptor.getDefaultType());
1441 }
1442 });
1443 values.initialize(null, classObjectDescriptor.getThisAsReceiverParameter(), Collections.<TypeParameterDescriptor>emptyList(),
1444 Collections.<ValueParameterDescriptor>emptyList(),
1445 type, Modality.FINAL,
1446 Visibilities.PUBLIC, false);
1447 return values;
1448 }
1449
1450 public static SimpleFunctionDescriptor createEnumClassObjectValueOfMethod(
1451 @NotNull ClassDescriptor classObjectDescriptor,
1452 BindingTrace trace
1453 ) {
1454 final ClassDescriptor enumClassDescriptor = (ClassDescriptor) classObjectDescriptor.getContainingDeclaration();
1455 assert enumClassDescriptor.getKind() == ClassKind.ENUM_CLASS;
1456 List<AnnotationDescriptor> annotations = Collections.<AnnotationDescriptor>emptyList();
1457 SimpleFunctionDescriptorImpl values =
1458 new SimpleFunctionDescriptorImpl(classObjectDescriptor, annotations,
1459 VALUE_OF_METHOD_NAME,
1460 CallableMemberDescriptor.Kind.DECLARATION);
1461 JetType type = DeferredType.create(trace, new RecursionIntolerantLazyValue<JetType>() {
1462 @Override
1463 protected JetType compute() {
1464 return enumClassDescriptor.getDefaultType();
1465 }
1466 });
1467 ValueParameterDescriptor parameterDescriptor = new ValueParameterDescriptorImpl(
1468 values,
1469 0,
1470 Collections.<AnnotationDescriptor>emptyList(),
1471 Name.identifier("value"),
1472 KotlinBuiltIns.getInstance().getStringType(),
1473 false,
1474 null);
1475 values.initialize(null, classObjectDescriptor.getThisAsReceiverParameter(),
1476 Collections.<TypeParameterDescriptor>emptyList(),
1477 Collections.singletonList(parameterDescriptor),
1478 type, Modality.FINAL,
1479 Visibilities.PUBLIC, false);
1480 return values;
1481 }
1482
1483 public static ReceiverParameterDescriptor createLazyReceiverParameterDescriptor(@NotNull final ClassDescriptor classDescriptor) {
1484 return new AbstractReceiverParameterDescriptor() {
1485
1486 private ClassReceiver value;
1487
1488 @NotNull
1489 @Override
1490 public JetType getType() {
1491 // This must be lazy, thus the inner class
1492 return classDescriptor.getDefaultType();
1493 }
1494
1495 @NotNull
1496 @Override
1497 public ReceiverValue getValue() {
1498 if (value == null) {
1499 value = new ClassReceiver(classDescriptor);
1500 }
1501 return value;
1502 }
1503
1504 @NotNull
1505 @Override
1506 public DeclarationDescriptor getContainingDeclaration() {
1507 return classDescriptor;
1508 }
1509
1510 @Override
1511 public String toString() {
1512 return "class " + classDescriptor.getName() + "::this";
1513 }
1514 };
1515 }
1516
1517 public static boolean checkHasOuterClassInstance(
1518 @NotNull JetScope scope,
1519 @NotNull BindingTrace trace,
1520 @NotNull PsiElement reportErrorsOn,
1521 @NotNull ClassDescriptor target
1522 ) {
1523 return checkHasOuterClassInstance(scope, trace, reportErrorsOn, target, true);
1524 }
1525
1526 public static boolean checkHasOuterClassInstance(
1527 @NotNull JetScope scope,
1528 @NotNull BindingTrace trace,
1529 @NotNull PsiElement reportErrorsOn,
1530 @NotNull ClassDescriptor target,
1531 boolean doSuperClassCheck
1532 ) {
1533 DeclarationDescriptor descriptor = getContainingClass(scope);
1534
1535 while (descriptor != null) {
1536 if (descriptor instanceof ClassDescriptor) {
1537 ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
1538
1539 if (classDescriptor == target) {
1540 return true;
1541 }
1542
1543 if (doSuperClassCheck && isSubclass(classDescriptor, target)) {
1544 return true;
1545 }
1546
1547 if (isStaticNestedClass(classDescriptor)) {
1548 trace.report(INACCESSIBLE_OUTER_CLASS_EXPRESSION.on(reportErrorsOn, classDescriptor));
1549 return false;
1550 }
1551 }
1552 descriptor = descriptor.getContainingDeclaration();
1553 }
1554 return true;
1555 }
1556
1557 public static void checkParameterHasNoValOrVar(
1558 @NotNull BindingTrace trace,
1559 @NotNull JetParameter parameter,
1560 @NotNull DiagnosticFactory1<PsiElement, JetKeywordToken> diagnosticFactory
1561 ) {
1562 ASTNode valOrVarNode = parameter.getValOrVarNode();
1563 if (valOrVarNode != null) {
1564 trace.report(diagnosticFactory.on(valOrVarNode.getPsi(), ((JetKeywordToken) valOrVarNode.getElementType())));
1565 }
1566 }
1567 }