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