Beispiel #1
0
  private void findModuleInfo(ModuleSymbol msym) {
    try {
      JavaFileObject src_fo =
          (msym.sourceLocation == null)
              ? null
              : fileManager.getJavaFileForInput(
                  msym.sourceLocation, names.module_info.toString(), Kind.SOURCE);

      JavaFileObject class_fo =
          (msym.classLocation == null)
              ? null
              : fileManager.getJavaFileForInput(
                  msym.classLocation, names.module_info.toString(), Kind.CLASS);

      JavaFileObject fo =
          (src_fo == null)
              ? class_fo
              : (class_fo == null) ? src_fo : classFinder.preferredFileObject(src_fo, class_fo);

      if (fo == null) {
        String moduleName =
            msym.sourceLocation == null && msym.classLocation != null
                ? fileManager.inferModuleName(msym.classLocation)
                : null;
        if (moduleName != null) {
          msym.module_info.classfile = null;
          msym.flags_field |= Flags.AUTOMATIC_MODULE;
        } else {
          msym.kind = ERR;
        }
      } else {
        msym.module_info.classfile = fo;
        msym.module_info.completer =
            new Symbol.Completer() {
              @Override
              public void complete(Symbol sym) throws CompletionFailure {
                classFinder.fillIn(msym.module_info);
              }

              @Override
              public String toString() {
                return "ModuleInfoCompleter";
              }
            };
      }
    } catch (IOException e) {
      msym.kind = ERR;
    }
  }
 @Override
 public ClassLoader getClassLoader(Location location) {
   if (location == StandardLocation.PLATFORM_CLASS_PATH) {
     return standardJavaFileManager.getClassLoader(location);
   }
   return classLoader;
 }
Beispiel #3
0
  private List<ModuleSymbol> scanModulePath(ModuleSymbol toFind) {
    ListBuffer<ModuleSymbol> results = new ListBuffer<>();
    Map<Name, Location> namesInSet = new HashMap<>();
    while (moduleLocationIterator.hasNext()) {
      Set<Location> locns = (moduleLocationIterator.next());
      namesInSet.clear();
      for (Location l : locns) {
        try {
          Name n = names.fromString(fileManager.inferModuleName(l));
          if (namesInSet.put(n, l) == null) {
            ModuleSymbol msym = syms.enterModule(n);
            if (msym.sourceLocation != null || msym.classLocation != null) {
              // module has already been found, so ignore this instance
              continue;
            }
            if (moduleLocationIterator.outer == StandardLocation.MODULE_SOURCE_PATH) {
              msym.sourceLocation = l;
              if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
                msym.classLocation =
                    fileManager.getLocationForModule(
                        StandardLocation.CLASS_OUTPUT, msym.name.toString());
              }
            } else {
              msym.classLocation = l;
            }
            if (moduleLocationIterator.outer == StandardLocation.SYSTEM_MODULES
                || moduleLocationIterator.outer == StandardLocation.UPGRADE_MODULE_PATH) {
              msym.flags_field |= Flags.SYSTEM_MODULE;
            }
            if (toFind == msym || toFind == null) {
              // Note: cannot return msym directly, because we must finish
              // processing this set first
              results.add(msym);
            }
          } else {
            log.error(
                Errors.DuplicateModuleOnPath(getDescription(moduleLocationIterator.outer), n));
          }
        } catch (IOException e) {
          // skip location for now?  log error?
        }
      }
      if (toFind != null && results.nonEmpty()) return results.toList();
    }

    return results.toList();
  }
  private void initProcessorIterator(Context context, Iterable<? extends Processor> processors) {
    Log log = Log.instance(context);
    Iterator<? extends Processor> processorIterator;

    if (options.isSet(XPRINT)) {
      try {
        Processor processor = PrintingProcessor.class.newInstance();
        processorIterator = List.of(processor).iterator();
      } catch (Throwable t) {
        AssertionError assertError = new AssertionError("Problem instantiating PrintingProcessor.");
        assertError.initCause(t);
        throw assertError;
      }
    } else if (processors != null) {
      processorIterator = processors.iterator();
    } else {
      String processorNames = options.get(PROCESSOR);
      JavaFileManager fileManager = context.get(JavaFileManager.class);
      try {
        // If processorpath is not explicitly set, use the classpath.
        processorClassLoader =
            fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH)
                ? fileManager.getClassLoader(ANNOTATION_PROCESSOR_PATH)
                : fileManager.getClassLoader(CLASS_PATH);

        /*
         * If the "-processor" option is used, search the appropriate
         * path for the named class.  Otherwise, use a service
         * provider mechanism to create the processor iterator.
         */
        if (processorNames != null) {
          processorIterator = new NameProcessIterator(processorNames, processorClassLoader, log);
        } else {
          processorIterator = new ServiceIterator(processorClassLoader, log);
        }
      } catch (SecurityException e) {
        /*
         * A security exception will occur if we can't create a classloader.
         * Ignore the exception if, with hindsight, we didn't need it anyway
         * (i.e. no processor was specified either explicitly, or implicitly,
         * in service configuration file.) Otherwise, we cannot continue.
         */
        processorIterator = handleServiceLoaderUnavailability("proc.cant.create.loader", e);
      }
    }
    discoveredProcs = new DiscoveredProcessors(processorIterator);
  }
Beispiel #5
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;
  }
  /**
   * Returns an empty processor iterator if no processors are on the relevant path, otherwise if
   * processors are present, logs an error. Called when a service loader is unavailable for some
   * reason, either because a service loader class cannot be found or because a security policy
   * prevents class loaders from being created.
   *
   * @param key The resource key to use to log an error message
   * @param e If non-null, pass this exception to Abort
   */
  private Iterator<Processor> handleServiceLoaderUnavailability(String key, Exception e) {
    JavaFileManager fileManager = context.get(JavaFileManager.class);

    if (fileManager instanceof JavacFileManager) {
      StandardJavaFileManager standardFileManager = (JavacFileManager) fileManager;
      Iterable<? extends File> workingPath =
          fileManager.hasLocation(ANNOTATION_PROCESSOR_PATH)
              ? standardFileManager.getLocation(ANNOTATION_PROCESSOR_PATH)
              : standardFileManager.getLocation(CLASS_PATH);

      if (needClassLoader(options.get(PROCESSOR), workingPath)) handleException(key, e);

    } else {
      handleException(key, e);
    }

    java.util.List<Processor> pl = Collections.emptyList();
    return pl.iterator();
  }
 @Override
 public String inferBinaryName(Location location, JavaFileObject file) {
   if (file instanceof LocalFileObject) {
     return ((LocalFileObject) file).binaryName();
   }
   if (file instanceof ZipJavaFileObject) {
     return ((ZipJavaFileObject) file).binaryName();
   }
   return standardJavaFileManager.inferBinaryName(location, file);
 }
Beispiel #8
0
  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()) {
        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> env = 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, env);
      } 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, env);
          }
        }
      }
    }
    classEnter(tree.defs, env);
    if (addEnv) {
      todo.append(env);
    }
    log.useSource(prev);
    result = null;
  }
Beispiel #9
0
  private JavaFileObject getModuleInfoFromLocation(Location location, Kind kind)
      throws IOException {
    if (!fileManager.hasLocation(location)) return null;

    return fileManager.getJavaFileForInput(location, names.module_info.toString(), kind);
  }
Beispiel #10
0
  /**
   * Save a compiled class and associated classes to a jar file.
   *
   * <p>With a packageName = "" and recursive = false, it will save clazz and any classes compiled
   * from the same source (I think); this is probably what you want.
   *
   * @param packageName package name prefix to search for classes, or "" for all
   * @param clazz a class that has been previously compiled by this bridge
   * @param mainClazz a class that will be installed as the "Main-Class" of a runnable jar
   * @param outStream output stream
   * @param recursive whether to retrieve classes from rest of the the JavaFileManager hierarchy
   * @throws FileNotFoundException
   * @throws IOException
   */
  public void saveToJar(
      String packageName,
      Class<?> clazz,
      Class<?> mainClazz,
      OutputStream outStream,
      boolean recursive)
      throws IOException {
    JavaFileManager manager = fileManagerCache.get(clazz);
    List<JavaFileObject> list = new ArrayList<JavaFileObject>();

    for (JavaFileObject obj :
        manager.list(
            StandardLocation.CLASS_PATH,
            packageName,
            Collections.singleton(JavaFileObject.Kind.CLASS),
            false)) list.add(obj);

    if (list.iterator().hasNext()) {
      Manifest manifest = new Manifest();
      manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");

      if (mainClazz != null) {
        manifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS, mainClazz.getName());
      }
      manifest
          .getMainAttributes()
          .put(new Attributes.Name("X-Rascal-Saved-Class"), clazz.getName());
      JarOutputStream target = new JarOutputStream(outStream, manifest);
      JarEntry entry = new JarEntry("META-INF/");
      target.putNextEntry(entry);
      Collection<String> dirs = new ArrayList<String>();

      for (JavaFileObject o : list) {
        String path = o.toUri().getPath().replace(".", "/");
        makeJarDirs(target, dirs, path);
        entry = new JarEntry(path + ".class");
        entry.setTime(o.getLastModified());
        target.putNextEntry(entry);

        try (InputStream stream = o.openInputStream()) {
          byte[] buffer = new byte[8192];
          int c = stream.read(buffer);
          while (c > -1) {
            target.write(buffer, 0, c);
            c = stream.read(buffer);
          }
        }
        target.closeEntry();
      }

      if (mainClazz != null) {
        String name = mainClazz.getName();
        String path = name.replace(".", "/") + ".class";

        String dir = path.substring(0, path.lastIndexOf('/'));
        StringBuilder dirTmp = new StringBuilder(dir.length());
        for (String d : dir.split("/")) {
          dirTmp.append(d);
          dirTmp.append("/");
          String tmp = dirTmp.toString();
          if (!dirs.contains(tmp)) {
            dirs.add(tmp);
            entry = new JarEntry(tmp);
            target.putNextEntry(entry);
          }
        }
        entry = new JarEntry(path);
        target.putNextEntry(entry);

        try (InputStream stream = mainClazz.getClassLoader().getResourceAsStream(path)) {
          byte[] buffer = new byte[8192];
          int c = stream.read(buffer);
          while (c > -1) {
            target.write(buffer, 0, c);
            c = stream.read(buffer);
          }
        }
        target.closeEntry();
      }

      target.close();
    }
  }
    @Override
    public Iterable<JavaFileObject> list(
        Location location, String packageName, Set<Kind> kinds, boolean recurse)
        throws IOException {
      if (location == StandardLocation.PLATFORM_CLASS_PATH) {
        return standardJavaFileManager.list(location, packageName, kinds, recurse);
      }
      List<JavaFileObject> ret = new ArrayList<>();
      if (kinds.contains(Kind.CLASS) && location.equals(StandardLocation.CLASS_PATH)) {
        if (classLoader instanceof ModuleClassLoader) {
          ModuleClassLoader mcl = (ModuleClassLoader) classLoader;
          final String packageWithSlashes = packageName.replace(".", "/");
          try {
            Iterator<Resource> resources =
                mcl.getModule()
                    .iterateResources(
                        new PathFilter() {
                          @Override
                          public boolean accept(String path) {
                            if (recurse) {
                              return path.startsWith(packageWithSlashes);
                            } else {
                              return path.equals(packageWithSlashes);
                            }
                          }
                        });
            while (resources.hasNext()) {
              Resource res = resources.next();
              if (!res.getName().endsWith(".class")) {
                continue;
              }
              String binaryName =
                  res.getName().replace("/", ".").substring(0, res.getName().length() - 6);
              try {
                ret.add(
                    new ZipJavaFileObject(
                        org.fakereplace.util.FileReader.readFileBytes(res.openStream()),
                        binaryName,
                        res.getURL().toURI()));
              } catch (URISyntaxException e) {
                e.printStackTrace();
              }
            }
          } catch (ModuleLoadException e) {
            e.printStackTrace();
          }
        } else {
          URL res = classLoader.getResource(packageName.replace(".", "/"));
          if (res != null) {
            if (res.getProtocol().equals("file")) {
              Path dirPath = Paths.get(res.getFile());
              listDir(packageName, dirPath, recurse, ret);
            } else if (res.getProtocol().equals("jar")) {
              JarURLConnection connection = (JarURLConnection) res.openConnection();
              Enumeration<JarEntry> entryEnum = connection.getJarFile().entries();
              while (entryEnum.hasMoreElements()) {
                JarEntry entry = entryEnum.nextElement();
                String name = entry.getName();
                if (name.endsWith(".class") && !entry.isDirectory()) {
                  if (name.startsWith(packageName.replace(".", "/"))) {
                    String rem = name.substring(packageName.length());
                    if (rem.startsWith("/")) {
                      rem = rem.substring(1);
                    }
                    if (!recurse) {
                      if (rem.contains("/")) {
                        continue;
                      }
                    }
                    String binaryName =
                        entry
                            .getName()
                            .replace("/", ".")
                            .substring(0, entry.getName().length() - 6);
                    try {
                      URI uri = new URI(res.toExternalForm() + "/" + rem);
                      ret.add(
                          new ZipJavaFileObject(
                              org.fakereplace.util.FileReader.readFileBytes(
                                  uri.toURL().openStream()),
                              binaryName,
                              uri));
                    } catch (Exception e) {
                      e.printStackTrace();
                    }
                  }
                }
              }
            } else {
              System.err.println(
                  "Could not find package "
                      + packageName
                      + " in "
                      + classLoader
                      + " unknown protocol "
                      + res.getProtocol());
            }
          } else {
            return standardJavaFileManager.list(location, packageName, kinds, recurse);
          }
        }
      } else {
        return standardJavaFileManager.list(location, packageName, kinds, recurse);
      }

      return ret;
    }