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