< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java

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

*** 23,10 ***
--- 23,11 ---
   * questions.
   */
  
  package com.sun.tools.javac.model;
  
+ import java.lang.reflect.Method;
  import java.util.Arrays;
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.LinkedHashSet;

*** 41,12 ***
--- 42,15 ---
  import javax.lang.model.type.DeclaredType;
  import javax.lang.model.util.Elements;
  import javax.tools.JavaFileObject;
  import static javax.lang.model.util.ElementFilter.methodsIn;
  
+ import com.sun.source.tree.Tree;
  import com.sun.source.util.JavacTask;
+ import com.sun.tools.javac.api.JavacScope;
  import com.sun.tools.javac.api.JavacTaskImpl;
+ import com.sun.tools.javac.api.JavacTrees;
  import com.sun.tools.javac.code.*;
  import com.sun.tools.javac.code.Attribute.Compound;
  import com.sun.tools.javac.code.Directive.ExportsDirective;
  import com.sun.tools.javac.code.Directive.ExportsFlag;
  import com.sun.tools.javac.code.Directive.OpensDirective;

*** 54,30 ***
  import com.sun.tools.javac.code.Directive.RequiresDirective;
  import com.sun.tools.javac.code.Directive.RequiresFlag;
  import com.sun.tools.javac.code.Scope.WriteableScope;
  import com.sun.tools.javac.code.Source.Feature;
  import com.sun.tools.javac.code.Symbol.*;
  import com.sun.tools.javac.comp.AttrContext;
  import com.sun.tools.javac.comp.Enter;
  import com.sun.tools.javac.comp.Env;
  import com.sun.tools.javac.main.JavaCompiler;
  import com.sun.tools.javac.processing.PrintingProcessor;
  import com.sun.tools.javac.tree.JCTree;
  import com.sun.tools.javac.tree.JCTree.*;
  import com.sun.tools.javac.tree.TreeInfo;
  import com.sun.tools.javac.tree.TreeScanner;
  import com.sun.tools.javac.util.*;
  import com.sun.tools.javac.util.DefinedBy.Api;
  import com.sun.tools.javac.util.Name;
  import static com.sun.tools.javac.code.Kinds.Kind.*;
  import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
  import static com.sun.tools.javac.code.TypeTag.CLASS;
! import com.sun.tools.javac.comp.Attr;
  import com.sun.tools.javac.comp.Modules;
  import com.sun.tools.javac.comp.Resolve;
- import com.sun.tools.javac.comp.Resolve.RecoveryLoadClass;
  import com.sun.tools.javac.resources.CompilerProperties.Notes;
  import static com.sun.tools.javac.tree.JCTree.Tag.*;
  
  /**
   * Utility methods for operating on program elements.
   *
--- 58,34 ---
  import com.sun.tools.javac.code.Directive.RequiresDirective;
  import com.sun.tools.javac.code.Directive.RequiresFlag;
  import com.sun.tools.javac.code.Scope.WriteableScope;
  import com.sun.tools.javac.code.Source.Feature;
  import com.sun.tools.javac.code.Symbol.*;
+ import com.sun.tools.javac.comp.Attr;
  import com.sun.tools.javac.comp.AttrContext;
  import com.sun.tools.javac.comp.Enter;
  import com.sun.tools.javac.comp.Env;
+ import com.sun.tools.javac.comp.ReflectMethods;
  import com.sun.tools.javac.main.JavaCompiler;
  import com.sun.tools.javac.processing.PrintingProcessor;
  import com.sun.tools.javac.tree.JCTree;
  import com.sun.tools.javac.tree.JCTree.*;
  import com.sun.tools.javac.tree.TreeInfo;
+ import com.sun.tools.javac.tree.TreeMaker;
  import com.sun.tools.javac.tree.TreeScanner;
  import com.sun.tools.javac.util.*;
  import com.sun.tools.javac.util.DefinedBy.Api;
  import com.sun.tools.javac.util.Name;
  import static com.sun.tools.javac.code.Kinds.Kind.*;
  import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
  import static com.sun.tools.javac.code.TypeTag.CLASS;
! 
  import com.sun.tools.javac.comp.Modules;
  import com.sun.tools.javac.comp.Resolve;
  import com.sun.tools.javac.resources.CompilerProperties.Notes;
+ import jdk.internal.java.lang.reflect.code.op.CoreOp;
+ 
  import static com.sun.tools.javac.tree.JCTree.Tag.*;
  
  /**
   * Utility methods for operating on program elements.
   *

*** 92,14 ***
--- 100,17 ---
      private final Symtab syms;
      private final Modules modules;
      private final Names names;
      private final Types types;
      private final Enter enter;
+     private final JavacTrees javacTrees;
      private final Attr attr;
      private final Resolve resolve;
+     private final ReflectMethods reflectMethods;
      private final JavacTaskImpl javacTaskImpl;
      private final Log log;
+     private final TreeMaker make;
      private final boolean allowModules;
  
      public static JavacElements instance(Context context) {
          JavacElements instance = context.get(JavacElements.class);
          if (instance == null)

*** 116,13 ***
--- 127,16 ---
          names = Names.instance(context);
          types = Types.instance(context);
          enter = Enter.instance(context);
          attr = Attr.instance(context);
          resolve = Resolve.instance(context);
+         javacTrees = JavacTrees.instance(context);
+         reflectMethods = ReflectMethods.instance(context);
          JavacTask t = context.get(JavacTask.class);
          javacTaskImpl = t instanceof JavacTaskImpl taskImpl ? taskImpl : null;
          log = Log.instance(context);
+         make = TreeMaker.instance(context);
          Source source = Source.instance(context);
          allowModules = Feature.MODULES.allowedInSource(source);
      }
  
      @Override @DefinedBy(Api.LANGUAGE_MODEL)

*** 791,10 ***
--- 805,42 ---
              case TYP -> ((ClassSymbol) sym).classfile;
              default -> sym.enclClass().classfile;
          };
      }
  
+     @Override @DefinedBy(Api.LANGUAGE_MODEL)
+     public Optional<Object> getBody(ExecutableElement e) {
+         if (e.getModifiers().contains(Modifier.ABSTRACT) ||
+                 e.getModifiers().contains(Modifier.NATIVE)) {
+             return Optional.empty();
+         }
+ 
+         CoreOp.FuncOp funcOp;
+         try {
+             JCMethodDecl methodTree = (JCMethodDecl)getTree(e);
+             JavacScope scope = javacTrees.getScope(javacTrees.getPath(e));
+             ClassSymbol enclosingClass = (ClassSymbol) scope.getEnclosingClass();
+             funcOp = attr.runWithAttributedMethod(scope.getEnv(), methodTree,
+                     attribBlock -> reflectMethods.getMethodBody(enclosingClass, methodTree, attribBlock, make));
+         } catch (RuntimeException ex) {  // ReflectMethods.UnsupportedASTException
+             // some other error occurred when attempting to attribute the method
+             // @@@ better report of error
+             ex.printStackTrace();
+             return Optional.empty();
+         }
+ 
+         // Reparse using API in java.base
+         try {
+             String opString = funcOp.toText();
+             Class<?> opParserClass = Class.forName("java.lang.reflect.code.parser.OpParser");
+             Method fromStringMethod = opParserClass.getDeclaredMethod("fromStringOfFuncOp", String.class);
+             return Optional.of(fromStringMethod.invoke(null, opString));
+         } catch (ReflectiveOperationException ex) {
+             throw new RuntimeException(ex);
+         }
+     }
+ 
      /**
       * Returns the tree node and compilation unit corresponding to this
       * element, or null if they can't be found.
       */
      private Pair<JCTree, JCCompilationUnit> getTreeAndTopLevel(Element e) {
< prev index next >