< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java

Print this page
*** 1,7 ***
  /*
!  * Copyright (c) 1999, 2023, 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
--- 1,7 ---
  /*
!  * 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

*** 24,10 ***
--- 24,11 ---
   */
  
  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;

*** 35,12 ***
--- 36,14 ---
  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;

*** 83,12 ***
  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;
--- 86,10 ---

*** 376,10 ***
--- 377,12 ---
  
      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;

*** 1052,10 ***
--- 1055,19 ---
          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;
      }

*** 1604,18 ***
              }
  
              if (shouldStop(CompileState.TRANSTYPES))
                  return;
  
              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);
              }
  
              compileStates.put(env, CompileState.TRANSPATTERNS);
  
              if (shouldStop(CompileState.LOWER))
--- 1616,26 ---
              }
  
              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);
              }
  
              compileStates.put(env, CompileState.TRANSPATTERNS);
  
              if (shouldStop(CompileState.LOWER))

*** 1659,10 ***
--- 1679,43 ---
              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.
       */

*** 1814,10 ***
--- 1867,14 ---
  
      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 >