< prev index next > src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java
Print this page
/*
- * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*/
package com.sun.tools.javac.main;
import java.io.*;
+ import java.lang.module.Configuration;
import java.nio.file.FileSystemNotFoundException;
import java.nio.file.InvalidPathException;
import java.nio.file.ReadOnlyFileSystemException;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.MissingResourceException;
+ import java.util.Optional;
import java.util.Queue;
import java.util.ResourceBundle;
+ import java.util.ServiceLoader;
import java.util.Set;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import javax.annotation.processing.Processor;
import com.sun.tools.javac.util.Log.DiscardDiagnosticHandler;
import com.sun.tools.javac.util.Log.WriterKind;
import static com.sun.tools.javac.code.Kinds.Kind.*;
- import com.sun.tools.javac.code.Lint;
- import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
import com.sun.tools.javac.resources.CompilerProperties.Notes;
private boolean enterDone;
protected CompileStates compileStates;
+ private boolean hasCodeReflectionModule;
+
/** Construct a new compiler using a shared context.
*/
@SuppressWarnings("this-escape")
public JavaCompiler(Context context) {
this.context = context;
return !shouldStop(CompileState.ATTR);
}
public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) {
modules.initModules(roots);
+
+ if (modules.modulesInitialized()) {
+ // This has to happen precisely here. At this point, we have all we need to
+ // determine whether jdk.incubator.module is part of the module graph
+ // but we have yet to trigger an ENTER event. This gives the code reflection plugin
+ // a window to check whether code reflection should be enabled for this compilation unit.
+ hasCodeReflectionModule = modules.getObservableModule(names.jdk_incubator_code) != null;
+ }
+
if (roots.isEmpty()) {
enterDone();
}
return roots;
}
}
if (shouldStop(CompileState.TRANSTYPES))
return;
+ if (Feature.REFLECT_METHODS.allowedInSource(source)) {
+ Optional<CodeReflectionTransformer> reflectMethods = reflectMethods();
+ if (reflectMethods.isPresent()) {
+ env.tree = reflectMethods.get().translateTopLevelClass(context, env.tree, localMake);
+ }
+ }
+
env.tree = transTypes.translateTopLevelClass(env.tree, localMake);
compileStates.put(env, CompileState.TRANSTYPES);
if (shouldStop(CompileState.TRANSPATTERNS))
return;
if (scanner.hasPatterns) {
- env.tree = TransPatterns.instance(context).translateTopLevelClass(env, env.tree, localMake);
+ env.tree = TransPatterns.instance(context)
+ .translateTopLevelClass(env, env.tree, localMake);
}
compileStates.put(env, CompileState.TRANSPATTERNS);
if (shouldStop(CompileState.LOWER))
log.useSource(prev);
}
}
+ Optional<CodeReflectionTransformer> reflectMethods() {
+ if (CodeReflectionSupport.CODE_LAYER != null) {
+ return ServiceLoader.load(CodeReflectionSupport.CODE_LAYER, CodeReflectionTransformer.class)
+ .findFirst();
+ } else {
+ return Optional.empty();
+ }
+ }
+
+ static class CodeReflectionSupport {
+ static final ModuleLayer CODE_LAYER;
+
+ static {
+ if (java.lang.module.ModuleFinder.ofSystem().find("jdk.incubator.code").isPresent() &&
+ !ModuleLayer.boot().findModule("jdk.incubator.code").isPresent()) {
+ ModuleLayer parent = ModuleLayer.boot();
+ Configuration cf = parent.configuration()
+ .resolve(java.lang.module.ModuleFinder.of(), java.lang.module.ModuleFinder.ofSystem(), Set.of("jdk.incubator.code"));
+ ClassLoader scl = ClassLoader.getSystemClassLoader();
+ CODE_LAYER = parent.defineModulesWithOneLoader(cf, scl);
+ Module codeReflectionModule = CODE_LAYER.findModule("jdk.incubator.code").get();
+ Module jdkCompilerModule = JavaCompiler.class.getModule();
+ // We need to add exports all jdk.compiler packages so that the plugin can use them
+ for (String packageName : jdkCompilerModule.getPackages()) {
+ jdkCompilerModule.addExports(packageName, codeReflectionModule);
+ }
+ } else {
+ // if we run javac in bootstrap mode, there might be no jdk.incubator.code
+ CODE_LAYER = null;
+ }
+ }
+ }
+
/** Generates the source or class file for a list of classes.
* The decision to generate a source file or a class file is
* based upon the compiler's options.
* Generation stops if an error occurs while writing files.
*/
public boolean isEnterDone() {
return enterDone;
}
+ public boolean hasCodeReflectionModule() {
+ return hasCodeReflectionModule;
+ }
+
private Name readModuleName(JavaFileObject fo) {
return parseAndGetName(fo, t -> {
JCModuleDecl md = t.getModuleDecl();
return md != null ? TreeInfo.fullName(md.getName()) : null;
< prev index next >