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