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.google.common.collect.Sets;
022 import com.intellij.lang.ASTNode;
023 import com.intellij.psi.PsiElement;
024 import com.intellij.util.containers.ContainerUtil;
025 import com.intellij.util.containers.LinkedMultiMap;
026 import com.intellij.util.containers.MultiMap;
027 import kotlin.KotlinPackage;
028 import org.jetbrains.annotations.NotNull;
029 import org.jetbrains.jet.lang.descriptors.*;
030 import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
031 import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
032 import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptorLite;
033 import org.jetbrains.jet.lang.diagnostics.Errors;
034 import org.jetbrains.jet.lang.psi.*;
035 import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
036 import org.jetbrains.jet.lang.resolve.name.Name;
037 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
038 import org.jetbrains.jet.lang.types.JetType;
039 import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
040 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
041 import org.jetbrains.jet.lexer.JetTokens;
042
043 import javax.inject.Inject;
044 import java.util.*;
045
046 import static org.jetbrains.jet.lang.diagnostics.Errors.*;
047 import static org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE;
048
049 public class OverrideResolver {
050
051 private BindingTrace trace;
052
053 @Inject
054 public void setTrace(BindingTrace trace) {
055 this.trace = trace;
056 }
057
058
059
060 public void process(@NotNull TopDownAnalysisContext c) {
061 //all created fake descriptors are stored to resolve visibility on them later
062 generateOverridesAndDelegation(c);
063
064 check(c);
065 }
066
067 public void check(@NotNull TopDownAnalysisContext c) {
068 checkVisibility(c);
069 checkOverrides(c);
070 checkParameterOverridesForAllClasses(c);
071 }
072
073 /**
074 * Generate fake overrides and add overridden descriptors to existing descriptors.
075 */
076 private void generateOverridesAndDelegation(@NotNull TopDownAnalysisContext c) {
077 Set<ClassDescriptorWithResolutionScopes> ourClasses = new HashSet<ClassDescriptorWithResolutionScopes>(c.getClasses().values());
078 Set<ClassifierDescriptor> processed = new HashSet<ClassifierDescriptor>();
079
080 for (MutableClassDescriptorLite klass : ContainerUtil.reverse(c.getClassesTopologicalOrder())) {
081 if (klass instanceof MutableClassDescriptor && ourClasses.contains(klass)) {
082 generateOverridesAndDelegationInAClass((MutableClassDescriptor) klass, processed, ourClasses);
083
084 MutableClassDescriptorLite classObject = klass.getClassObjectDescriptor();
085 if (classObject instanceof MutableClassDescriptor) {
086 generateOverridesAndDelegationInAClass((MutableClassDescriptor) classObject, processed, ourClasses);
087 }
088 }
089 }
090 }
091
092 private void generateOverridesAndDelegationInAClass(
093 @NotNull MutableClassDescriptor classDescriptor,
094 @NotNull Set<ClassifierDescriptor> processed,
095 @NotNull Set<ClassDescriptorWithResolutionScopes> classesBeingAnalyzed
096 // to filter out classes such as stdlib and others that come from dependencies
097 ) {
098 if (!processed.add(classDescriptor)) {
099 return;
100 }
101
102 for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
103 ClassDescriptor superclass = (ClassDescriptor) supertype.getConstructor().getDeclarationDescriptor();
104 if (superclass instanceof MutableClassDescriptor && classesBeingAnalyzed.contains(superclass)) {
105 generateOverridesAndDelegationInAClass((MutableClassDescriptor) superclass, processed, classesBeingAnalyzed);
106 }
107 }
108
109 JetClassOrObject classOrObject = (JetClassOrObject) BindingContextUtils
110 .classDescriptorToDeclaration(trace.getBindingContext(), classDescriptor);
111 if (classOrObject != null) {
112 DelegationResolver.generateDelegatesInAClass(classDescriptor, trace, classOrObject);
113 }
114
115 generateOverridesInAClass(classDescriptor);
116 }
117
118 private void generateOverridesInAClass(@NotNull final MutableClassDescriptor classDescriptor) {
119 List<CallableMemberDescriptor> membersFromSupertypes = getCallableMembersFromSupertypes(classDescriptor);
120
121 MultiMap<Name, CallableMemberDescriptor> membersFromSupertypesByName = groupDescriptorsByName(membersFromSupertypes);
122
123 MultiMap<Name, CallableMemberDescriptor> membersFromCurrentByName = groupDescriptorsByName(classDescriptor.getDeclaredCallableMembers());
124
125 Set<Name> memberNames = new LinkedHashSet<Name>();
126 memberNames.addAll(membersFromSupertypesByName.keySet());
127 memberNames.addAll(membersFromCurrentByName.keySet());
128
129 for (Name memberName : memberNames) {
130 Collection<CallableMemberDescriptor> fromSupertypes = membersFromSupertypesByName.get(memberName);
131 Collection<CallableMemberDescriptor> fromCurrent = membersFromCurrentByName.get(memberName);
132
133 OverridingUtil.generateOverridesInFunctionGroup(
134 memberName,
135 fromSupertypes,
136 fromCurrent,
137 classDescriptor,
138 new OverridingUtil.DescriptorSink() {
139 @Override
140 public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
141 if (fakeOverride instanceof PropertyDescriptor) {
142 classDescriptor.getBuilder().addPropertyDescriptor((PropertyDescriptor) fakeOverride);
143 }
144 else if (fakeOverride instanceof SimpleFunctionDescriptor) {
145 classDescriptor.getBuilder().addFunctionDescriptor((SimpleFunctionDescriptor) fakeOverride);
146 }
147 else {
148 throw new IllegalStateException(fakeOverride.getClass().getName());
149 }
150 }
151
152 @Override
153 public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) {
154 JetDeclaration declaration = (JetDeclaration) BindingContextUtils
155 .descriptorToDeclaration(trace.getBindingContext(), fromCurrent);
156 trace.report(Errors.CONFLICTING_OVERLOADS.on(declaration, fromCurrent, fromCurrent.getContainingDeclaration().getName().asString()));
157 }
158 });
159 }
160 resolveUnknownVisibilities(classDescriptor.getAllCallableMembers(), trace);
161 }
162
163 public static void resolveUnknownVisibilities(
164 @NotNull Collection<? extends CallableMemberDescriptor> descriptors,
165 @NotNull BindingTrace trace) {
166 for (CallableMemberDescriptor descriptor : descriptors) {
167 resolveUnknownVisibilityForMember(descriptor, trace);
168 }
169 }
170
171 public static void resolveUnknownVisibilityForMember(@NotNull CallableMemberDescriptor descriptor, @NotNull final BindingTrace trace) {
172 OverridingUtil.resolveUnknownVisibilityForMember(descriptor, new OverridingUtil.NotInferredVisibilitySink() {
173 @Override
174 public void cannotInferVisibility(@NotNull CallableMemberDescriptor descriptor) {
175 PsiElement element = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), descriptor);
176 if (element instanceof JetDeclaration) {
177 trace.report(CANNOT_INFER_VISIBILITY.on((JetDeclaration) element));
178 }
179 }
180 });
181 }
182
183 private static <T extends DeclarationDescriptor> MultiMap<Name, T> groupDescriptorsByName(Collection<T> properties) {
184 MultiMap<Name, T> r = new LinkedMultiMap<Name, T>();
185 for (T property : properties) {
186 r.putValue(property.getName(), property);
187 }
188 return r;
189 }
190
191
192 private static List<CallableMemberDescriptor> getCallableMembersFromSupertypes(ClassDescriptor classDescriptor) {
193 Set<CallableMemberDescriptor> r = Sets.newLinkedHashSet();
194 for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
195 r.addAll(getCallableMembersFromType(supertype.getMemberScope()));
196 }
197 return new ArrayList<CallableMemberDescriptor>(r);
198 }
199
200 private static List<CallableMemberDescriptor> getCallableMembersFromType(JetScope scope) {
201 List<CallableMemberDescriptor> r = Lists.newArrayList();
202 for (DeclarationDescriptor decl : scope.getAllDescriptors()) {
203 if (decl instanceof PropertyDescriptor || decl instanceof SimpleFunctionDescriptor) {
204 r.add((CallableMemberDescriptor) decl);
205 }
206 }
207 return r;
208 }
209
210 private void checkOverrides(@NotNull TopDownAnalysisContext c) {
211 for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getClasses().entrySet()) {
212 checkOverridesInAClass(c, entry.getValue(), entry.getKey());
213 }
214 }
215
216 private void checkOverridesInAClass(@NotNull TopDownAnalysisContext c, @NotNull ClassDescriptorWithResolutionScopes classDescriptor, @NotNull JetClassOrObject klass) {
217 if (c.getTopDownAnalysisParameters().isAnalyzingBootstrapLibrary()) return;
218
219 // Check overrides for internal consistency
220 for (CallableMemberDescriptor member : classDescriptor.getDeclaredCallableMembers()) {
221 checkOverrideForMember(member);
222 }
223
224 // Check if everything that must be overridden, actually is
225 // More than one implementation or no implementations at all
226 Set<CallableMemberDescriptor> abstractNoImpl = Sets.newLinkedHashSet();
227 Set<CallableMemberDescriptor> manyImpl = Sets.newLinkedHashSet();
228 collectMissingImplementations(classDescriptor, abstractNoImpl, manyImpl);
229
230 PsiElement nameIdentifier = null;
231 if (klass instanceof JetClass) {
232 nameIdentifier = klass.getNameIdentifier();
233 }
234 else if (klass instanceof JetObjectDeclaration) {
235 nameIdentifier = klass.getNameIdentifier();
236 if (nameIdentifier == null) {
237 nameIdentifier = ((JetObjectDeclaration) klass).getObjectKeyword();
238 }
239 }
240 if (nameIdentifier == null) return;
241
242 for (CallableMemberDescriptor memberDescriptor : manyImpl) {
243 trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(nameIdentifier, klass, memberDescriptor));
244 break;
245 }
246
247
248 if (classDescriptor.getModality() == Modality.ABSTRACT) {
249 return;
250 }
251
252 for (CallableMemberDescriptor memberDescriptor : abstractNoImpl) {
253 trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(nameIdentifier, klass, memberDescriptor));
254 break;
255 }
256 }
257
258 public static void collectMissingImplementations(
259 MutableClassDescriptor classDescriptor, Set<CallableMemberDescriptor> abstractNoImpl, Set<CallableMemberDescriptor> manyImpl
260 ) {
261 for (CallableMemberDescriptor descriptor : classDescriptor.getAllCallableMembers()) {
262 collectMissingImplementations(descriptor, abstractNoImpl, manyImpl);
263 }
264 }
265
266 public static void collectMissingImplementations(
267 ClassDescriptor classDescriptor, Set<CallableMemberDescriptor> abstractNoImpl, Set<CallableMemberDescriptor> manyImpl
268 ) {
269 Iterator<CallableMemberDescriptor> callableMembers = KotlinPackage.filterIsInstance(
270 classDescriptor.getDefaultType().getMemberScope().getAllDescriptors().iterator(), CallableMemberDescriptor.class
271 );
272 while (callableMembers.hasNext()) {
273 collectMissingImplementations(callableMembers.next(), abstractNoImpl, manyImpl);
274 }
275 }
276
277 private static void collectMissingImplementations(
278 @NotNull CallableMemberDescriptor descriptor,
279 @NotNull Set<CallableMemberDescriptor> abstractNoImpl,
280 @NotNull Set<CallableMemberDescriptor> manyImpl
281 ) {
282 if (descriptor.getKind().isReal()) return;
283 if (descriptor.getVisibility() == Visibilities.INVISIBLE_FAKE) return;
284
285 Collection<? extends CallableMemberDescriptor> directOverridden = descriptor.getOverriddenDescriptors();
286 if (directOverridden.size() == 0) {
287 throw new IllegalStateException("A 'fake override' must override something");
288 }
289
290 // collects map from the directly overridden descriptor to the set of declarations:
291 // -- if directly overridden is not fake, the set consists of one element: this directly overridden
292 // -- if it's fake, overridden declarations (non-fake) of this descriptor are collected
293 Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenDeclarationsByDirectParent = collectOverriddenDeclarations(directOverridden);
294
295 List<CallableMemberDescriptor> allOverriddenDeclarations = ContainerUtil.flatten(overriddenDeclarationsByDirectParent.values());
296 Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations = OverridingUtil.filterOutOverridden(
297 Sets.newLinkedHashSet(allOverriddenDeclarations));
298
299 Set<CallableMemberDescriptor> relevantDirectlyOverridden =
300 getRelevantDirectlyOverridden(overriddenDeclarationsByDirectParent, allFilteredOverriddenDeclarations);
301
302 int implCount = countImplementations(relevantDirectlyOverridden);
303 if (implCount == 0) {
304 collectNotSynthesizedDescriptorsByModality(allFilteredOverriddenDeclarations, abstractNoImpl, Modality.ABSTRACT);
305 }
306 else if (implCount > 1) {
307 collectNotSynthesizedDescriptorsByModality(allFilteredOverriddenDeclarations, manyImpl, Modality.OPEN, Modality.FINAL);
308 }
309 }
310
311 private static int countImplementations(@NotNull Set<CallableMemberDescriptor> relevantDirectlyOverridden) {
312 int implCount = 0;
313 for (CallableMemberDescriptor overriddenDescriptor : relevantDirectlyOverridden) {
314 if (overriddenDescriptor.getModality() != Modality.ABSTRACT) {
315 implCount++;
316 }
317 }
318 return implCount;
319 }
320
321 private static void collectNotSynthesizedDescriptorsByModality(
322 @NotNull Set<CallableMemberDescriptor> allOverriddenDeclarations,
323 @NotNull Set<CallableMemberDescriptor> result,
324 Modality... modalities
325 ) {
326 Set<Modality> modalitySet = Sets.newHashSet(modalities);
327 for (CallableMemberDescriptor overridden : allOverriddenDeclarations) {
328 if (modalitySet.contains(overridden.getModality())) {
329 if (!CallResolverUtil.isOrOverridesSynthesized(overridden)) {
330 result.add(overridden);
331 }
332 }
333 }
334 }
335
336 @NotNull
337 private static Set<CallableMemberDescriptor> getRelevantDirectlyOverridden(
338 @NotNull Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenByParent,
339 @NotNull Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations
340 ) {
341 /* Let the following class hierarchy is declared:
342
343 trait A { fun foo() = 1 }
344 trait B : A
345 trait C : A
346 trait D : A { override fun foo() = 2 }
347 trait E : B, C, D {}
348
349 Traits B and C have fake descriptors for function foo.
350 The map 'overriddenByParent' is:
351 { 'foo in B' (fake) -> { 'foo in A' }, 'foo in C' (fake) -> { 'foo in A' }, 'foo in D' -> { 'foo in D'} }
352 This is a map from directly overridden descriptors (functions 'foo' in B, C, D in this example) to the set of declarations (non-fake),
353 that are overridden by this descriptor.
354
355 The goal is to leave only relevant directly overridden descriptors to count implementations of our fake function on them.
356 In the example above there is no error (trait E inherits only one implementation of 'foo' (from D), because this implementation is more precise).
357 So only 'foo in D' is relevant.
358
359 Directly overridden descriptor is not relevant if it doesn't add any more appropriate non-fake declarations of the concerned function.
360 More precisely directly overridden descriptor is not relevant if:
361 - it's declaration set is a subset of declaration set for other directly overridden descriptor
362 ('foo in B' is not relevant because it's declaration set is a subset of 'foo in C' function's declaration set)
363 - each member of it's declaration set is overridden by a member of other declaration set
364 ('foo in C' is not relevant, because 'foo in A' is overridden by 'foo in D', so 'foo in A' is not appropriate non-fake declaration for 'foo')
365
366 For the last condition allFilteredOverriddenDeclarations helps (for the example above it's { 'foo in A' } only): each declaration set
367 is compared with allFilteredOverriddenDeclarations, if they have no intersection, this means declaration set has only functions that
368 are overridden by some other function and corresponding directly overridden descriptor is not relevant.
369 */
370
371 Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> relevantOverriddenByParent = Maps.newLinkedHashMap(overriddenByParent);
372
373 for (Map.Entry<CallableMemberDescriptor, Set<CallableMemberDescriptor>> entry : overriddenByParent.entrySet()) {
374 CallableMemberDescriptor directlyOverridden = entry.getKey();
375 Set<CallableMemberDescriptor> declarationSet = entry.getValue();
376 if (!isRelevant(declarationSet, relevantOverriddenByParent.values(), allFilteredOverriddenDeclarations)) {
377 relevantOverriddenByParent.remove(directlyOverridden);
378 }
379 }
380 return relevantOverriddenByParent.keySet();
381 }
382
383 private static boolean isRelevant(
384 @NotNull Set<CallableMemberDescriptor> declarationSet,
385 @NotNull Collection<Set<CallableMemberDescriptor>> allDeclarationSets,
386 @NotNull Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations
387 ) {
388 for (Set<CallableMemberDescriptor> otherSet : allDeclarationSets) {
389 if (otherSet == declarationSet) continue;
390 if (otherSet.containsAll(declarationSet)) return false;
391 if (Collections.disjoint(allFilteredOverriddenDeclarations, declarationSet)) return false;
392 }
393 return true;
394 }
395
396 @NotNull
397 private static Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> collectOverriddenDeclarations(
398 @NotNull Collection<? extends CallableMemberDescriptor> directOverriddenDescriptors
399 ) {
400 Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenDeclarationsByDirectParent = Maps.newLinkedHashMap();
401 for (CallableMemberDescriptor descriptor : directOverriddenDescriptors) {
402 Collection<CallableMemberDescriptor> overriddenDeclarations = OverridingUtil.getOverriddenDeclarations(descriptor);
403 Set<CallableMemberDescriptor> filteredOverrides = OverridingUtil.filterOutOverridden(
404 Sets.newLinkedHashSet(overriddenDeclarations));
405 Set<CallableMemberDescriptor> overridden = Sets.newLinkedHashSet();
406 for (CallableMemberDescriptor memberDescriptor : filteredOverrides) {
407 overridden.add(memberDescriptor);
408 }
409 overriddenDeclarationsByDirectParent.put(descriptor, overridden);
410 }
411 return overriddenDeclarationsByDirectParent;
412 }
413
414 private interface CheckOverrideReportStrategy {
415 void overridingFinalMember(@NotNull CallableMemberDescriptor overridden);
416
417 void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden);
418
419 void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden);
420
421 void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden);
422
423 void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden);
424
425 void nothingToOverride();
426 }
427
428 private void checkOverrideForMember(@NotNull final CallableMemberDescriptor declared) {
429 if (declared.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED) {
430 // TODO: this should be replaced soon by a framework of synthesized member generation tools
431 if (declared.getName().asString().startsWith(DescriptorResolver.COMPONENT_FUNCTION_NAME_PREFIX)) {
432 checkOverrideForComponentFunction(declared);
433 }
434 return;
435 }
436
437 if (declared.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
438 return;
439 }
440
441 final JetNamedDeclaration member = (JetNamedDeclaration) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), declared);
442 if (member == null) {
443 throw new IllegalStateException("declared descriptor is not resolved to declaration: " + declared);
444 }
445
446 JetModifierList modifierList = member.getModifierList();
447 final ASTNode overrideNode = modifierList != null ? modifierList.getModifierNode(JetTokens.OVERRIDE_KEYWORD) : null;
448 Set<? extends CallableMemberDescriptor> overriddenDescriptors = declared.getOverriddenDescriptors();
449
450 if (overrideNode != null) {
451 checkOverridesForMemberMarkedOverride(declared, true, new CheckOverrideReportStrategy() {
452 private boolean finalOverriddenError = false;
453 private boolean typeMismatchError = false;
454 private boolean kindMismatchError = false;
455
456 @Override
457 public void overridingFinalMember( @NotNull CallableMemberDescriptor overridden) {
458 if (!finalOverriddenError) {
459 finalOverriddenError = true;
460 trace.report(OVERRIDING_FINAL_MEMBER.on(overrideNode.getPsi(), overridden, overridden.getContainingDeclaration()));
461 }
462 }
463
464 @Override
465 public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
466 if (!typeMismatchError) {
467 typeMismatchError = true;
468 trace.report(RETURN_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
469 }
470 }
471
472 @Override
473 public void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
474 if (!typeMismatchError) {
475 typeMismatchError = true;
476 trace.report(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
477 }
478 }
479
480 @Override
481 public void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden) {
482 if (!kindMismatchError) {
483 kindMismatchError = true;
484 trace.report(VAR_OVERRIDDEN_BY_VAL.on((JetProperty) member, (PropertyDescriptor) declared, (PropertyDescriptor) overridden));
485 }
486 }
487
488 @Override
489 public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden) {
490 trace.report(CANNOT_OVERRIDE_INVISIBLE_MEMBER.on(member, declared, invisibleOverridden, invisibleOverridden.getContainingDeclaration()));
491 }
492
493 @Override
494 public void nothingToOverride() {
495 trace.report(NOTHING_TO_OVERRIDE.on(member, declared));
496 }
497 });
498 }
499 else if (!overriddenDescriptors.isEmpty()) {
500 CallableMemberDescriptor overridden = overriddenDescriptors.iterator().next();
501 trace.report(VIRTUAL_MEMBER_HIDDEN.on(member, declared, overridden, overridden.getContainingDeclaration()));
502 }
503 }
504
505 private void checkOverridesForMemberMarkedOverride(
506 @NotNull CallableMemberDescriptor declared,
507 boolean checkIfOverridesNothing,
508 @NotNull CheckOverrideReportStrategy reportError
509 ) {
510 Set<? extends CallableMemberDescriptor> overriddenDescriptors = declared.getOverriddenDescriptors();
511
512 for (CallableMemberDescriptor overridden : overriddenDescriptors) {
513 if (overridden != null) {
514 if (!overridden.getModality().isOverridable()) {
515 reportError.overridingFinalMember(overridden);
516 }
517
518 if (declared instanceof PropertyDescriptor && !OverridingUtil.isPropertyTypeOkForOverride(
519 JetTypeChecker.INSTANCE, (PropertyDescriptor) overridden, (PropertyDescriptor) declared)) {
520 reportError.propertyTypeMismatchOnOverride(overridden);
521 }
522 else if (!OverridingUtil.isReturnTypeOkForOverride(JetTypeChecker.INSTANCE, overridden, declared)) {
523 reportError.returnTypeMismatchOnOverride(overridden);
524 }
525
526 if (checkPropertyKind(overridden, true) && checkPropertyKind(declared, false)) {
527 reportError.varOverriddenByVal(overridden);
528 }
529 }
530 }
531
532 if (checkIfOverridesNothing && overriddenDescriptors.isEmpty()) {
533 DeclarationDescriptor containingDeclaration = declared.getContainingDeclaration();
534 assert containingDeclaration instanceof ClassDescriptor : "Overrides may only be resolved in a class, but " + declared + " comes from " + containingDeclaration;
535 ClassDescriptor declaringClass = (ClassDescriptor) containingDeclaration;
536
537 CallableMemberDescriptor invisibleOverriddenDescriptor = findInvisibleOverriddenDescriptor(declared, declaringClass);
538 if (invisibleOverriddenDescriptor != null) {
539 reportError.cannotOverrideInvisibleMember(invisibleOverriddenDescriptor);
540 }
541 else {
542 reportError.nothingToOverride();
543 }
544 }
545 }
546
547 private void checkOverrideForComponentFunction(@NotNull final CallableMemberDescriptor componentFunction) {
548 final JetAnnotationEntry dataAnnotation = findDataAnnotationForDataClass(componentFunction.getContainingDeclaration());
549
550 checkOverridesForMemberMarkedOverride(componentFunction, false, new CheckOverrideReportStrategy() {
551 private boolean overrideConflict = false;
552
553 @Override
554 public void overridingFinalMember(@NotNull CallableMemberDescriptor overridden) {
555 if (!overrideConflict) {
556 overrideConflict = true;
557 trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataAnnotation, componentFunction, overridden.getContainingDeclaration()));
558 }
559 }
560
561 @Override
562 public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
563 if (!overrideConflict) {
564 overrideConflict = true;
565 trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataAnnotation, componentFunction, overridden.getContainingDeclaration()));
566 }
567 }
568
569 @Override
570 public void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
571 throw new IllegalStateException("Component functions are not properties");
572 }
573
574 @Override
575 public void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden) {
576 throw new IllegalStateException("Component functions are not properties");
577 }
578
579 @Override
580 public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden) {
581 throw new IllegalStateException("CANNOT_OVERRIDE_INVISIBLE_MEMBER should be reported on the corresponding property");
582 }
583
584 @Override
585 public void nothingToOverride() {
586 throw new IllegalStateException("Component functions are OK to override nothing");
587 }
588 });
589 }
590
591 @NotNull
592 private JetAnnotationEntry findDataAnnotationForDataClass(@NotNull DeclarationDescriptor dataClass) {
593 ClassDescriptor stdDataClassAnnotation = KotlinBuiltIns.getInstance().getDataClassAnnotation();
594 AnnotationDescriptor annotation = dataClass.getAnnotations().findAnnotation(DescriptorUtils.getFqNameSafe(stdDataClassAnnotation));
595 if (annotation == null) {
596 throw new IllegalStateException("No data annotation is found for data class " + dataClass);
597 }
598 return BindingContextUtils.getNotNull(trace.getBindingContext(),
599 BindingContext.ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT,
600 annotation);
601 }
602
603 private CallableMemberDescriptor findInvisibleOverriddenDescriptor(CallableMemberDescriptor declared, ClassDescriptor declaringClass) {
604 CallableMemberDescriptor invisibleOverride = null;
605 outer:
606 for (JetType supertype : declaringClass.getTypeConstructor().getSupertypes()) {
607 Set<CallableMemberDescriptor> all = Sets.newLinkedHashSet();
608 all.addAll(supertype.getMemberScope().getFunctions(declared.getName()));
609 all.addAll((Collection) supertype.getMemberScope().getProperties(declared.getName()));
610 for (CallableMemberDescriptor fromSuper : all) {
611 if (OverridingUtil.isOverridableBy(fromSuper, declared).getResult() == OVERRIDABLE) {
612 invisibleOverride = fromSuper;
613 if (Visibilities.isVisible(fromSuper, declared)) {
614 throw new IllegalStateException("Descriptor " + fromSuper + " is overridable by " + declared + " and visible but does not appear in its getOverriddenDescriptors()");
615 }
616 break outer;
617 }
618 }
619 }
620 return invisibleOverride;
621 }
622
623 private void checkParameterOverridesForAllClasses(@NotNull TopDownAnalysisContext c) {
624 for (ClassDescriptorWithResolutionScopes classDescriptor : c.getClasses().values()) {
625 for (DeclarationDescriptor member : classDescriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
626 if (member instanceof CallableMemberDescriptor) {
627 checkOverridesForParameters((CallableMemberDescriptor) member);
628 }
629 }
630 }
631 }
632
633 private void checkOverridesForParameters(@NotNull CallableMemberDescriptor declared) {
634 boolean noDeclaration = declared.getKind() != CallableMemberDescriptor.Kind.DECLARATION;
635 if (!noDeclaration) {
636 // No check if the function is not marked as 'override'
637 JetModifierListOwner declaration =
638 (JetModifierListOwner) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), declared);
639 if (!declaration.hasModifier(JetTokens.OVERRIDE_KEYWORD)) {
640 return;
641 }
642 }
643
644 // Let p1 be a parameter of the overriding function
645 // Let p2 be a parameter of the function being overridden
646 // Then
647 // a) p1 is not allowed to have a default value declared
648 // b) p1 must have the same name as p2
649 for (ValueParameterDescriptor parameterFromSubclass : declared.getValueParameters()) {
650 JetParameter parameter =
651 noDeclaration ? null :
652 (JetParameter) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), parameterFromSubclass);
653
654 JetClassOrObject classElement = noDeclaration ? (JetClassOrObject) BindingContextUtils
655 .descriptorToDeclaration(trace.getBindingContext(), declared.getContainingDeclaration()) : null;
656
657 if (parameterFromSubclass.declaresDefaultValue() && !noDeclaration) {
658 trace.report(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE.on(parameter));
659 }
660
661 boolean superWithDefault = false;
662 for (ValueParameterDescriptor parameterFromSuperclass : parameterFromSubclass.getOverriddenDescriptors()) {
663 if (parameterFromSuperclass.declaresDefaultValue()) {
664 if (!superWithDefault) {
665 superWithDefault = true;
666 }
667 else {
668 if (noDeclaration) {
669 trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE.on(classElement, parameterFromSubclass));
670 }
671 else {
672 trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES.on(parameter, parameterFromSubclass));
673 }
674 break;
675 }
676 }
677
678 DeclarationDescriptor superFunction = parameterFromSuperclass.getContainingDeclaration();
679 if (declared.hasStableParameterNames() &&
680 superFunction instanceof CallableDescriptor && ((CallableDescriptor) superFunction).hasStableParameterNames() &&
681 !parameterFromSuperclass.getName().equals(parameterFromSubclass.getName())) {
682 if (noDeclaration) {
683 trace.report(DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES.on(classElement, declared.getOverriddenDescriptors(), parameterFromSuperclass.getIndex() + 1));
684 }
685 else {
686 trace.report(PARAMETER_NAME_CHANGED_ON_OVERRIDE.on(parameter, (ClassDescriptor) superFunction.getContainingDeclaration(), parameterFromSuperclass));
687 }
688 }
689 }
690 }
691 }
692
693 private boolean checkPropertyKind(CallableMemberDescriptor descriptor, boolean isVar) {
694 if (descriptor instanceof PropertyDescriptor) {
695 PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
696 return propertyDescriptor.isVar() == isVar;
697 }
698 return false;
699 }
700
701 private void checkVisibility(@NotNull TopDownAnalysisContext c) {
702 for (Map.Entry<JetDeclaration, CallableMemberDescriptor> entry : c.getMembers().entrySet()) {
703 checkVisibilityForMember(entry.getKey(), entry.getValue());
704 }
705 }
706
707 private void checkVisibilityForMember(@NotNull JetDeclaration declaration, @NotNull CallableMemberDescriptor memberDescriptor) {
708 Visibility visibility = memberDescriptor.getVisibility();
709 for (CallableMemberDescriptor descriptor : memberDescriptor.getOverriddenDescriptors()) {
710 Integer compare = Visibilities.compare(visibility, descriptor.getVisibility());
711 if (compare == null) {
712 trace.report(CANNOT_CHANGE_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
713 return;
714 }
715 else if (compare < 0) {
716 trace.report(CANNOT_WEAKEN_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
717 return;
718 }
719 }
720 }
721 }