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