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