@@ -354,37 +354,44 @@ abstract class RefChecks extends Transform {
354
354
overrideErrorWithMemberInfo(" `override` modifier required to override concrete member:" )
355
355
}
356
356
357
- def overrideAccessError (): Unit = {
358
- val otherAccess = accessFlagsToString(other)
359
- overrideError(" weaker access privileges in overriding\n " +
360
- overriddenWithAddendum(s " override should ${(if (otherAccess == " " ) " be public" else " at least be " + otherAccess)}" ))
361
- }
357
+ def weakerAccessError (advice : String ): Unit = overrideError(s " weaker access privileges in overriding \n ${overriddenWithAddendum(advice)}" )
358
+ def overrideAccessError (): Unit =
359
+ accessFlagsToString(other) match {
360
+ case " " => weakerAccessError(" override should be public" )
361
+ case otherAccess => weakerAccessError(s " override should at least be $otherAccess" )
362
+ }
362
363
363
364
// Console.println(infoString(member) + " overrides " + infoString(other) + " in " + clazz);//DEBUG
364
365
365
366
/* Is the intersection between given two lists of overridden symbols empty? */
366
- def intersectionIsEmpty (syms1 : List [Symbol ], syms2 : List [Symbol ]) =
367
- ! (syms1 exists (syms2 contains _))
367
+ def intersectionIsEmpty (syms1 : List [Symbol ], syms2 : List [Symbol ]) = ! syms1.exists(syms2 contains _)
368
368
369
- if (memberClass == ObjectClass && otherClass == AnyClass ) {} // skip -- can we have a mode of symbolpairs where this pair doesn't even appear?
369
+ if (memberClass == ObjectClass && otherClass == AnyClass ) () // skip -- can we have a mode of symbolpairs where this pair doesn't even appear?
370
370
else if (typesOnly) checkOverrideTypes()
371
371
else {
372
372
// o: public | protected | package-protected (aka java's default access)
373
373
// ^-may be overridden by member with access privileges-v
374
374
// m: public | public/protected | public/protected/package-protected-in-same-package-as-o
375
375
376
376
if (member.isPrivate) // (1.1)
377
- overrideError(" weaker access privileges in overriding\n " +
378
- overriddenWithAddendum(s " override should not be private " ))
377
+ overrideError(sm """ weaker access privileges in overriding
378
+ | ${ overriddenWithAddendum(" override should not be private" )} """ )
379
379
380
380
// todo: align accessibility implication checking with isAccessible in Contexts
381
- val ob = other.accessBoundary(memberClass)
382
- val mb = member.accessBoundary(memberClass)
383
- def isOverrideAccessOK = member.isPublic || { // member is public, definitely same or relaxed access
384
- ( ! other.isProtected || member.isProtected) && // if o is protected, so is m
385
- (( ! isRootOrNone(ob) && ob.hasTransOwner(mb)) || // m relaxes o's access boundary
386
- (other.isJavaDefined && other.isProtected)) // overriding a protected java member, see #3946 #12349
381
+ @ inline def protectedOK = ! other.isProtected || member.isProtected
382
+ @ inline def accessBoundaryOK = {
383
+ val ob = other.accessBoundary(memberClass)
384
+ val mb = member.accessBoundary(memberClass)
385
+ @ inline def companionBoundaryOK = ob.isClass && mb.isModuleClass && mb.module == ob.companionSymbol
386
+ ! isRootOrNone(ob) && (ob.hasTransOwner(mb) || companionBoundaryOK)
387
387
}
388
+ @ inline def otherIsJavaProtected = other.isJavaDefined && other.isProtected
389
+ def isOverrideAccessOK =
390
+ member.isPublic || // member is public, definitely same or relaxed access
391
+ protectedOK && // if o is protected, so is m
392
+ (accessBoundaryOK || // m relaxes o's access boundary
393
+ otherIsJavaProtected // overriding a protected java member, see #3946 #12349
394
+ )
388
395
if (! isOverrideAccessOK) {
389
396
overrideAccessError()
390
397
} else if (other.isClass) {
@@ -753,10 +760,8 @@ abstract class RefChecks extends Transform {
753
760
lazy val varargsType = toJavaRepeatedParam(member.tpe)
754
761
755
762
def isSignatureMatch (sym : Symbol ) = ! sym.isTerm || {
756
- val symtpe = clazz.thisType memberType sym
757
- def matches (tp : Type ) = tp matches symtpe
758
-
759
- matches(member.tpe) || (isVarargs && matches(varargsType))
763
+ val symtpe = clazz.thisType.memberType(sym)
764
+ member.tpe.matches(symtpe) || (isVarargs && varargsType.matches(symtpe))
760
765
}
761
766
/* The rules for accessing members which have an access boundary are more
762
767
* restrictive in java than scala. Since java has no concept of package nesting,
@@ -781,15 +786,19 @@ abstract class RefChecks extends Transform {
781
786
|| sym.isProtected // marked protected in java, thus accessible to subclasses
782
787
|| sym.privateWithin == member.enclosingPackageClass // exact package match
783
788
)
784
- def classDecls = inclazz.info.nonPrivateDecl(member.name)
785
- def matchingSyms = classDecls filter (sym => isSignatureMatch(sym) && javaAccessCheck(sym))
789
+ def classDecl =
790
+ inclazz.info.nonPrivateDecl(member.name) match {
791
+ case NoSymbol => inclazz.info.nonPrivateDecl(member.unexpandedName)
792
+ case exact => exact
793
+ }
794
+ def matchingSyms = classDecl.filter(sym => isSignatureMatch(sym) && javaAccessCheck(sym))
786
795
787
796
(inclazz != clazz) && (matchingSyms != NoSymbol )
788
797
}
789
798
790
799
// 4. Check that every defined member with an `override` modifier overrides some other member.
791
800
for (member <- clazz.info.decls)
792
- if (member.isAnyOverride && ! (clazz.thisType.baseClasses exists (hasMatchingSym(_, member)))) {
801
+ if (member.isAnyOverride && ! (clazz.thisType.baseClasses. exists(hasMatchingSym(_, member)))) {
793
802
// for (bc <- clazz.info.baseClasses.tail) Console.println("" + bc + " has " + bc.info.decl(member.name) + ":" + bc.info.decl(member.name).tpe);//DEBUG
794
803
795
804
val nonMatching : List [Symbol ] = clazz.info.member(member.name).alternatives.filterNot(_.owner == clazz).filterNot(_.isFinal)
0 commit comments