/**
  * Invoked when current class classified as inner class. Owner of inner classes - is some outer
  * class, which is either already completed, and thus already has this inner class as member,
  * either will be completed by {@link org.sonar.java.resolve.BytecodeCompleter}, and thus will
  * have this inner class as member (see {@link #defineInnerClass(String, int)}).
  */
 private void defineOuterClass(String outerName, String innerName, int flags) {
   JavaSymbol.TypeJavaSymbol outerClassSymbol = getClassSymbol(outerName, flags);
   Preconditions.checkState(
       outerClassSymbol.completer == null
           || outerClassSymbol.completer instanceof BytecodeCompleter);
   classSymbol.name = innerName;
   classSymbol.flags =
       flags | bytecodeCompleter.filterBytecodeFlags(classSymbol.flags & ~Flags.ACCESS_FLAGS);
   classSymbol.owner = outerClassSymbol;
 }
Beispiel #2
0
 /** Is class accessible in given environment? */
 @VisibleForTesting
 static boolean isAccessible(Env env, JavaSymbol.TypeJavaSymbol c) {
   final boolean result;
   switch (c.flags() & Flags.ACCESS_FLAGS) {
     case Flags.PRIVATE:
       result = sameOutermostClass(env.enclosingClass, c.owner());
       break;
     case 0:
       result = env.packge == c.packge();
       break;
     case Flags.PUBLIC:
       result = true;
       break;
     case Flags.PROTECTED:
       result = env.packge == c.packge() || isInnerSubClass(env.enclosingClass, c.owner());
       break;
     default:
       throw new IllegalStateException();
   }
   // TODO check accessibility of enclosing type: isAccessible(env, c.type.getEnclosingType())
   return result;
 }
 /**
  * If at this point there is no owner of current class, then this is a top-level class, because
  * outer classes always will be completed before inner classes - see {@link
  * #defineOuterClass(String, String, int)}. Owner of top-level classes - is a package.
  */
 @Override
 public void visitEnd() {
   if (classSymbol.owner == null) {
     String flatName = className.replace('/', '.');
     classSymbol.name = flatName.substring(flatName.lastIndexOf('.') + 1);
     classSymbol.owner = bytecodeCompleter.enterPackage(flatName);
     JavaSymbol.PackageJavaSymbol owner = (JavaSymbol.PackageJavaSymbol) classSymbol.owner;
     if (owner.members == null) {
       // package was without classes so far
       owner.members = new Scope(owner);
     }
     owner.members.enter(classSymbol);
   }
 }
Beispiel #4
0
 /** Is given class a subclass of given base class, or an inner class of a subclass? */
 private static boolean isInnerSubClass(JavaSymbol.TypeJavaSymbol c, JavaSymbol base) {
   while (c != null && isSubClass(c, base)) {
     c = c.owner().enclosingClass();
   }
   return c != null;
 }