Esempio n. 1
0
  /**
   * Main method: enter one class from a list of toplevel trees and place the rest on uncompleted
   * for later processing.
   *
   * @param trees The list of trees to be processed.
   * @param c The class symbol to be processed.
   */
  public void complete(List<JCCompilationUnit> trees, ClassSymbol c) {
    annotate.enterStart();
    ListBuffer<ClassSymbol> prevUncompleted = uncompleted;
    if (memberEnter.completionEnabled) uncompleted = new ListBuffer<ClassSymbol>();

    try {
      // enter all classes, and construct uncompleted list
      classEnter(trees, null);

      // complete all uncompleted classes in memberEnter
      if (memberEnter.completionEnabled) {
        while (uncompleted.nonEmpty()) {
          ClassSymbol clazz = uncompleted.next();
          if (c == null || c == clazz || prevUncompleted == null) clazz.complete();
          else
            // defer
            prevUncompleted.append(clazz);
        }

        // if there remain any unimported toplevels (these must have
        // no classes at all), process their import statements as well.
        for (JCCompilationUnit tree : trees) {
          if (tree.starImportScope.elems == null) {
            JavaFileObject prev = log.useSource(tree.sourcefile);
            Env<AttrContext> topEnv = topLevelEnv(tree);
            memberEnter.memberEnter(tree, topEnv);
            log.useSource(prev);
          }
        }
      }
    } finally {
      uncompleted = prevUncompleted;
      annotate.enterDone();
    }
  }
Esempio n. 2
0
  @Override
  public void visitTopLevel(JCCompilationUnit tree) {
    JavaFileObject prev = log.useSource(tree.sourcefile);
    boolean addEnv = false;
    boolean isPkgInfo =
        tree.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE);
    if (tree.pid != null) {
      tree.packge = reader.enterPackage(TreeInfo.fullName(tree.pid));
      if (tree.packageAnnotations.nonEmpty() || pkginfoOpt == PkgInfo.ALWAYS) {
        if (isPkgInfo) {
          addEnv = true;
        } else {
          log.error(tree.packageAnnotations.head.pos(), "pkg.annotations.sb.in.package-info.java");
        }
      }
    } else {
      tree.packge = syms.unnamedPackage;
    }
    tree.packge.complete(); // Find all classes in package.
    Env<AttrContext> topEnv = topLevelEnv(tree);

    // Save environment of package-info.java file.
    if (isPkgInfo) {
      Env<AttrContext> env0 = typeEnvs.get(tree.packge);
      if (env0 == null) {
        typeEnvs.put(tree.packge, topEnv);
      } else {
        JCCompilationUnit tree0 = env0.toplevel;
        if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) {
          log.warning(
              tree.pid != null ? tree.pid.pos() : null, "pkg-info.already.seen", tree.packge);
          if (addEnv
              || (tree0.packageAnnotations.isEmpty()
                  && tree.docComments != null
                  && tree.docComments.get(tree) != null)) {
            typeEnvs.put(tree.packge, topEnv);
          }
        }
      }

      for (Symbol q = tree.packge; q != null && q.kind == PCK; q = q.owner) q.flags_field |= EXISTS;

      Name name = names.package_info;
      ClassSymbol c = reader.enterClass(name, tree.packge);
      c.flatname = names.fromString(tree.packge + "." + name);
      c.sourcefile = tree.sourcefile;
      c.completer = null;
      c.members_field = new Scope(c);
      tree.packge.package_info = c;
    }
    classEnter(tree.defs, topEnv);
    if (addEnv) {
      todo.append(topEnv);
    }
    log.useSource(prev);
    result = null;
  }
Esempio n. 3
0
  protected Enter(Context context) {
    context.put(enterKey, this);

    log = Log.instance(context);
    reader = ClassReader.instance(context);
    make = TreeMaker.instance(context);
    syms = Symtab.instance(context);
    chk = Check.instance(context);
    memberEnter = MemberEnter.instance(context);
    types = Types.instance(context);
    annotate = Annotate.instance(context);
    lint = Lint.instance(context);
    names = Names.instance(context);

    predefClassDef =
        make.ClassDef(make.Modifiers(PUBLIC), syms.predefClass.name, null, null, null, null);
    predefClassDef.sym = syms.predefClass;
    todo = Todo.instance(context);
    fileManager = context.get(JavaFileManager.class);

    Options options = Options.instance(context);
    pkginfoOpt = PkgInfo.get(options);
  }
Esempio n. 4
0
 /** Complain about a duplicate class. */
 protected void duplicateClass(DiagnosticPosition pos, ClassSymbol c) {
   log.error(pos, "duplicate.class", c.fullname);
 }
Esempio n. 5
0
  @Override
  public void visitClassDef(JCClassDecl tree) {
    Symbol owner = env.info.scope.owner;
    Scope enclScope = enterScope(env);
    ClassSymbol c;
    if (owner.kind == PCK) {
      // We are seeing a toplevel class.
      PackageSymbol packge = (PackageSymbol) owner;
      for (Symbol q = packge; q != null && q.kind == PCK; q = q.owner) q.flags_field |= EXISTS;
      c = reader.enterClass(tree.name, packge);
      packge.members().enterIfAbsent(c);
      if ((tree.mods.flags & PUBLIC) != 0 && !classNameMatchesFileName(c, env)) {
        log.error(tree.pos(), "class.public.should.be.in.file", tree.name);
      }
    } else {
      if (!tree.name.isEmpty() && !chk.checkUniqueClassName(tree.pos(), tree.name, enclScope)) {
        result = null;
        return;
      }
      if (owner.kind == TYP) {
        // We are seeing a member class.
        c = reader.enterClass(tree.name, (TypeSymbol) owner);
        if ((owner.flags_field & INTERFACE) != 0) {
          tree.mods.flags |= PUBLIC | STATIC;
        }
      } else {
        // We are seeing a local class.
        c = reader.defineClass(tree.name, owner);
        c.flatname = chk.localClassName(c);
        if (!c.name.isEmpty()) chk.checkTransparentClass(tree.pos(), c, env.info.scope);
      }
    }
    tree.sym = c;

    // Enter class into `compiled' table and enclosing scope.
    if (chk.compiled.get(c.flatname) != null) {
      duplicateClass(tree.pos(), c);
      result = types.createErrorType(tree.name, (TypeSymbol) owner, Type.noType);
      tree.sym = (ClassSymbol) result.tsym;
      return;
    }
    chk.compiled.put(c.flatname, c);
    enclScope.enter(c);

    // Set up an environment for class block and store in `typeEnvs'
    // table, to be retrieved later in memberEnter and attribution.
    Env<AttrContext> localEnv = classEnv(tree, env);
    typeEnvs.put(c, localEnv);

    // Fill out class fields.
    c.completer = memberEnter;
    c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree);
    c.sourcefile = env.toplevel.sourcefile;
    c.members_field = new Scope(c);

    ClassType ct = (ClassType) c.type;
    if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
      // We are seeing a local or inner class.
      // Set outer_field of this class to closest enclosing class
      // which contains this class in a non-static context
      // (its "enclosing instance class"), provided such a class exists.
      Symbol owner1 = owner;
      while ((owner1.kind & (VAR | MTH)) != 0 && (owner1.flags_field & STATIC) == 0) {
        owner1 = owner1.owner;
      }
      if (owner1.kind == TYP) {
        ct.setEnclosingType(owner1.type);
      }
    }

    // Enter type parameters.
    ct.typarams_field = classEnter(tree.typarams, localEnv);

    // Add non-local class to uncompleted, to make sure it will be
    // completed later.
    if (!c.isLocal() && uncompleted != null) uncompleted.append(c);
    //      System.err.println("entering " + c.fullname + " in " + c.owner);//DEBUG

    // Recursively enter all member classes.
    classEnter(tree.defs, localEnv);

    result = c.type;
  }