< prev index next >

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

Print this page

  1 /*
  2  * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package com.sun.tools.javac.model;
 27 

 28 import java.util.Arrays;
 29 import java.util.Collections;
 30 import java.util.HashMap;
 31 import java.util.HashSet;
 32 import java.util.LinkedHashSet;
 33 import java.util.Map;
 34 import java.util.Optional;
 35 import java.util.Set;
 36 import java.util.stream.Collectors;
 37 
 38 import javax.lang.model.AnnotatedConstruct;
 39 import javax.lang.model.SourceVersion;
 40 import javax.lang.model.element.*;
 41 import javax.lang.model.type.DeclaredType;
 42 import javax.lang.model.util.Elements;
 43 import javax.tools.JavaFileObject;
 44 import static javax.lang.model.util.ElementFilter.methodsIn;
 45 

 46 import com.sun.source.util.JavacTask;

 47 import com.sun.tools.javac.api.JavacTaskImpl;

 48 import com.sun.tools.javac.code.*;
 49 import com.sun.tools.javac.code.Attribute.Compound;
 50 import com.sun.tools.javac.code.Directive.ExportsDirective;
 51 import com.sun.tools.javac.code.Directive.ExportsFlag;
 52 import com.sun.tools.javac.code.Directive.OpensDirective;
 53 import com.sun.tools.javac.code.Directive.OpensFlag;
 54 import com.sun.tools.javac.code.Directive.RequiresDirective;
 55 import com.sun.tools.javac.code.Directive.RequiresFlag;
 56 import com.sun.tools.javac.code.Scope.WriteableScope;
 57 import com.sun.tools.javac.code.Source.Feature;
 58 import com.sun.tools.javac.code.Symbol.*;

 59 import com.sun.tools.javac.comp.AttrContext;
 60 import com.sun.tools.javac.comp.Enter;
 61 import com.sun.tools.javac.comp.Env;

 62 import com.sun.tools.javac.main.JavaCompiler;
 63 import com.sun.tools.javac.processing.PrintingProcessor;
 64 import com.sun.tools.javac.tree.JCTree;
 65 import com.sun.tools.javac.tree.JCTree.*;
 66 import com.sun.tools.javac.tree.TreeInfo;

 67 import com.sun.tools.javac.tree.TreeScanner;
 68 import com.sun.tools.javac.util.*;
 69 import com.sun.tools.javac.util.DefinedBy.Api;
 70 import com.sun.tools.javac.util.Name;
 71 import static com.sun.tools.javac.code.Kinds.Kind.*;
 72 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
 73 import static com.sun.tools.javac.code.TypeTag.CLASS;
 74 import com.sun.tools.javac.comp.Attr;
 75 import com.sun.tools.javac.comp.Modules;
 76 import com.sun.tools.javac.comp.Resolve;
 77 import com.sun.tools.javac.comp.Resolve.RecoveryLoadClass;
 78 import com.sun.tools.javac.resources.CompilerProperties.Notes;


 79 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 80 
 81 /**
 82  * Utility methods for operating on program elements.
 83  *
 84  * <p><b>This is NOT part of any supported API.
 85  * If you write code that depends on this, you do so at your own
 86  * risk.  This code and its internal interfaces are subject to change
 87  * or deletion without notice.</b></p>
 88  */
 89 public class JavacElements implements Elements {
 90 
 91     private final JavaCompiler javaCompiler;
 92     private final Symtab syms;
 93     private final Modules modules;
 94     private final Names names;
 95     private final Types types;
 96     private final Enter enter;

 97     private final Attr attr;
 98     private final Resolve resolve;

 99     private final JavacTaskImpl javacTaskImpl;
100     private final Log log;

101     private final boolean allowModules;
102 
103     public static JavacElements instance(Context context) {
104         JavacElements instance = context.get(JavacElements.class);
105         if (instance == null)
106             instance = new JavacElements(context);
107         return instance;
108     }
109 
110     @SuppressWarnings("this-escape")
111     protected JavacElements(Context context) {
112         context.put(JavacElements.class, this);
113         javaCompiler = JavaCompiler.instance(context);
114         syms = Symtab.instance(context);
115         modules = Modules.instance(context);
116         names = Names.instance(context);
117         types = Types.instance(context);
118         enter = Enter.instance(context);
119         attr = Attr.instance(context);
120         resolve = Resolve.instance(context);


121         JavacTask t = context.get(JavacTask.class);
122         javacTaskImpl = t instanceof JavacTaskImpl taskImpl ? taskImpl : null;
123         log = Log.instance(context);

124         Source source = Source.instance(context);
125         allowModules = Feature.MODULES.allowedInSource(source);
126     }
127 
128     @Override @DefinedBy(Api.LANGUAGE_MODEL)
129     public Set<? extends ModuleElement> getAllModuleElements() {
130         if (allowModules)
131             return Collections.unmodifiableSet(modules.allModules());
132         else
133             return Collections.emptySet();
134     }
135 
136     @Override @DefinedBy(Api.LANGUAGE_MODEL)
137     public ModuleSymbol getModuleElement(CharSequence name) {
138         ensureEntered("getModuleElement");
139         if (modules.getDefaultModule() == syms.noModule)
140             return null;
141         String strName = name.toString();
142         if (strName.equals(""))
143             return syms.unnamedModule;

776             case PCK -> {
777                 PackageSymbol psym = (PackageSymbol) sym;
778                 if (psym.package_info == null) {
779                     yield null;
780                 }
781                 yield psym.package_info.classfile;
782             }
783 
784             case MDL -> {
785                 ModuleSymbol msym = (ModuleSymbol) sym;
786                 if (msym.module_info == null) {
787                     yield null;
788                 }
789                 yield msym.module_info.classfile;
790             }
791             case TYP -> ((ClassSymbol) sym).classfile;
792             default -> sym.enclClass().classfile;
793         };
794     }
795 
































796     /**
797      * Returns the tree node and compilation unit corresponding to this
798      * element, or null if they can't be found.
799      */
800     private Pair<JCTree, JCCompilationUnit> getTreeAndTopLevel(Element e) {
801         Symbol sym = cast(Symbol.class, e);
802         if (sym.kind == PCK) {
803             TypeSymbol pkgInfo = ((PackageSymbol) sym).package_info;
804             if (pkgInfo != null) {
805                 pkgInfo.complete();
806             }
807         }
808         Env<AttrContext> enterEnv = getEnterEnv(sym);
809         if (enterEnv == null)
810             return null;
811         JCTree tree = TreeInfo.declarationFor(sym, enterEnv.tree);
812         if (tree == null || enterEnv.toplevel == null)
813             return null;
814         return new Pair<>(tree, enterEnv.toplevel);
815     }

  1 /*
  2  * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package com.sun.tools.javac.model;
 27 
 28 import java.lang.reflect.Method;
 29 import java.util.Arrays;
 30 import java.util.Collections;
 31 import java.util.HashMap;
 32 import java.util.HashSet;
 33 import java.util.LinkedHashSet;
 34 import java.util.Map;
 35 import java.util.Optional;
 36 import java.util.Set;
 37 import java.util.stream.Collectors;
 38 
 39 import javax.lang.model.AnnotatedConstruct;
 40 import javax.lang.model.SourceVersion;
 41 import javax.lang.model.element.*;
 42 import javax.lang.model.type.DeclaredType;
 43 import javax.lang.model.util.Elements;
 44 import javax.tools.JavaFileObject;
 45 import static javax.lang.model.util.ElementFilter.methodsIn;
 46 
 47 import com.sun.source.tree.Tree;
 48 import com.sun.source.util.JavacTask;
 49 import com.sun.tools.javac.api.JavacScope;
 50 import com.sun.tools.javac.api.JavacTaskImpl;
 51 import com.sun.tools.javac.api.JavacTrees;
 52 import com.sun.tools.javac.code.*;
 53 import com.sun.tools.javac.code.Attribute.Compound;
 54 import com.sun.tools.javac.code.Directive.ExportsDirective;
 55 import com.sun.tools.javac.code.Directive.ExportsFlag;
 56 import com.sun.tools.javac.code.Directive.OpensDirective;
 57 import com.sun.tools.javac.code.Directive.OpensFlag;
 58 import com.sun.tools.javac.code.Directive.RequiresDirective;
 59 import com.sun.tools.javac.code.Directive.RequiresFlag;
 60 import com.sun.tools.javac.code.Scope.WriteableScope;
 61 import com.sun.tools.javac.code.Source.Feature;
 62 import com.sun.tools.javac.code.Symbol.*;
 63 import com.sun.tools.javac.comp.Attr;
 64 import com.sun.tools.javac.comp.AttrContext;
 65 import com.sun.tools.javac.comp.Enter;
 66 import com.sun.tools.javac.comp.Env;
 67 import com.sun.tools.javac.comp.ReflectMethods;
 68 import com.sun.tools.javac.main.JavaCompiler;
 69 import com.sun.tools.javac.processing.PrintingProcessor;
 70 import com.sun.tools.javac.tree.JCTree;
 71 import com.sun.tools.javac.tree.JCTree.*;
 72 import com.sun.tools.javac.tree.TreeInfo;
 73 import com.sun.tools.javac.tree.TreeMaker;
 74 import com.sun.tools.javac.tree.TreeScanner;
 75 import com.sun.tools.javac.util.*;
 76 import com.sun.tools.javac.util.DefinedBy.Api;
 77 import com.sun.tools.javac.util.Name;
 78 import static com.sun.tools.javac.code.Kinds.Kind.*;
 79 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
 80 import static com.sun.tools.javac.code.TypeTag.CLASS;
 81 
 82 import com.sun.tools.javac.comp.Modules;
 83 import com.sun.tools.javac.comp.Resolve;

 84 import com.sun.tools.javac.resources.CompilerProperties.Notes;
 85 import jdk.internal.java.lang.reflect.code.op.CoreOp;
 86 
 87 import static com.sun.tools.javac.tree.JCTree.Tag.*;
 88 
 89 /**
 90  * Utility methods for operating on program elements.
 91  *
 92  * <p><b>This is NOT part of any supported API.
 93  * If you write code that depends on this, you do so at your own
 94  * risk.  This code and its internal interfaces are subject to change
 95  * or deletion without notice.</b></p>
 96  */
 97 public class JavacElements implements Elements {
 98 
 99     private final JavaCompiler javaCompiler;
100     private final Symtab syms;
101     private final Modules modules;
102     private final Names names;
103     private final Types types;
104     private final Enter enter;
105     private final JavacTrees javacTrees;
106     private final Attr attr;
107     private final Resolve resolve;
108     private final ReflectMethods reflectMethods;
109     private final JavacTaskImpl javacTaskImpl;
110     private final Log log;
111     private final TreeMaker make;
112     private final boolean allowModules;
113 
114     public static JavacElements instance(Context context) {
115         JavacElements instance = context.get(JavacElements.class);
116         if (instance == null)
117             instance = new JavacElements(context);
118         return instance;
119     }
120 
121     @SuppressWarnings("this-escape")
122     protected JavacElements(Context context) {
123         context.put(JavacElements.class, this);
124         javaCompiler = JavaCompiler.instance(context);
125         syms = Symtab.instance(context);
126         modules = Modules.instance(context);
127         names = Names.instance(context);
128         types = Types.instance(context);
129         enter = Enter.instance(context);
130         attr = Attr.instance(context);
131         resolve = Resolve.instance(context);
132         javacTrees = JavacTrees.instance(context);
133         reflectMethods = ReflectMethods.instance(context);
134         JavacTask t = context.get(JavacTask.class);
135         javacTaskImpl = t instanceof JavacTaskImpl taskImpl ? taskImpl : null;
136         log = Log.instance(context);
137         make = TreeMaker.instance(context);
138         Source source = Source.instance(context);
139         allowModules = Feature.MODULES.allowedInSource(source);
140     }
141 
142     @Override @DefinedBy(Api.LANGUAGE_MODEL)
143     public Set<? extends ModuleElement> getAllModuleElements() {
144         if (allowModules)
145             return Collections.unmodifiableSet(modules.allModules());
146         else
147             return Collections.emptySet();
148     }
149 
150     @Override @DefinedBy(Api.LANGUAGE_MODEL)
151     public ModuleSymbol getModuleElement(CharSequence name) {
152         ensureEntered("getModuleElement");
153         if (modules.getDefaultModule() == syms.noModule)
154             return null;
155         String strName = name.toString();
156         if (strName.equals(""))
157             return syms.unnamedModule;

790             case PCK -> {
791                 PackageSymbol psym = (PackageSymbol) sym;
792                 if (psym.package_info == null) {
793                     yield null;
794                 }
795                 yield psym.package_info.classfile;
796             }
797 
798             case MDL -> {
799                 ModuleSymbol msym = (ModuleSymbol) sym;
800                 if (msym.module_info == null) {
801                     yield null;
802                 }
803                 yield msym.module_info.classfile;
804             }
805             case TYP -> ((ClassSymbol) sym).classfile;
806             default -> sym.enclClass().classfile;
807         };
808     }
809 
810     @Override @DefinedBy(Api.LANGUAGE_MODEL)
811     public Optional<Object> getBody(ExecutableElement e) {
812         if (e.getModifiers().contains(Modifier.ABSTRACT) ||
813                 e.getModifiers().contains(Modifier.NATIVE)) {
814             return Optional.empty();
815         }
816 
817         CoreOp.FuncOp funcOp;
818         try {
819             JCMethodDecl methodTree = (JCMethodDecl)getTree(e);
820             JavacScope scope = javacTrees.getScope(javacTrees.getPath(e));
821             ClassSymbol enclosingClass = (ClassSymbol) scope.getEnclosingClass();
822             funcOp = attr.runWithAttributedMethod(scope.getEnv(), methodTree,
823                     attribBlock -> reflectMethods.getMethodBody(enclosingClass, methodTree, attribBlock, make));
824         } catch (RuntimeException ex) {  // ReflectMethods.UnsupportedASTException
825             // some other error occurred when attempting to attribute the method
826             // @@@ better report of error
827             ex.printStackTrace();
828             return Optional.empty();
829         }
830 
831         // Reparse using API in java.base
832         try {
833             String opString = funcOp.toText();
834             Class<?> opParserClass = Class.forName("java.lang.reflect.code.parser.OpParser");
835             Method fromStringMethod = opParserClass.getDeclaredMethod("fromStringOfFuncOp", String.class);
836             return Optional.of(fromStringMethod.invoke(null, opString));
837         } catch (ReflectiveOperationException ex) {
838             throw new RuntimeException(ex);
839         }
840     }
841 
842     /**
843      * Returns the tree node and compilation unit corresponding to this
844      * element, or null if they can't be found.
845      */
846     private Pair<JCTree, JCCompilationUnit> getTreeAndTopLevel(Element e) {
847         Symbol sym = cast(Symbol.class, e);
848         if (sym.kind == PCK) {
849             TypeSymbol pkgInfo = ((PackageSymbol) sym).package_info;
850             if (pkgInfo != null) {
851                 pkgInfo.complete();
852             }
853         }
854         Env<AttrContext> enterEnv = getEnterEnv(sym);
855         if (enterEnv == null)
856             return null;
857         JCTree tree = TreeInfo.declarationFor(sym, enterEnv.tree);
858         if (tree == null || enterEnv.toplevel == null)
859             return null;
860         return new Pair<>(tree, enterEnv.toplevel);
861     }
< prev index next >