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.Function;
025 import com.intellij.util.containers.ContainerUtil;
026 import com.intellij.util.containers.LinkedMultiMap;
027 import com.intellij.util.containers.MultiMap;
028 import kotlin.Function1;
029 import kotlin.Unit;
030 import org.jetbrains.annotations.NotNull;
031 import org.jetbrains.annotations.Nullable;
032 import org.jetbrains.annotations.ReadOnly;
033 import org.jetbrains.jet.lang.descriptors.*;
034 import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
035 import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
036 import org.jetbrains.jet.lang.psi.*;
037 import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
038 import org.jetbrains.jet.lang.resolve.name.Name;
039 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
040 import org.jetbrains.jet.lang.types.*;
041 import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
042 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
043 import org.jetbrains.jet.lexer.JetTokens;
044
045 import javax.inject.Inject;
046 import java.util.*;
047
048 import static org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.*;
049 import static org.jetbrains.jet.lang.diagnostics.Errors.*;
050 import static org.jetbrains.jet.lang.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE;
051
052 public class OverrideResolver {
053
054 private BindingTrace trace;
055
056 @Inject
057 public void setTrace(BindingTrace trace) {
058 this.trace = trace;
059 }
060
061
062
063 public void process(@NotNull TopDownAnalysisContext c) {
064 //all created fake descriptors are stored to resolve visibility on them later
065 generateOverridesAndDelegation(c);
066
067 check(c);
068 }
069
070 public void check(@NotNull TopDownAnalysisContext c) {
071 checkVisibility(c);
072 checkOverrides(c);
073 checkParameterOverridesForAllClasses(c);
074 }
075
076 /**
077 * Generate fake overrides and add overridden descriptors to existing descriptors.
078 */
079 private void generateOverridesAndDelegation(@NotNull TopDownAnalysisContext c) {
080 Set<ClassDescriptorWithResolutionScopes> ourClasses = new HashSet<ClassDescriptorWithResolutionScopes>(c.getAllClasses());
081 Set<ClassifierDescriptor> processed = new HashSet<ClassifierDescriptor>();
082
083 for (MutableClassDescriptor klass : ContainerUtil.reverse(c.getClassesTopologicalOrder())) {
084 if (ourClasses.contains(klass)) {
085 generateOverridesAndDelegationInAClass(klass, processed, ourClasses);
086
087 MutableClassDescriptor classObject = klass.getClassObjectDescriptor();
088 if (classObject != null) {
089 generateOverridesAndDelegationInAClass(classObject, processed, ourClasses);
090 }
091 }
092 }
093 }
094
095 private void generateOverridesAndDelegationInAClass(
096 @NotNull MutableClassDescriptor classDescriptor,
097 @NotNull Set<ClassifierDescriptor> processed,
098 @NotNull Set<ClassDescriptorWithResolutionScopes> classesBeingAnalyzed
099 // to filter out classes such as stdlib and others that come from dependencies
100 ) {
101 if (!processed.add(classDescriptor)) {
102 return;
103 }
104
105 for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
106 ClassDescriptor superclass = (ClassDescriptor) supertype.getConstructor().getDeclarationDescriptor();
107 if (superclass instanceof MutableClassDescriptor && classesBeingAnalyzed.contains(superclass)) {
108 generateOverridesAndDelegationInAClass((MutableClassDescriptor) superclass, processed, classesBeingAnalyzed);
109 }
110 }
111
112 JetClassOrObject classOrObject = (JetClassOrObject) BindingContextUtils
113 .classDescriptorToDeclaration(trace.getBindingContext(), classDescriptor);
114 if (classOrObject != null) {
115 DelegationResolver.generateDelegatesInAClass(classDescriptor, trace, classOrObject);
116 }
117
118 generateOverridesInAClass(classDescriptor);
119 }
120
121 private void generateOverridesInAClass(@NotNull final MutableClassDescriptor classDescriptor) {
122 List<CallableMemberDescriptor> membersFromSupertypes = getCallableMembersFromSupertypes(classDescriptor);
123
124 MultiMap<Name, CallableMemberDescriptor> membersFromSupertypesByName = groupDescriptorsByName(membersFromSupertypes);
125
126 MultiMap<Name, CallableMemberDescriptor> membersFromCurrentByName = groupDescriptorsByName(classDescriptor.getDeclaredCallableMembers());
127
128 Set<Name> memberNames = new LinkedHashSet<Name>();
129 memberNames.addAll(membersFromSupertypesByName.keySet());
130 memberNames.addAll(membersFromCurrentByName.keySet());
131
132 for (Name memberName : memberNames) {
133 Collection<CallableMemberDescriptor> fromSupertypes = membersFromSupertypesByName.get(memberName);
134 Collection<CallableMemberDescriptor> fromCurrent = membersFromCurrentByName.get(memberName);
135
136 OverridingUtil.generateOverridesInFunctionGroup(
137 memberName,
138 fromSupertypes,
139 fromCurrent,
140 classDescriptor,
141 new OverridingUtil.DescriptorSink() {
142 @Override
143 public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
144 if (fakeOverride instanceof PropertyDescriptor) {
145 classDescriptor.getBuilder().addPropertyDescriptor((PropertyDescriptor) fakeOverride);
146 }
147 else if (fakeOverride instanceof SimpleFunctionDescriptor) {
148 classDescriptor.getBuilder().addFunctionDescriptor((SimpleFunctionDescriptor) fakeOverride);
149 }
150 else {
151 throw new IllegalStateException(fakeOverride.getClass().getName());
152 }
153 }
154
155 @Override
156 public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) {
157 JetDeclaration declaration =
158 (JetDeclaration) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), fromCurrent);
159 //noinspection ConstantConditions
160 trace.report(CONFLICTING_OVERLOADS.on(declaration, fromCurrent, fromCurrent.getContainingDeclaration().getName().asString()));
161 }
162 });
163 }
164 resolveUnknownVisibilities(classDescriptor.getAllCallableMembers(), trace);
165 }
166
167 public static void resolveUnknownVisibilities(
168 @NotNull Collection<? extends CallableMemberDescriptor> descriptors,
169 @NotNull BindingTrace trace
170 ) {
171 for (CallableMemberDescriptor descriptor : descriptors) {
172 OverridingUtil.resolveUnknownVisibilityForMember(descriptor, createCannotInferVisibilityReporter(trace));
173 }
174 }
175
176 @NotNull
177 public static Function1<CallableMemberDescriptor, Unit> createCannotInferVisibilityReporter(@NotNull final BindingTrace trace) {
178 return new Function1<CallableMemberDescriptor, Unit>() {
179 @Override
180 public Unit invoke(@NotNull CallableMemberDescriptor descriptor) {
181 DeclarationDescriptor reportOn = descriptor.getKind() == FAKE_OVERRIDE || descriptor.getKind() == DELEGATION
182 ? DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class)
183 : descriptor;
184 //noinspection ConstantConditions
185 PsiElement element = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), reportOn);
186 if (element instanceof JetDeclaration) {
187 trace.report(CANNOT_INFER_VISIBILITY.on((JetDeclaration) element));
188 }
189 return Unit.VALUE;
190 }
191 };
192 }
193
194 private static enum Filtering {
195 RETAIN_OVERRIDING,
196 RETAIN_OVERRIDDEN
197 }
198
199 @NotNull
200 public static <D extends CallableDescriptor> Set<D> filterOutOverridden(@NotNull Set<D> candidateSet) {
201 //noinspection unchecked
202 return filterOverrides(candidateSet, Function.ID, Filtering.RETAIN_OVERRIDING);
203 }
204
205 @NotNull
206 public static <D> Set<D> filterOutOverriding(@NotNull Set<D> candidateSet) {
207 //noinspection unchecked
208 return filterOverrides(candidateSet, Function.ID, Filtering.RETAIN_OVERRIDDEN);
209 }
210
211 @NotNull
212 public static <D> Set<D> filterOutOverridden(
213 @NotNull Set<D> candidateSet,
214 @NotNull Function<? super D, ? extends CallableDescriptor> transform
215 ) {
216 return filterOverrides(candidateSet, transform, Filtering.RETAIN_OVERRIDING);
217 }
218
219 @NotNull
220 private static <D> Set<D> filterOverrides(
221 @NotNull Set<D> candidateSet,
222 @NotNull Function<? super D, ? extends CallableDescriptor> transform,
223 @NotNull Filtering filtering
224 ) {
225 Set<D> candidates = Sets.newLinkedHashSet();
226 outerLoop:
227 for (D meD : candidateSet) {
228 CallableDescriptor me = transform.fun(meD);
229 for (D otherD : candidateSet) {
230 CallableDescriptor other = transform.fun(otherD);
231 if (me == other) continue;
232 if (filtering == Filtering.RETAIN_OVERRIDING) {
233 if (overrides(other, me)) {
234 continue outerLoop;
235 }
236 }
237 else if (filtering == Filtering.RETAIN_OVERRIDDEN) {
238 if (overrides(me, other)) {
239 continue outerLoop;
240 }
241 }
242 else {
243 throw new AssertionError("Unexpected Filtering object: " + filtering);
244 }
245 }
246 for (D otherD : candidates) {
247 CallableDescriptor other = transform.fun(otherD);
248 if (me.getOriginal() == other.getOriginal()
249 && OverridingUtil.isOverridableBy(other, me).getResult() == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE
250 && OverridingUtil.isOverridableBy(me, other).getResult() == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE) {
251 continue outerLoop;
252 }
253 }
254 candidates.add(meD);
255 }
256 return candidates;
257 }
258
259 public static <D extends CallableDescriptor> boolean overrides(@NotNull D f, @NotNull D g) {
260 CallableDescriptor originalG = g.getOriginal();
261 for (CallableDescriptor overriddenFunction : getAllOverriddenDescriptors(f)) {
262 if (originalG.equals(overriddenFunction.getOriginal())) return true;
263 }
264 return false;
265 }
266
267 @NotNull
268 public static Set<CallableDescriptor> getAllOverriddenDescriptors(@NotNull CallableDescriptor f) {
269 Set<CallableDescriptor> result = new LinkedHashSet<CallableDescriptor>();
270 collectAllOverriddenDescriptors(f.getOriginal(), result);
271 return result;
272 }
273
274 private static void collectAllOverriddenDescriptors(@NotNull CallableDescriptor current, @NotNull Set<CallableDescriptor> result) {
275 if (result.contains(current)) return;
276 for (CallableDescriptor descriptor : current.getOriginal().getOverriddenDescriptors()) {
277 collectAllOverriddenDescriptors(descriptor, result);
278 result.add(descriptor);
279 }
280 }
281
282 private static <T extends DeclarationDescriptor> MultiMap<Name, T> groupDescriptorsByName(Collection<T> properties) {
283 MultiMap<Name, T> r = new LinkedMultiMap<Name, T>();
284 for (T property : properties) {
285 r.putValue(property.getName(), property);
286 }
287 return r;
288 }
289
290
291 private static List<CallableMemberDescriptor> getCallableMembersFromSupertypes(ClassDescriptor classDescriptor) {
292 Set<CallableMemberDescriptor> r = Sets.newLinkedHashSet();
293 for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
294 r.addAll(getCallableMembersFromType(supertype.getMemberScope()));
295 }
296 return new ArrayList<CallableMemberDescriptor>(r);
297 }
298
299 private static List<CallableMemberDescriptor> getCallableMembersFromType(JetScope scope) {
300 List<CallableMemberDescriptor> r = Lists.newArrayList();
301 for (DeclarationDescriptor decl : scope.getAllDescriptors()) {
302 if (decl instanceof PropertyDescriptor || decl instanceof SimpleFunctionDescriptor) {
303 r.add((CallableMemberDescriptor) decl);
304 }
305 }
306 return r;
307 }
308
309 private void checkOverrides(@NotNull TopDownAnalysisContext c) {
310 for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
311 checkOverridesInAClass(c, entry.getValue(), entry.getKey());
312 }
313 }
314
315 private void checkOverridesInAClass(@NotNull TopDownAnalysisContext c, @NotNull ClassDescriptorWithResolutionScopes classDescriptor, @NotNull JetClassOrObject klass) {
316 if (c.getTopDownAnalysisParameters().isAnalyzingBootstrapLibrary()) return;
317
318 // Check overrides for internal consistency
319 for (CallableMemberDescriptor member : classDescriptor.getDeclaredCallableMembers()) {
320 checkOverrideForMember(member);
321 }
322
323 // Check if everything that must be overridden, actually is
324 // More than one implementation or no implementations at all
325 Set<CallableMemberDescriptor> abstractNoImpl = Sets.newLinkedHashSet();
326 Set<CallableMemberDescriptor> manyImpl = Sets.newLinkedHashSet();
327 collectMissingImplementations(classDescriptor, abstractNoImpl, manyImpl);
328
329 if (!manyImpl.isEmpty()) {
330 trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(klass, klass, manyImpl.iterator().next()));
331 }
332
333 if (classDescriptor.getModality() != Modality.ABSTRACT && !abstractNoImpl.isEmpty()) {
334 trace.report(ABSTRACT_MEMBER_NOT_IMPLEMENTED.on(klass, klass, abstractNoImpl.iterator().next()));
335 }
336 }
337
338 @NotNull
339 public static Set<CallableMemberDescriptor> getMissingImplementations(@NotNull ClassDescriptor classDescriptor) {
340 Set<CallableMemberDescriptor> result = new LinkedHashSet<CallableMemberDescriptor>();
341 collectMissingImplementations(classDescriptor, result, result);
342 return result;
343 }
344
345 private static void collectMissingImplementations(
346 @NotNull ClassDescriptor classDescriptor,
347 @NotNull Set<CallableMemberDescriptor> abstractNoImpl,
348 @NotNull Set<CallableMemberDescriptor> manyImpl
349 ) {
350 for (DeclarationDescriptor member : classDescriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
351 if (member instanceof CallableMemberDescriptor) {
352 collectMissingImplementations((CallableMemberDescriptor) member, abstractNoImpl, manyImpl);
353 }
354 }
355 }
356
357 private static void collectMissingImplementations(
358 @NotNull CallableMemberDescriptor descriptor,
359 @NotNull Set<CallableMemberDescriptor> abstractNoImpl,
360 @NotNull Set<CallableMemberDescriptor> manyImpl
361 ) {
362 if (descriptor.getKind().isReal()) return;
363 if (descriptor.getVisibility() == Visibilities.INVISIBLE_FAKE) return;
364
365 Collection<? extends CallableMemberDescriptor> directOverridden = descriptor.getOverriddenDescriptors();
366 if (directOverridden.size() == 0) {
367 throw new IllegalStateException("A 'fake override' must override something");
368 }
369
370 // collects map from the directly overridden descriptor to the set of declarations:
371 // -- if directly overridden is not fake, the set consists of one element: this directly overridden
372 // -- if it's fake, overridden declarations (non-fake) of this descriptor are collected
373 Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenDeclarationsByDirectParent = collectOverriddenDeclarations(directOverridden);
374
375 List<CallableMemberDescriptor> allOverriddenDeclarations = ContainerUtil.flatten(overriddenDeclarationsByDirectParent.values());
376 Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations = filterOutOverridden(
377 Sets.newLinkedHashSet(allOverriddenDeclarations));
378
379 Set<CallableMemberDescriptor> relevantDirectlyOverridden =
380 getRelevantDirectlyOverridden(overriddenDeclarationsByDirectParent, allFilteredOverriddenDeclarations);
381
382 int implCount = countImplementations(relevantDirectlyOverridden);
383 if (implCount == 0) {
384 collectNotSynthesizedDescriptorsByModality(allFilteredOverriddenDeclarations, abstractNoImpl, Modality.ABSTRACT);
385 }
386 else if (implCount > 1) {
387 collectNotSynthesizedDescriptorsByModality(allFilteredOverriddenDeclarations, manyImpl, Modality.OPEN, Modality.FINAL);
388 }
389 }
390
391 private static int countImplementations(@NotNull Set<CallableMemberDescriptor> relevantDirectlyOverridden) {
392 int implCount = 0;
393 for (CallableMemberDescriptor overriddenDescriptor : relevantDirectlyOverridden) {
394 if (overriddenDescriptor.getModality() != Modality.ABSTRACT) {
395 implCount++;
396 }
397 }
398 return implCount;
399 }
400
401 private static void collectNotSynthesizedDescriptorsByModality(
402 @NotNull Set<CallableMemberDescriptor> allOverriddenDeclarations,
403 @NotNull Set<CallableMemberDescriptor> result,
404 Modality... modalities
405 ) {
406 Set<Modality> modalitySet = Sets.newHashSet(modalities);
407 for (CallableMemberDescriptor overridden : allOverriddenDeclarations) {
408 if (modalitySet.contains(overridden.getModality())) {
409 if (!CallResolverUtil.isOrOverridesSynthesized(overridden)) {
410 result.add(overridden);
411 }
412 }
413 }
414 }
415
416 @NotNull
417 private static Set<CallableMemberDescriptor> getRelevantDirectlyOverridden(
418 @NotNull Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenByParent,
419 @NotNull Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations
420 ) {
421 /* Let the following class hierarchy is declared:
422
423 trait A { fun foo() = 1 }
424 trait B : A
425 trait C : A
426 trait D : A { override fun foo() = 2 }
427 trait E : B, C, D {}
428
429 Traits B and C have fake descriptors for function foo.
430 The map 'overriddenByParent' is:
431 { 'foo in B' (fake) -> { 'foo in A' }, 'foo in C' (fake) -> { 'foo in A' }, 'foo in D' -> { 'foo in D'} }
432 This is a map from directly overridden descriptors (functions 'foo' in B, C, D in this example) to the set of declarations (non-fake),
433 that are overridden by this descriptor.
434
435 The goal is to leave only relevant directly overridden descriptors to count implementations of our fake function on them.
436 In the example above there is no error (trait E inherits only one implementation of 'foo' (from D), because this implementation is more precise).
437 So only 'foo in D' is relevant.
438
439 Directly overridden descriptor is not relevant if it doesn't add any more appropriate non-fake declarations of the concerned function.
440 More precisely directly overridden descriptor is not relevant if:
441 - it's declaration set is a subset of declaration set for other directly overridden descriptor
442 ('foo in B' is not relevant because it's declaration set is a subset of 'foo in C' function's declaration set)
443 - each member of it's declaration set is overridden by a member of other declaration set
444 ('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')
445
446 For the last condition allFilteredOverriddenDeclarations helps (for the example above it's { 'foo in A' } only): each declaration set
447 is compared with allFilteredOverriddenDeclarations, if they have no intersection, this means declaration set has only functions that
448 are overridden by some other function and corresponding directly overridden descriptor is not relevant.
449 */
450
451 Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> relevantOverriddenByParent = Maps.newLinkedHashMap(overriddenByParent);
452
453 for (Map.Entry<CallableMemberDescriptor, Set<CallableMemberDescriptor>> entry : overriddenByParent.entrySet()) {
454 CallableMemberDescriptor directlyOverridden = entry.getKey();
455 Set<CallableMemberDescriptor> declarationSet = entry.getValue();
456 if (!isRelevant(declarationSet, relevantOverriddenByParent.values(), allFilteredOverriddenDeclarations)) {
457 relevantOverriddenByParent.remove(directlyOverridden);
458 }
459 }
460 return relevantOverriddenByParent.keySet();
461 }
462
463 private static boolean isRelevant(
464 @NotNull Set<CallableMemberDescriptor> declarationSet,
465 @NotNull Collection<Set<CallableMemberDescriptor>> allDeclarationSets,
466 @NotNull Set<CallableMemberDescriptor> allFilteredOverriddenDeclarations
467 ) {
468 for (Set<CallableMemberDescriptor> otherSet : allDeclarationSets) {
469 if (otherSet == declarationSet) continue;
470 if (otherSet.containsAll(declarationSet)) return false;
471 if (Collections.disjoint(allFilteredOverriddenDeclarations, declarationSet)) return false;
472 }
473 return true;
474 }
475
476 @NotNull
477 private static Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> collectOverriddenDeclarations(
478 @NotNull Collection<? extends CallableMemberDescriptor> directOverriddenDescriptors
479 ) {
480 Map<CallableMemberDescriptor, Set<CallableMemberDescriptor>> overriddenDeclarationsByDirectParent = Maps.newLinkedHashMap();
481 for (CallableMemberDescriptor descriptor : directOverriddenDescriptors) {
482 Set<CallableMemberDescriptor> overriddenDeclarations = getOverriddenDeclarations(descriptor);
483 Set<CallableMemberDescriptor> filteredOverrides = filterOutOverridden(overriddenDeclarations);
484 overriddenDeclarationsByDirectParent.put(descriptor, new LinkedHashSet<CallableMemberDescriptor>(filteredOverrides));
485 }
486 return overriddenDeclarationsByDirectParent;
487 }
488
489 /**
490 * @return overridden real descriptors (not fake overrides). Note that all usages of this method should be followed by calling
491 * {@link #filterOutOverridden(java.util.Set)} or {@link #filterOutOverriding(java.util.Set)}, because some of the declarations
492 * can override the other
493 * TODO: merge this method with filterOutOverridden
494 */
495 @NotNull
496 public static Set<CallableMemberDescriptor> getOverriddenDeclarations(@NotNull CallableMemberDescriptor descriptor) {
497 Set<CallableMemberDescriptor> result = new LinkedHashSet<CallableMemberDescriptor>();
498 getOverriddenDeclarations(descriptor, result);
499 return result;
500 }
501
502 private static void getOverriddenDeclarations(
503 @NotNull CallableMemberDescriptor descriptor,
504 @NotNull Set<CallableMemberDescriptor> result
505 ) {
506 if (descriptor.getKind().isReal()) {
507 result.add(descriptor);
508 }
509 else {
510 if (descriptor.getOverriddenDescriptors().isEmpty()) {
511 throw new IllegalStateException("No overridden descriptors found for (fake override) " + descriptor);
512 }
513 for (CallableMemberDescriptor overridden : descriptor.getOverriddenDescriptors()) {
514 getOverriddenDeclarations(overridden, result);
515 }
516 }
517 }
518
519 private interface CheckOverrideReportStrategy {
520 void overridingFinalMember(@NotNull CallableMemberDescriptor overridden);
521
522 void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden);
523
524 void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden);
525
526 void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden);
527
528 void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden);
529
530 void nothingToOverride();
531 }
532
533 private void checkOverrideForMember(@NotNull final CallableMemberDescriptor declared) {
534 if (declared.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED) {
535 // TODO: this should be replaced soon by a framework of synthesized member generation tools
536 if (declared.getName().asString().startsWith(DescriptorResolver.COMPONENT_FUNCTION_NAME_PREFIX)) {
537 checkOverrideForComponentFunction(declared);
538 }
539 return;
540 }
541
542 if (declared.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
543 return;
544 }
545
546 final JetNamedDeclaration member = (JetNamedDeclaration) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), declared);
547 if (member == null) {
548 throw new IllegalStateException("declared descriptor is not resolved to declaration: " + declared);
549 }
550
551 JetModifierList modifierList = member.getModifierList();
552 final ASTNode overrideNode = modifierList != null ? modifierList.getModifierNode(JetTokens.OVERRIDE_KEYWORD) : null;
553 Set<? extends CallableMemberDescriptor> overriddenDescriptors = declared.getOverriddenDescriptors();
554
555 if (overrideNode != null) {
556 checkOverridesForMemberMarkedOverride(declared, true, new CheckOverrideReportStrategy() {
557 private boolean finalOverriddenError = false;
558 private boolean typeMismatchError = false;
559 private boolean kindMismatchError = false;
560
561 @Override
562 public void overridingFinalMember( @NotNull CallableMemberDescriptor overridden) {
563 if (!finalOverriddenError) {
564 finalOverriddenError = true;
565 trace.report(OVERRIDING_FINAL_MEMBER.on(overrideNode.getPsi(), overridden, overridden.getContainingDeclaration()));
566 }
567 }
568
569 @Override
570 public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
571 if (!typeMismatchError) {
572 typeMismatchError = true;
573 trace.report(RETURN_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
574 }
575 }
576
577 @Override
578 public void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
579 if (!typeMismatchError) {
580 typeMismatchError = true;
581 trace.report(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden));
582 }
583 }
584
585 @Override
586 public void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden) {
587 if (!kindMismatchError) {
588 kindMismatchError = true;
589 trace.report(VAR_OVERRIDDEN_BY_VAL.on((JetProperty) member, (PropertyDescriptor) declared, (PropertyDescriptor) overridden));
590 }
591 }
592
593 @Override
594 public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden) {
595 trace.report(CANNOT_OVERRIDE_INVISIBLE_MEMBER.on(member, declared, invisibleOverridden));
596 }
597
598 @Override
599 public void nothingToOverride() {
600 trace.report(NOTHING_TO_OVERRIDE.on(member, declared));
601 }
602 });
603 }
604 else if (!overriddenDescriptors.isEmpty()) {
605 CallableMemberDescriptor overridden = overriddenDescriptors.iterator().next();
606 trace.report(VIRTUAL_MEMBER_HIDDEN.on(member, declared, overridden, overridden.getContainingDeclaration()));
607 }
608 }
609
610 private static void checkOverridesForMemberMarkedOverride(
611 @NotNull CallableMemberDescriptor declared,
612 boolean checkIfOverridesNothing,
613 @NotNull CheckOverrideReportStrategy reportError
614 ) {
615 Set<? extends CallableMemberDescriptor> overriddenDescriptors = declared.getOverriddenDescriptors();
616
617 for (CallableMemberDescriptor overridden : overriddenDescriptors) {
618 if (overridden == null) continue;
619
620 if (!overridden.getModality().isOverridable()) {
621 reportError.overridingFinalMember(overridden);
622 }
623
624 if (declared instanceof PropertyDescriptor &&
625 !isPropertyTypeOkForOverride((PropertyDescriptor) overridden, (PropertyDescriptor) declared)) {
626 reportError.propertyTypeMismatchOnOverride(overridden);
627 }
628 else if (!isReturnTypeOkForOverride(overridden, declared)) {
629 reportError.returnTypeMismatchOnOverride(overridden);
630 }
631
632 if (checkPropertyKind(overridden, true) && checkPropertyKind(declared, false)) {
633 reportError.varOverriddenByVal(overridden);
634 }
635 }
636
637 if (checkIfOverridesNothing && overriddenDescriptors.isEmpty()) {
638 DeclarationDescriptor containingDeclaration = declared.getContainingDeclaration();
639 assert containingDeclaration instanceof ClassDescriptor : "Overrides may only be resolved in a class, but " + declared + " comes from " + containingDeclaration;
640 ClassDescriptor declaringClass = (ClassDescriptor) containingDeclaration;
641
642 CallableMemberDescriptor invisibleOverriddenDescriptor = findInvisibleOverriddenDescriptor(declared, declaringClass);
643 if (invisibleOverriddenDescriptor != null) {
644 reportError.cannotOverrideInvisibleMember(invisibleOverriddenDescriptor);
645 }
646 else {
647 reportError.nothingToOverride();
648 }
649 }
650 }
651
652 public static boolean isReturnTypeOkForOverride(
653 @NotNull CallableDescriptor superDescriptor,
654 @NotNull CallableDescriptor subDescriptor
655 ) {
656 TypeSubstitutor typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor);
657 if (typeSubstitutor == null) return false;
658
659 JetType superReturnType = superDescriptor.getReturnType();
660 assert superReturnType != null;
661
662 JetType subReturnType = subDescriptor.getReturnType();
663 assert subReturnType != null;
664
665 JetType substitutedSuperReturnType = typeSubstitutor.substitute(superReturnType, Variance.OUT_VARIANCE);
666 assert substitutedSuperReturnType != null;
667
668 return JetTypeChecker.INSTANCE.isSubtypeOf(subReturnType, substitutedSuperReturnType);
669 }
670
671 @Nullable
672 private static TypeSubstitutor prepareTypeSubstitutor(
673 @NotNull CallableDescriptor superDescriptor,
674 @NotNull CallableDescriptor subDescriptor
675 ) {
676 List<TypeParameterDescriptor> superTypeParameters = superDescriptor.getTypeParameters();
677 List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters();
678 if (subTypeParameters.size() != superTypeParameters.size()) return null;
679
680 Map<TypeConstructor, TypeProjection> substitutionContext = Maps.newHashMapWithExpectedSize(superTypeParameters.size());
681 for (int i = 0; i < superTypeParameters.size(); i++) {
682 TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i);
683 TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i);
684 substitutionContext.put(
685 superTypeParameter.getTypeConstructor(),
686 new TypeProjectionImpl(subTypeParameter.getDefaultType())
687 );
688 }
689 return TypeSubstitutor.create(substitutionContext);
690 }
691
692 public static boolean isPropertyTypeOkForOverride(
693 @NotNull PropertyDescriptor superDescriptor,
694 @NotNull PropertyDescriptor subDescriptor
695 ) {
696 TypeSubstitutor typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor);
697 if (typeSubstitutor == null) return false;
698
699 if (!superDescriptor.isVar()) return true;
700
701 JetType substitutedSuperReturnType = typeSubstitutor.substitute(superDescriptor.getType(), Variance.OUT_VARIANCE);
702 assert substitutedSuperReturnType != null;
703 return JetTypeChecker.INSTANCE.equalTypes(subDescriptor.getType(), substitutedSuperReturnType);
704 }
705
706 private void checkOverrideForComponentFunction(@NotNull final CallableMemberDescriptor componentFunction) {
707 final JetAnnotationEntry dataAnnotation = findDataAnnotationForDataClass(componentFunction.getContainingDeclaration());
708
709 checkOverridesForMemberMarkedOverride(componentFunction, false, new CheckOverrideReportStrategy() {
710 private boolean overrideConflict = false;
711
712 @Override
713 public void overridingFinalMember(@NotNull CallableMemberDescriptor overridden) {
714 if (!overrideConflict) {
715 overrideConflict = true;
716 trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataAnnotation, componentFunction, overridden.getContainingDeclaration()));
717 }
718 }
719
720 @Override
721 public void returnTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
722 if (!overrideConflict) {
723 overrideConflict = true;
724 trace.report(DATA_CLASS_OVERRIDE_CONFLICT.on(dataAnnotation, componentFunction, overridden.getContainingDeclaration()));
725 }
726 }
727
728 @Override
729 public void propertyTypeMismatchOnOverride(@NotNull CallableMemberDescriptor overridden) {
730 throw new IllegalStateException("Component functions are not properties");
731 }
732
733 @Override
734 public void varOverriddenByVal(@NotNull CallableMemberDescriptor overridden) {
735 throw new IllegalStateException("Component functions are not properties");
736 }
737
738 @Override
739 public void cannotOverrideInvisibleMember(@NotNull CallableMemberDescriptor invisibleOverridden) {
740 throw new IllegalStateException("CANNOT_OVERRIDE_INVISIBLE_MEMBER should be reported on the corresponding property");
741 }
742
743 @Override
744 public void nothingToOverride() {
745 throw new IllegalStateException("Component functions are OK to override nothing");
746 }
747 });
748 }
749
750 @NotNull
751 private JetAnnotationEntry findDataAnnotationForDataClass(@NotNull DeclarationDescriptor dataClass) {
752 ClassDescriptor stdDataClassAnnotation = KotlinBuiltIns.getInstance().getDataClassAnnotation();
753 AnnotationDescriptor annotation = dataClass.getAnnotations().findAnnotation(DescriptorUtils.getFqNameSafe(stdDataClassAnnotation));
754 if (annotation == null) {
755 throw new IllegalStateException("No data annotation is found for data class " + dataClass);
756 }
757 return BindingContextUtils.getNotNull(trace.getBindingContext(),
758 BindingContext.ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT,
759 annotation);
760 }
761
762 @Nullable
763 private static CallableMemberDescriptor findInvisibleOverriddenDescriptor(
764 @NotNull CallableMemberDescriptor declared,
765 @NotNull ClassDescriptor declaringClass
766 ) {
767 for (JetType supertype : declaringClass.getTypeConstructor().getSupertypes()) {
768 Set<CallableMemberDescriptor> all = Sets.newLinkedHashSet();
769 all.addAll(supertype.getMemberScope().getFunctions(declared.getName()));
770 //noinspection unchecked
771 all.addAll((Collection) supertype.getMemberScope().getProperties(declared.getName()));
772 for (CallableMemberDescriptor fromSuper : all) {
773 if (OverridingUtil.isOverridableBy(fromSuper, declared).getResult() == OVERRIDABLE) {
774 if (Visibilities.isVisible(fromSuper, declared)) {
775 throw new IllegalStateException("Descriptor " + fromSuper + " is overridable by " + declared +
776 " and visible but does not appear in its getOverriddenDescriptors()");
777 }
778 return fromSuper;
779 }
780 }
781 }
782 return null;
783 }
784
785 private void checkParameterOverridesForAllClasses(@NotNull TopDownAnalysisContext c) {
786 for (ClassDescriptorWithResolutionScopes classDescriptor : c.getDeclaredClasses().values()) {
787 for (DeclarationDescriptor member : classDescriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
788 if (member instanceof CallableMemberDescriptor) {
789 checkOverridesForParameters((CallableMemberDescriptor) member);
790 }
791 }
792 }
793 }
794
795 private void checkOverridesForParameters(@NotNull CallableMemberDescriptor declared) {
796 boolean isDeclaration = declared.getKind() == CallableMemberDescriptor.Kind.DECLARATION;
797 if (isDeclaration) {
798 // No check if the function is not marked as 'override'
799 JetModifierListOwner declaration =
800 (JetModifierListOwner) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), declared);
801 if (declaration != null && !declaration.hasModifier(JetTokens.OVERRIDE_KEYWORD)) {
802 return;
803 }
804 }
805
806 // Let p1 be a parameter of the overriding function
807 // Let p2 be a parameter of the function being overridden
808 // Then
809 // a) p1 is not allowed to have a default value declared
810 // b) p1 must have the same name as p2
811 for (ValueParameterDescriptor parameterFromSubclass : declared.getValueParameters()) {
812 int defaultsInSuper = 0;
813 for (ValueParameterDescriptor parameterFromSuperclass : parameterFromSubclass.getOverriddenDescriptors()) {
814 if (parameterFromSuperclass.declaresDefaultValue()) {
815 defaultsInSuper++;
816 }
817 }
818 boolean multipleDefaultsInSuper = defaultsInSuper > 1;
819
820 if (isDeclaration) {
821 checkNameAndDefaultForDeclaredParameter(parameterFromSubclass, multipleDefaultsInSuper);
822 }
823 else {
824 checkNameAndDefaultForFakeOverrideParameter(declared, parameterFromSubclass, multipleDefaultsInSuper);
825 }
826 }
827 }
828
829 private void checkNameAndDefaultForDeclaredParameter(@NotNull ValueParameterDescriptor descriptor, boolean multipleDefaultsInSuper) {
830 JetParameter parameter = (JetParameter) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), descriptor);
831 assert parameter != null : "Declaration not found for parameter: " + descriptor;
832
833 if (descriptor.declaresDefaultValue()) {
834 trace.report(DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE.on(parameter));
835 }
836
837 if (multipleDefaultsInSuper) {
838 trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES.on(parameter, descriptor));
839 }
840
841 for (ValueParameterDescriptor parameterFromSuperclass : descriptor.getOverriddenDescriptors()) {
842 if (shouldReportParameterNameOverrideWarning(descriptor, parameterFromSuperclass)) {
843 //noinspection ConstantConditions
844 trace.report(PARAMETER_NAME_CHANGED_ON_OVERRIDE.on(
845 parameter,
846 (ClassDescriptor) parameterFromSuperclass.getContainingDeclaration().getContainingDeclaration(),
847 parameterFromSuperclass)
848 );
849 }
850 }
851 }
852
853 private void checkNameAndDefaultForFakeOverrideParameter(
854 @NotNull CallableMemberDescriptor containingFunction,
855 @NotNull ValueParameterDescriptor descriptor,
856 boolean multipleDefaultsInSuper
857 ) {
858 DeclarationDescriptor containingClass = containingFunction.getContainingDeclaration();
859 JetClassOrObject classElement =
860 (JetClassOrObject) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), containingClass);
861 assert classElement != null : "Declaration not found for class: " + containingClass;
862
863 if (multipleDefaultsInSuper) {
864 trace.report(MULTIPLE_DEFAULTS_INHERITED_FROM_SUPERTYPES_WHEN_NO_EXPLICIT_OVERRIDE.on(classElement, descriptor));
865 }
866
867 for (ValueParameterDescriptor parameterFromSuperclass : descriptor.getOverriddenDescriptors()) {
868 if (shouldReportParameterNameOverrideWarning(descriptor, parameterFromSuperclass)) {
869 trace.report(DIFFERENT_NAMES_FOR_THE_SAME_PARAMETER_IN_SUPERTYPES.on(
870 classElement,
871 containingFunction.getOverriddenDescriptors(),
872 parameterFromSuperclass.getIndex() + 1)
873 );
874 }
875 }
876 }
877
878 private static boolean shouldReportParameterNameOverrideWarning(
879 @NotNull ValueParameterDescriptor parameterFromSubclass,
880 @NotNull ValueParameterDescriptor parameterFromSuperclass
881 ) {
882 DeclarationDescriptor subFunction = parameterFromSubclass.getContainingDeclaration();
883 DeclarationDescriptor superFunction = parameterFromSuperclass.getContainingDeclaration();
884 return subFunction instanceof CallableDescriptor && ((CallableDescriptor) subFunction).hasStableParameterNames() &&
885 superFunction instanceof CallableDescriptor && ((CallableDescriptor) superFunction).hasStableParameterNames() &&
886 !parameterFromSuperclass.getName().equals(parameterFromSubclass.getName());
887 }
888
889 private static boolean checkPropertyKind(@NotNull CallableMemberDescriptor descriptor, boolean isVar) {
890 return descriptor instanceof PropertyDescriptor && ((PropertyDescriptor) descriptor).isVar() == isVar;
891 }
892
893 private void checkVisibility(@NotNull TopDownAnalysisContext c) {
894 for (Map.Entry<JetDeclaration, CallableMemberDescriptor> entry : c.getMembers().entrySet()) {
895 checkVisibilityForMember(entry.getKey(), entry.getValue());
896 }
897 }
898
899 private void checkVisibilityForMember(@NotNull JetDeclaration declaration, @NotNull CallableMemberDescriptor memberDescriptor) {
900 Visibility visibility = memberDescriptor.getVisibility();
901 for (CallableMemberDescriptor descriptor : memberDescriptor.getOverriddenDescriptors()) {
902 Integer compare = Visibilities.compare(visibility, descriptor.getVisibility());
903 if (compare == null) {
904 trace.report(CANNOT_CHANGE_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
905 return;
906 }
907 else if (compare < 0) {
908 trace.report(CANNOT_WEAKEN_ACCESS_PRIVILEGE.on(declaration, descriptor.getVisibility(), descriptor, descriptor.getContainingDeclaration()));
909 return;
910 }
911 }
912 }
913
914 @NotNull
915 public static <D extends CallableMemberDescriptor> Set<D> getDirectlyOverriddenDeclarations(@NotNull D descriptor) {
916 Set<D> result = Sets.newHashSet();
917 //noinspection unchecked
918 Set<D> overriddenDescriptors = (Set<D>) descriptor.getOverriddenDescriptors();
919 for (D overriddenDescriptor : overriddenDescriptors) {
920 CallableMemberDescriptor.Kind kind = overriddenDescriptor.getKind();
921 if (kind == DECLARATION) {
922 result.add(overriddenDescriptor);
923 }
924 else if (kind == FAKE_OVERRIDE || kind == DELEGATION) {
925 result.addAll(getDirectlyOverriddenDeclarations(overriddenDescriptor));
926 }
927 else if (kind == SYNTHESIZED) {
928 //do nothing
929 }
930 else {
931 throw new AssertionError("Unexpected callable kind " + kind);
932 }
933 }
934 return filterOutOverridden(result);
935 }
936
937 @NotNull
938 public static <D extends CallableMemberDescriptor> Set<D> getAllOverriddenDeclarations(@NotNull D memberDescriptor) {
939 Set<D> result = Sets.newHashSet();
940 for (CallableMemberDescriptor overriddenDeclaration : memberDescriptor.getOverriddenDescriptors()) {
941 CallableMemberDescriptor.Kind kind = overriddenDeclaration.getKind();
942 if (kind == DECLARATION) {
943 //noinspection unchecked
944 result.add((D) overriddenDeclaration);
945 }
946 else if (kind == DELEGATION || kind == FAKE_OVERRIDE || kind == SYNTHESIZED) {
947 //do nothing
948 }
949 else {
950 throw new AssertionError("Unexpected callable kind " + kind);
951 }
952 //noinspection unchecked
953 result.addAll(getAllOverriddenDeclarations((D) overriddenDeclaration));
954 }
955 return result;
956 }
957
958 @NotNull
959 @ReadOnly
960 public static <D extends CallableMemberDescriptor> Set<D> getDeepestSuperDeclarations(@NotNull D functionDescriptor) {
961 Set<D> overriddenDeclarations = getAllOverriddenDeclarations(functionDescriptor);
962 if (overriddenDeclarations.isEmpty()) {
963 return Collections.singleton(functionDescriptor);
964 }
965
966 return filterOutOverriding(overriddenDeclarations);
967 }
968 }