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