Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code cleanup #312

Merged
merged 1 commit into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 37 additions & 39 deletions aot-api/src/main/java/io/micronaut/aot/MicronautAotOptimizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
Expand All @@ -73,21 +72,21 @@
* generation at build time. Its role is to generate a bunch of
* source code for various optimizations which can be computed
* at build time.
*
* <p>
* Typically, generated code will involve the generation of an
* "optimized" entry point for the application, which delegates
* to the main entry point, but also performs some static
* initialization by making calls to the
* {@link io.micronaut.core.optim.StaticOptimizations} class.
*
* <p>
* The Micronaut AOT optimizer is experimental and won't do
* anything by its own: it must be integrated in some form, for
* example via a build plugin, which in turn will make the generated
* classes visible to the user. For example, the build tool may
* call this class to generate the optimization code, and in addition
* create an optimized jar, an optimized native binary or even a
* full distribution.
*
* <p>
* The optimizer works by passing in the whole application runtime
* classpath and a set of configuration options. It then analyzes
* the classpath, for example to identify the services to be loaded,
Expand Down Expand Up @@ -119,9 +118,9 @@ private MicronautAotOptimizer(List<File> classpath,

private void compileGeneratedSources(List<File> extraClasspath, List<JavaFile> javaFiles) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> ds = new DiagnosticCollector<>();
var ds = new DiagnosticCollector<JavaFileObject>();
try (StandardJavaFileManager mgr = compiler.getStandardFileManager(ds, null, null)) {
List<File> fullClasspath = new ArrayList<>(classpath);
var fullClasspath = new ArrayList<>(classpath);
fullClasspath.addAll(extraClasspath);
List<String> options = compilerOptions(outputClassesDirectory, fullClasspath);
List<File> filesToCompile = outputSourceFilesToSourceDir(outputSourcesDirectory, javaFiles);
Expand All @@ -134,8 +133,8 @@ private void compileGeneratedSources(List<File> extraClasspath, List<JavaFile> j
throw new RuntimeException("Unable to compile generated classes", e);
}
List<Diagnostic<? extends JavaFileObject>> diagnostics = ds.getDiagnostics().stream()
.filter(d -> d.getKind() == Diagnostic.Kind.ERROR)
.collect(Collectors.toList());
.filter(d -> d.getKind() == Diagnostic.Kind.ERROR)
.toList();
if (!diagnostics.isEmpty()) {
throwCompilationError(diagnostics);
}
Expand All @@ -150,21 +149,21 @@ private void compileGeneratedSources(List<File> extraClasspath, List<JavaFile> j
*/
public static void exportConfiguration(String runtime, File propertiesFile) {
List<AOTModule> list = SourceGeneratorLoader.list(Runtime.valueOf(runtime.toUpperCase(Locale.ENGLISH)));
try (PrintWriter wrt = new PrintWriter(new FileOutputStream(propertiesFile))) {
Deque<AOTModule> queue = new ArrayDeque<>(list);
try (var wrt = new PrintWriter(new FileOutputStream(propertiesFile))) {
var queue = new ArrayDeque<>(list);
while (!queue.isEmpty()) {
AOTModule generator = queue.pop();
if (!generator.description().isEmpty()) {
Arrays.stream(generator.description().split("\r?\n")).forEach(line ->
wrt.println("# " + line));
wrt.println("# " + line));
}
wrt.println(generator.id() + ".enabled = true");
Arrays.stream(generator.subgenerators())
.map(MetadataUtils::findMetadata)
.filter(Optional::isPresent)
.map(Optional::get)
.sorted(Collections.reverseOrder())
.forEachOrdered(queue::addFirst);
.map(MetadataUtils::findMetadata)
.filter(Optional::isPresent)
.map(Optional::get)
.sorted(Collections.reverseOrder())
.forEachOrdered(queue::addFirst);
for (Option option : generator.options()) {
wrt.println(toPropertiesSample(option));
}
Expand All @@ -190,16 +189,16 @@ public static void exportConfiguration(String runtime, File propertiesFile) {
* @param props the configuration properties
*/
public static void execute(Properties props) {
Configuration config = new DefaultConfiguration(props);
var config = new DefaultConfiguration(props);
String pkg = config.mandatoryValue(GENERATED_PACKAGE);
File outputDir = new File(config.mandatoryValue(OUTPUT_DIRECTORY));
File sourcesDir = new File(outputDir, "sources");
File classesDir = new File(outputDir, "classes");
File logsDir = new File(outputDir, "logs");
var outputDir = new File(config.mandatoryValue(OUTPUT_DIRECTORY));
var sourcesDir = new File(outputDir, "sources");
var classesDir = new File(outputDir, "classes");
var logsDir = new File(outputDir, "logs");

runner(pkg, sourcesDir, classesDir, logsDir, config)
.addClasspath(config.stringList(CLASSPATH).stream().map(File::new).collect(Collectors.toList()))
.execute();
.addClasspath(config.stringList(CLASSPATH).stream().map(File::new).collect(Collectors.toList()))
.execute();
}

public static Runner runner(String generatedPackage,
Expand All @@ -211,7 +210,7 @@ public static Runner runner(String generatedPackage,
}

private static List<File> outputSourceFilesToSourceDir(File srcDir, List<JavaFile> javaFiles) {
List<File> srcFiles = new ArrayList<>(javaFiles.size());
var srcFiles = new ArrayList<File>(javaFiles.size());
if (srcDir.isDirectory() || srcDir.mkdirs()) {
StreamHelper.trying(() -> {
for (JavaFile javaFile : javaFiles) {
Expand All @@ -230,7 +229,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
}

private static void throwCompilationError(List<Diagnostic<? extends JavaFileObject>> diagnostics) {
StringBuilder sb = new StringBuilder("Compilation errors:\n");
var sb = new StringBuilder("Compilation errors:\n");
for (Diagnostic<? extends JavaFileObject> d : diagnostics) {
JavaFileObject source = d.getSource();
String srcFile = source == null ? "unknown" : new File(source.toUri()).getName();
Expand All @@ -242,11 +241,11 @@ private static void throwCompilationError(List<Diagnostic<? extends JavaFileObje

private static List<String> compilerOptions(File dstDir,
List<File> classPath) {
List<String> options = new ArrayList<>();
var options = new ArrayList<String>();
options.add("-source");
options.add("1.8");
options.add("17");
options.add("-target");
options.add("1.8");
options.add("17");
options.add("-classpath");
String cp = classPath.stream().map(File::getAbsolutePath).collect(Collectors.joining(File.pathSeparator));
options.add(cp);
Expand All @@ -259,15 +258,15 @@ private void writeLogs(DefaultSourceGenerationContext context) {
if (logsDirectory.isDirectory() || logsDirectory.mkdirs()) {
writeLines(new File(logsDirectory, OUTPUT_RESOURCES_FILE_NAME), context.getExcludedResources());
context.getDiagnostics().forEach((key, messages) -> {
File logFile = new File(logsDirectory, key.toLowerCase(Locale.US) + ".log");
var logFile = new File(logsDirectory, key.toLowerCase(Locale.US) + ".log");
writeLines(logFile, messages);
});
}
}

private static void writeLines(File outputFile, Collection<String> lines) {
try (PrintWriter writer = new PrintWriter(
new OutputStreamWriter(new FileOutputStream(outputFile), StandardCharsets.UTF_8)
try (var writer = new PrintWriter(
new OutputStreamWriter(new FileOutputStream(outputFile), StandardCharsets.UTF_8)
)) {
lines.forEach(writer::println);
} catch (FileNotFoundException e) {
Expand Down Expand Up @@ -318,13 +317,12 @@ public Runner addClasspath(Collection<File> elements) {
return this;
}

@SuppressWarnings("unchecked")
public Runner execute() {
MicronautAotOptimizer optimizer = new MicronautAotOptimizer(
classpath,
outputSourcesDirectory,
outputClassesDirectory,
logsDirectory);
var optimizer = new MicronautAotOptimizer(
classpath,
outputSourcesDirectory,
outputClassesDirectory,
logsDirectory);
ApplicationContextAnalyzer analyzer = ApplicationContextAnalyzer.create(spec -> {
if (config.containsKey(Environments.TARGET_ENVIRONMENTS_NAMES)) {
List<String> targetEnvs = config.stringList(Environments.TARGET_ENVIRONMENTS_NAMES);
Expand All @@ -335,10 +333,10 @@ public Runner execute() {
});
Set<String> environmentNames = analyzer.getEnvironmentNames();
LOGGER.info("Analysis will be performed with active environments: {}", environmentNames);
DefaultSourceGenerationContext context = new DefaultSourceGenerationContext(generatedPackage, analyzer, config, outputClassesDirectory.toPath());
var context = new DefaultSourceGenerationContext(generatedPackage, analyzer, config, outputClassesDirectory.toPath());
List<AOTCodeGenerator> sourceGenerators = SourceGeneratorLoader.load(config.getRuntime(), context);
ApplicationContextConfigurerGenerator generator = new ApplicationContextConfigurerGenerator(
sourceGenerators
sourceGenerators
);
generator.generate(context);
optimizer.compileGeneratedSources(context.getExtraClasspath(), context.getGeneratedJavaFiles());
Expand Down
8 changes: 4 additions & 4 deletions aot-cli/src/main/java/io/micronaut/aot/cli/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ public class Main implements Runnable, ConfigKeys {
@Override
public void run() {
List<URL> classpath = toURLs(classpathString);
Properties props = new Properties();
var props = new Properties();
if (config.exists()) {
try (InputStreamReader reader = new InputStreamReader(new FileInputStream(config))) {
try (var reader = new InputStreamReader(new FileInputStream(config))) {
props.load(reader);
} catch (IOException e) {
throw new RuntimeException(e);
Expand Down Expand Up @@ -97,7 +97,7 @@ public void run() {
* @param ctxClassLoader the current context classloader
*/
private void executeInIsolatedLoader(Properties props, URL[] urls, ClassLoader ctxClassLoader) {
URLClassLoader cl = new URLClassLoader(urls, new FilteringClassLoader(ctxClassLoader));
var cl = new URLClassLoader(urls, new FilteringClassLoader(ctxClassLoader));
try {
Thread.currentThread().setContextClassLoader(cl);
Class<?> runnerClass = cl.loadClass("io.micronaut.aot.MicronautAotOptimizer");
Expand Down Expand Up @@ -127,7 +127,7 @@ private static List<URL> toURLs(String classpathString) {
}
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
.toList();
}

public static int execute(String[] args) {
Expand Down
18 changes: 9 additions & 9 deletions aot-cli/src/main/java/io/micronaut/aot/cli/VersionProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ public class VersionProvider implements CommandLine.IVersionProvider {

static {
String text = "unknown";
try (InputStream stream = VersionProvider.class.getResourceAsStream("/version.txt")) {
text = new BufferedReader(
new InputStreamReader(stream, StandardCharsets.UTF_8))
.lines()
.collect(Collectors.joining("\n"));
} catch (Exception ex) {
// noop
}
VERSION = text;
try (InputStream stream = VersionProvider.class.getResourceAsStream("/version.txt")) {
text = new BufferedReader(
new InputStreamReader(stream, StandardCharsets.UTF_8))
.lines()
.collect(Collectors.joining("\n"));
} catch (Exception ex) {
// noop
}
VERSION = text;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
* <li>one or more source files</li>
* <li>one or more resource files</li>
* </ul>
*
* <p>
* Code generators must be annotated with {@link AOTModule}.
*/
public interface AOTCodeGenerator {
Expand Down
16 changes: 15 additions & 1 deletion aot-core/src/main/java/io/micronaut/aot/core/AOTContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,27 +45,31 @@ public interface AOTContext {

/**
* Returns the source generators configuration.
*
* @return the configuration
*/
@NonNull
Configuration getConfiguration();

/**
* Returns the application context analyzer.
*
* @return the application context analyzer
*/
@NonNull
ApplicationContextAnalyzer getAnalyzer();

/**
* Registers a generated source file.
*
* @param javaFile the file to be added.
*/
void registerGeneratedSourceFile(@NonNull JavaFile javaFile);

/**
* Registers a code block to be executed statically when
* the optimized binary is loaded.
*
* @param staticInitializer the static initializer method
*/
void registerStaticInitializer(MethodSpec staticInitializer);
Expand All @@ -75,6 +79,7 @@ public interface AOTContext {
* create a class which implements the {@link io.micronaut.core.optim.StaticOptimizations}
* service type. The consumer should create a body which returns
* an instance of the optimization type.
*
* @param className the name of the class to generate
* @param optimizationKind the type of the optimization
* @param bodyBuilder the builder of the body of the load() method
Expand All @@ -84,13 +89,15 @@ public interface AOTContext {

/**
* Registers a generated service type.
*
* @param serviceType the type of the service
* @param simpleServiceName the simple name of the generated type
*/
void registerServiceImplementation(Class<?> serviceType, String simpleServiceName);

/**
* Registers a new generated resource.
*
* @param path the relative path to the resource (including file name)
* @param consumer the consumer to be called when the resource is generated.
*/
Expand Down Expand Up @@ -118,12 +125,14 @@ public interface AOTContext {

/**
* Registers a type as a requiring initialization at build time.
*
* @param className the type
*/
void registerBuildTimeInit(@NonNull String className);

/**
* Generates a java file spec.
*
* @param typeSpec the type spec of the main class
* @return a java file
*/
Expand All @@ -144,6 +153,7 @@ public interface AOTContext {
/**
* Stores an entry in the context. The entry may be read by other
* processors, as long as they are executed in the proper order.
*
* @param type the class of the value to store
* @param value the value to store
* @param <T> the type of the value
Expand All @@ -152,6 +162,7 @@ public interface AOTContext {

/**
* Reads an entry from the context.
*
* @param type the class of the entry
* @param <T> the type of the entry
* @return an empty value if absent
Expand All @@ -161,20 +172,23 @@ public interface AOTContext {

/**
* Returns the diagnostics map.
*
* @return the diagnostics
*/
@NonNull
Map<String, List<String>> getDiagnostics();

/**
* Returns the target runtime environment.
*
* @return target runtime
*/
@NonNull
Runtime getRuntime();

/**
* Returns the set of classes which require build time initialization
* Returns the set of classes which require build time initialization.
*
* @return the set of classes needing build time init
*/
Set<String> getBuildTimeInitClasses();
Expand Down
Loading
Loading