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