@@ -340,6 +340,61 @@ class Callable extends StmtParent, Member, @callable {
340340 }
341341}
342342
343+ /** A callable that is the same as its source declaration. */
344+ class SrcCallable extends Callable {
345+ SrcCallable ( ) { this .isSourceDeclaration ( ) }
346+
347+ /**
348+ * Holds if the given type is public and not a nested type.
349+ * If the given type is a nested type, holds if its enclosing type
350+ * is also public.
351+ */
352+ private predicate veryPublic ( RefType t ) {
353+ t .isPublic ( ) and
354+ (
355+ not t instanceof NestedType or
356+ veryPublic ( t .( NestedType ) .getEnclosingType ( ) )
357+ )
358+ }
359+
360+ /**
361+ * Holds if this callable is effectively `public`, meaning that it can be
362+ * called outside the codebase.
363+ */
364+ predicate isEffectivelyPublic ( ) {
365+ exists ( RefType t | t = this .getDeclaringType ( ) |
366+ this .isPublic ( ) and veryPublic ( t )
367+ or
368+ this .isProtected ( ) and not t .isFinal ( ) and veryPublic ( t )
369+ )
370+ or
371+ exists ( SrcRefType tsub , Method m |
372+ veryPublic ( tsub ) and
373+ tsub .hasMethod ( m , _) and
374+ m .getSourceDeclaration ( ) = this
375+ |
376+ this .isPublic ( )
377+ or
378+ this .isProtected ( ) and not tsub .isFinal ( )
379+ )
380+ }
381+
382+ /**
383+ * Holds if this callable is implicitly `public`, meaning that it can be
384+ * called outside the codebase or if there exists a method that can be called
385+ * outside the codebase and this callable is a possible implementation of that
386+ * method.
387+ */
388+ predicate isImplicitlyPublic ( ) {
389+ this .isEffectivelyPublic ( )
390+ or
391+ exists ( SrcMethod m |
392+ m .( SrcCallable ) .isEffectivelyPublic ( ) and
393+ m .getAPossibleImplementationOfSrcMethod ( ) = this
394+ )
395+ }
396+ }
397+
343398/** Gets the erasure of `t1` if it is a raw type, or `t1` itself otherwise. */
344399private Type eraseRaw ( Type t1 ) {
345400 if t1 instanceof RawType then result = t1 .getErasure ( ) else result = t1
0 commit comments