Пример #1
0
 private JavaSymbol findMemberType(
     Env env, JavaSymbol.TypeJavaSymbol site, String name, JavaSymbol.TypeJavaSymbol c) {
   JavaSymbol bestSoFar = symbolNotFound;
   for (JavaSymbol symbol : c.members().lookup(name)) {
     if (symbol.kind == JavaSymbol.TYP) {
       return isAccessible(env, site, symbol)
           ? symbol
           : new AccessErrorJavaSymbol(symbol, Symbols.unknownType);
     }
   }
   if (c.getSuperclass() != null) {
     JavaSymbol symbol = findMemberType(env, site, name, c.getSuperclass().symbol);
     if (symbol.kind < bestSoFar.kind) {
       bestSoFar = symbol;
     }
   }
   if (c.getInterfaces() == null) {
     // Invariant to check that interfaces are not set only when we are looking into the symbol we
     // are currently completing.
     // required for generics
     Preconditions.checkState(
         c.completing, "interfaces of a symbol not currently completing are not set.");
     Preconditions.checkState(c == site);
   } else {
     for (JavaType interfaceType : c.getInterfaces()) {
       JavaSymbol symbol = findMemberType(env, site, name, interfaceType.symbol);
       if (symbol.kind < bestSoFar.kind) {
         bestSoFar = symbol;
       }
     }
   }
   return bestSoFar;
 }
Пример #2
0
 /** Finds field with given name. */
 private Resolution findField(
     Env env, JavaSymbol.TypeJavaSymbol site, String name, JavaSymbol.TypeJavaSymbol c) {
   Resolution bestSoFar = unresolved();
   Resolution resolution = new Resolution();
   for (JavaSymbol symbol : c.members().lookup(name)) {
     if (symbol.kind == JavaSymbol.VAR) {
       if (isAccessible(env, site, symbol)) {
         resolution.symbol = symbol;
         resolution.type = resolveTypeSubstitution(symbol.type, c.type);
         return resolution;
       } else {
         return Resolution.resolution(new AccessErrorJavaSymbol(symbol, Symbols.unknownType));
       }
     }
   }
   if (c.getSuperclass() != null) {
     resolution = findField(env, site, name, c.getSuperclass().symbol);
     if (resolution.symbol.kind < bestSoFar.symbol.kind) {
       resolution.type = resolveTypeSubstitution(resolution.symbol.type, c.getSuperclass());
       bestSoFar = resolution;
     }
   }
   for (JavaType interfaceType : c.getInterfaces()) {
     resolution = findField(env, site, name, interfaceType.symbol);
     if (resolution.symbol.kind < bestSoFar.symbol.kind) {
       bestSoFar = resolution;
     }
   }
   return bestSoFar;
 }
Пример #3
0
 /** Registers builtin types as symbols, so that they can be found as an usual identifiers. */
 private JavaType initType(int tag, String name) {
   JavaSymbol.TypeJavaSymbol symbol =
       new JavaSymbol.TypeJavaSymbol(Flags.PUBLIC, name, rootPackage);
   symbol.members = new Scope(symbol);
   predefClass.members.enter(symbol);
   ((JavaType.ClassJavaType) symbol.type).interfaces = ImmutableList.of();
   symbol.type.tag = tag;
   return symbol.type;
 }
Пример #4
0
 @Override
 public void visit(
     int version,
     int flags,
     String name,
     @Nullable String signature,
     @Nullable String superName,
     @Nullable String[] interfaces) {
   Preconditions.checkState(
       name.endsWith(classSymbol.name),
       "Name : '" + name + "' should ends with " + classSymbol.name);
   Preconditions.checkState(!BytecodeCompleter.isSynthetic(flags), name + " is synthetic");
   className = name;
   if (signature != null) {
     SignatureReader signatureReader = new SignatureReader(signature);
     signatureReader.accept(new TypeParameterDeclaration(classSymbol));
     ReadGenericSignature readGenericSignature = new ReadGenericSignature();
     signatureReader.accept(readGenericSignature);
     ((ClassJavaType) classSymbol.type).interfaces = readGenericSignature.interfaces();
   } else {
     if (superName == null) {
       Preconditions.checkState(
           "java/lang/Object".equals(className),
           "superName must be null only for java/lang/Object, but not for " + className);
       // TODO(Godin): what about interfaces and annotations
     } else {
       ((ClassJavaType) classSymbol.type).supertype = getClassSymbol(superName).type;
     }
     ((ClassJavaType) classSymbol.type).interfaces = getCompletedClassSymbolsType(interfaces);
   }
   // if class has already access flags set (inner class) then do not reset those.
   // The important access flags are the one defined in the outer class.
   if ((classSymbol.flags & Flags.ACCESS_FLAGS) != 0) {
     classSymbol.flags |= bytecodeCompleter.filterBytecodeFlags(flags & ~Flags.ACCESS_FLAGS);
   } else {
     classSymbol.flags |= bytecodeCompleter.filterBytecodeFlags(flags);
   }
   classSymbol.members = new Scope(classSymbol);
 }
Пример #5
0
  static {
    rootPackage = new JavaSymbol.PackageJavaSymbol("", null);
    unknownSymbol =
        new JavaSymbol.TypeJavaSymbol(Flags.PUBLIC, "!unknownSymbol!", rootPackage) {
          @Override
          public void addUsage(IdentifierTree tree) {
            // noop
          }

          @Override
          public boolean isTypeSymbol() {
            return false;
          }

          @Override
          public boolean isUnknown() {
            return true;
          }
        };
    unknownSymbol.members =
        new Scope(unknownSymbol) {
          @Override
          public void enter(JavaSymbol symbol) {
            // noop
          }
        };
    unknownType =
        new JavaType.ClassJavaType(unknownSymbol) {
          @Override
          public String toString() {
            return "!unknown!";
          }
        };
    unknownType.tag = JavaType.UNKNOWN;
    unknownType.supertype = null;
    unknownType.interfaces = ImmutableList.of();
    unknownSymbol.type = unknownType;
  }
Пример #6
0
  public Symbols(BytecodeCompleter bytecodeCompleter) {
    defaultPackage = new JavaSymbol.PackageJavaSymbol("", rootPackage);

    predefClass = new JavaSymbol.TypeJavaSymbol(Flags.PUBLIC, "", rootPackage);
    predefClass.members = new Scope(predefClass);
    ((JavaType.ClassJavaType) predefClass.type).interfaces = ImmutableList.of();

    // TODO should have type "noType":
    noSymbol = new JavaSymbol.TypeJavaSymbol(0, "", rootPackage);

    methodClass = new JavaSymbol.TypeJavaSymbol(Flags.PUBLIC, "", noSymbol);

    // builtin types
    byteType = initType(JavaType.BYTE, "byte");
    charType = initType(JavaType.CHAR, "char");
    shortType = initType(JavaType.SHORT, "short");
    intType = initType(JavaType.INT, "int");
    longType = initType(JavaType.LONG, "long");
    floatType = initType(JavaType.FLOAT, "float");
    doubleType = initType(JavaType.DOUBLE, "double");
    booleanType = initType(JavaType.BOOLEAN, "boolean");
    nullType = initType(JavaType.BOT, "<nulltype>");
    voidType = initType(JavaType.VOID, "void");

    bytecodeCompleter.init(this);

    // predefined types for java lang
    JavaSymbol.PackageJavaSymbol javalang = bytecodeCompleter.enterPackage("java.lang");
    // define a star import scope to let resolve types to java.lang when needed.
    javalang.members = new Scope.StarImportScope(javalang, bytecodeCompleter);
    javalang.members.enter(javalang);

    objectType = bytecodeCompleter.loadClass("java.lang.Object").type;
    classType = bytecodeCompleter.loadClass("java.lang.Class").type;
    stringType = bytecodeCompleter.loadClass("java.lang.String").type;
    cloneableType = bytecodeCompleter.loadClass("java.lang.Cloneable").type;
    serializableType = bytecodeCompleter.loadClass("java.io.Serializable").type;
    annotationType = bytecodeCompleter.loadClass("java.lang.annotation.Annotation").type;
    enumType = bytecodeCompleter.loadClass("java.lang.Enum").type;

    // Associate boxed types
    boxedTypes = HashBiMap.create();
    boxedTypes.put(byteType, bytecodeCompleter.loadClass("java.lang.Byte").type);
    boxedTypes.put(charType, bytecodeCompleter.loadClass("java.lang.Character").type);
    boxedTypes.put(shortType, bytecodeCompleter.loadClass("java.lang.Short").type);
    boxedTypes.put(intType, bytecodeCompleter.loadClass("java.lang.Integer").type);
    boxedTypes.put(longType, bytecodeCompleter.loadClass("java.lang.Long").type);
    boxedTypes.put(floatType, bytecodeCompleter.loadClass("java.lang.Float").type);
    boxedTypes.put(doubleType, bytecodeCompleter.loadClass("java.lang.Double").type);
    boxedTypes.put(booleanType, bytecodeCompleter.loadClass("java.lang.Boolean").type);

    for (Entry<JavaType, JavaType> entry : boxedTypes.entrySet()) {
      entry.getKey().primitiveWrapperType = entry.getValue();
      entry.getValue().primitiveType = entry.getKey();
    }

    // TODO comment me
    arrayClass = new JavaSymbol.TypeJavaSymbol(Flags.PUBLIC, "Array", noSymbol);
    JavaType.ClassJavaType arrayClassType = (JavaType.ClassJavaType) arrayClass.type;
    arrayClassType.supertype = objectType;
    arrayClassType.interfaces = ImmutableList.of(cloneableType, serializableType);
    arrayClass.members = new Scope(arrayClass);
    arrayClass
        .members()
        .enter(
            new JavaSymbol.VariableJavaSymbol(
                Flags.PUBLIC | Flags.FINAL, "length", intType, arrayClass));
    // TODO arrayClass implements clone() method

    enterOperators();
  }