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