/**
   * Adds the given new method declaration to the provided type AST Node. Can also inject
   * constructors.
   *
   * <p>Also takes care of updating the JavacAST.
   */
  public static void injectMethod(JavacNode typeNode, JCMethodDecl method) {
    JCClassDecl type = (JCClassDecl) typeNode.get();

    if (method.getName().contentEquals("<init>")) {
      // Scan for default constructor, and remove it.
      int idx = 0;
      for (JCTree def : type.defs) {
        if (def instanceof JCMethodDecl) {
          if ((((JCMethodDecl) def).mods.flags & Flags.GENERATEDCONSTR) != 0) {
            JavacNode tossMe = typeNode.getNodeFor(def);
            if (tossMe != null) tossMe.up().removeChild(tossMe);
            type.defs = addAllButOne(type.defs, idx);
            if (type.sym != null && type.sym.members_field != null) {
              type.sym.members_field.remove(((JCMethodDecl) def).sym);
            }
            break;
          }
        }
        idx++;
      }
    }

    addSuppressWarningsAll(method.mods, typeNode, method.pos, getGeneratedBy(method));
    type.defs = type.defs.append(method);

    typeNode.add(method, Kind.METHOD);
  }
  private static void injectField(
      JavacNode typeNode, JCVariableDecl field, boolean addSuppressWarnings) {
    JCClassDecl type = (JCClassDecl) typeNode.get();

    if (addSuppressWarnings)
      addSuppressWarningsAll(field.mods, typeNode, field.pos, getGeneratedBy(field));

    List<JCTree> insertAfter = null;
    List<JCTree> insertBefore = type.defs;
    while (insertBefore.tail != null) {
      if (insertBefore.head instanceof JCVariableDecl) {
        JCVariableDecl f = (JCVariableDecl) insertBefore.head;
        if (isEnumConstant(f) || isGenerated(f)) {
          insertAfter = insertBefore;
          insertBefore = insertBefore.tail;
          continue;
        }
      }
      break;
    }
    List<JCTree> fieldEntry = List.<JCTree>of(field);
    fieldEntry.tail = insertBefore;
    if (insertAfter == null) {
      type.defs = fieldEntry;
    } else {
      insertAfter.tail = fieldEntry;
    }

    typeNode.add(field, Kind.FIELD);
  }
 private JavaFileObject genCodeUnlessError(Env<AttrContext> env, JCClassDecl cdef)
     throws IOException {
   try {
     CeylonFileObject sourcefile = (CeylonFileObject) env.toplevel.sourcefile;
     // do not look at the global number of errors but only those for this file
     if (super.gen.genClass(env, cdef) && sourcefile.errors == 0)
       return writer.writeClass(cdef.sym);
   } catch (ClassWriter.PoolOverflow ex) {
     log.error(cdef.pos(), "limit.pool");
   } catch (ClassWriter.StringOverflow ex) {
     log.error(cdef.pos(), "limit.string.overflow", ex.value.substring(0, 20));
   } catch (CompletionFailure ex) {
     chk.completionError(cdef.pos(), ex);
   }
   return null;
 }
Beispiel #4
0
 public void visitClassDef(JCClassDecl tree) {
   try {
     consumeComments(tree.pos);
     println();
     align();
     printDocComment(tree);
     printAnnotations(tree.mods.annotations);
     printFlags(tree.mods.flags & ~INTERFACE);
     Name enclClassNamePrev = enclClassName;
     enclClassName = tree.name;
     if ((tree.mods.flags & INTERFACE) != 0) {
       print("interface " + tree.name);
       printTypeParameters(tree.typarams);
       if (tree.implementing.nonEmpty()) {
         print(" extends ");
         printExprs(tree.implementing);
       }
     } else {
       if ((tree.mods.flags & ENUM) != 0) print("enum " + tree.name);
       else print("class " + tree.name);
       printTypeParameters(tree.typarams);
       if (tree.getExtendsClause() != null) {
         print(" extends ");
         printExpr(tree.getExtendsClause());
       }
       if (tree.implementing.nonEmpty()) {
         print(" implements ");
         printExprs(tree.implementing);
       }
     }
     print(" ");
     // <Added for delombok by Reinier Zwitserloot>
     if ((tree.mods.flags & INTERFACE) != 0) {
       removeImplicitModifiersForInterfaceMembers(tree.defs);
     }
     // </Added for delombok by Reinier Zwitserloot>
     if ((tree.mods.flags & ENUM) != 0) {
       printEnumBody(tree.defs);
     } else {
       printBlock(tree.defs, tree);
     }
     enclClassName = enclClassNamePrev;
   } catch (IOException e) {
     throw new UncheckedIOException(e);
   }
 }
 private JavaFileObject genCodeUnlessError(Env<AttrContext> env, JCClassDecl cdef)
     throws IOException {
   CeylonFileObject sourcefile = (CeylonFileObject) env.toplevel.sourcefile;
   try {
     // do not look at the global number of errors but only those for this file
     if (super.gen.genClass(env, cdef) && !sourcefile.hasError(cdef.pos)) {
       String packageName = cdef.sym.packge().getQualifiedName().toString();
       Package pkg = modelLoader.findPackage(packageName);
       if (pkg == null) throw new RuntimeException("Failed to find package: " + packageName);
       Module module = pkg.getModule();
       if (!module.isDefault()) {
         String moduleName = module.getNameAsString();
         CeylonFileObject moduleFileObject = moduleNamesToFileObjects.get(moduleName);
         // if there's no module source file object it means the module descriptor had parse errors
         if (moduleFileObject == null || moduleFileObject.hasError()) {
           // we do not produce any class files for modules with errors
           if (options.get(OptionName.VERBOSE) != null) {
             Log.printLines(
                 log.noticeWriter,
                 "[Not writing class "
                     + cdef.sym.className()
                     + " because its module has errors: "
                     + moduleName
                     + "]");
           }
           return null;
         }
       }
       return writer.writeClass(cdef.sym);
     }
   } catch (ClassWriter.PoolOverflow ex) {
     log.error(cdef.pos(), "limit.pool");
   } catch (ClassWriter.StringOverflow ex) {
     log.error(cdef.pos(), "limit.string.overflow", ex.value.substring(0, 20));
   } catch (CompletionFailure ex) {
     chk.completionError(cdef.pos(), ex);
   } catch (AssertionError e) {
     throw new RuntimeException("Error generating bytecode for " + sourcefile.getName(), e);
   }
   return null;
 }
Beispiel #6
0
  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;
  }
 public void visitClassDef(JCClassDecl node) {
   node.sym = null;
   super.visitClassDef(node);
 }