Пример #1
0
  /** Finds type with given name. */
  private JavaSymbol findType(Env env, String name) {
    JavaSymbol bestSoFar = symbolNotFound;
    for (Env env1 = env; env1 != null; env1 = env1.outer) {
      for (JavaSymbol symbol : env1.scope.lookup(name)) {
        if (symbol.kind == JavaSymbol.TYP) {
          return symbol;
        }
      }
      if (env1.outer != null) {
        JavaSymbol symbol = findMemberType(env1, env1.enclosingClass, name, env1.enclosingClass);
        if (symbol.kind < JavaSymbol.ERRONEOUS) {
          // symbol exists
          return symbol;
        } else if (symbol.kind < bestSoFar.kind) {
          bestSoFar = symbol;
        }
      }
    }

    // checks predefined types
    JavaSymbol predefinedSymbol =
        findMemberType(env, symbols.predefClass, name, symbols.predefClass);
    if (predefinedSymbol.kind < bestSoFar.kind) {
      return predefinedSymbol;
    }

    // JLS8 6.4.1 Shadowing rules
    // named imports
    for (JavaSymbol symbol : env.namedImports.lookup(name)) {
      if (symbol.kind == JavaSymbol.TYP) {
        return symbol;
      }
    }
    // package types
    JavaSymbol sym = findIdentInPackage(env.packge, name, JavaSymbol.TYP);
    if (sym.kind < bestSoFar.kind) {
      return sym;
    }
    // on demand imports
    for (JavaSymbol symbol : env.starImports.lookup(name)) {
      if (symbol.kind == JavaSymbol.TYP) {
        return symbol;
      }
    }
    // java.lang
    JavaSymbol.PackageJavaSymbol javaLang = bytecodeCompleter.enterPackage("java.lang");
    for (JavaSymbol symbol : javaLang.completedMembers().lookup(name)) {
      if (symbol.kind == JavaSymbol.TYP) {
        return symbol;
      }
    }
    return bestSoFar;
  }
Пример #2
0
 /**
  * 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);
   }
 }
Пример #3
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();
  }