Path: blob/aarch64-shenandoah-jdk8u272-b10/langtools/src/share/classes/com/sun/tools/classfile/ReferenceFinder.java
38899 views
/*1* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.tools.classfile;2627import java.util.ArrayList;28import java.util.HashSet;29import java.util.List;30import java.util.Objects;31import java.util.Set;32import com.sun.tools.classfile.Instruction.TypeKind;33import static com.sun.tools.classfile.ConstantPool.*;3435/**36* A utility class to find where in a ClassFile references37* a {@link CONSTANT_Methodref_info method},38* a {@link CONSTANT_InterfaceMethodref_info interface method,39* or a {@link CONSTANT_Fieldref_info field}.40*/41public final class ReferenceFinder {42/**43* Filter for ReferenceFinder of what constant pool entries for reference lookup.44*/45public interface Filter {46/**47* Decides if the given CPRefInfo entry should be accepted or filtered.48*49* @param cpool ConstantPool of the ClassFile being parsed50* @param cpref constant pool entry representing a reference to51* a fields method, and interface method.52* @return {@code true} if accepted; otherwise {@code false}53*/54boolean accept(ConstantPool cpool, CPRefInfo cpref);55}5657/**58* Visitor of individual method of a ClassFile that references the59* accepted field, method, or interface method references.60*/61public interface Visitor {62/**63* Invoked for a method containing one or more accepted CPRefInfo entries64*65* @param cf ClassFile66* @param method Method that does the references the accepted references67* @param refs Accepted constant pool method/field reference68*/69void visit(ClassFile cf, Method method, List<CPRefInfo> refConstantPool);70}7172private final Filter filter;73private final Visitor visitor;7475/**76* Constructor.77*/78public ReferenceFinder(Filter filter, Visitor visitor) {79this.filter = Objects.requireNonNull(filter);80this.visitor = Objects.requireNonNull(visitor);81}8283/**84* Parses a given ClassFile and invoke the visitor if there is any reference85* to the constant pool entries referencing field, method, or86* interface method that are accepted. This method will return87* {@code true} if there is one or more accepted constant pool entries88* to lookup; otherwise, it will return {@code false}.89*90* @param cf ClassFile91* @return {@code true} if the given class file is processed to lookup92* references93* @throws ConstantPoolException if an error of the constant pool94*/95public boolean parse(ClassFile cf) throws ConstantPoolException {96List<Integer> cprefs = new ArrayList<Integer>();97int index = 1;98for (ConstantPool.CPInfo cpInfo : cf.constant_pool.entries()) {99if (cpInfo.accept(cpVisitor, cf.constant_pool)) {100cprefs.add(index);101}102index += cpInfo.size();103}104105if (cprefs.isEmpty()) {106return false;107}108109for (Method m : cf.methods) {110Set<Integer> ids = new HashSet<Integer>();111Code_attribute c_attr = (Code_attribute) m.attributes.get(Attribute.Code);112if (c_attr != null) {113for (Instruction instr : c_attr.getInstructions()) {114int idx = instr.accept(codeVisitor, cprefs);115if (idx > 0) {116ids.add(idx);117}118}119}120if (ids.size() > 0) {121List<CPRefInfo> refInfos = new ArrayList<CPRefInfo>(ids.size());122for (int id : ids) {123refInfos.add(CPRefInfo.class.cast(cf.constant_pool.get(id)));124}125visitor.visit(cf, m, refInfos);126}127}128return true;129}130131private ConstantPool.Visitor<Boolean,ConstantPool> cpVisitor =132new ConstantPool.Visitor<Boolean,ConstantPool>()133{134public Boolean visitClass(CONSTANT_Class_info info, ConstantPool cpool) {135return false;136}137138public Boolean visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, ConstantPool cpool) {139return filter.accept(cpool, info);140}141142public Boolean visitMethodref(CONSTANT_Methodref_info info, ConstantPool cpool) {143return filter.accept(cpool, info);144}145146public Boolean visitFieldref(CONSTANT_Fieldref_info info, ConstantPool cpool) {147return filter.accept(cpool, info);148}149150public Boolean visitDouble(CONSTANT_Double_info info, ConstantPool cpool) {151return false;152}153154public Boolean visitFloat(CONSTANT_Float_info info, ConstantPool cpool) {155return false;156}157158public Boolean visitInteger(CONSTANT_Integer_info info, ConstantPool cpool) {159return false;160}161162public Boolean visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, ConstantPool cpool) {163return false;164}165166public Boolean visitLong(CONSTANT_Long_info info, ConstantPool cpool) {167return false;168}169170public Boolean visitNameAndType(CONSTANT_NameAndType_info info, ConstantPool cpool) {171return false;172}173174public Boolean visitMethodHandle(CONSTANT_MethodHandle_info info, ConstantPool cpool) {175return false;176}177178public Boolean visitMethodType(CONSTANT_MethodType_info info, ConstantPool cpool) {179return false;180}181182public Boolean visitString(CONSTANT_String_info info, ConstantPool cpool) {183return false;184}185186public Boolean visitUtf8(CONSTANT_Utf8_info info, ConstantPool cpool) {187return false;188}189};190191private Instruction.KindVisitor<Integer, List<Integer>> codeVisitor =192new Instruction.KindVisitor<Integer, List<Integer>>()193{194public Integer visitNoOperands(Instruction instr, List<Integer> p) {195return 0;196}197198public Integer visitArrayType(Instruction instr, TypeKind kind, List<Integer> p) {199return 0;200}201202public Integer visitBranch(Instruction instr, int offset, List<Integer> p) {203return 0;204}205206public Integer visitConstantPoolRef(Instruction instr, int index, List<Integer> p) {207return p.contains(index) ? index : 0;208}209210public Integer visitConstantPoolRefAndValue(Instruction instr, int index, int value, List<Integer> p) {211return p.contains(index) ? index : 0;212}213214public Integer visitLocal(Instruction instr, int index, List<Integer> p) {215return 0;216}217218public Integer visitLocalAndValue(Instruction instr, int index, int value, List<Integer> p) {219return 0;220}221222public Integer visitLookupSwitch(Instruction instr, int default_, int npairs, int[] matches, int[] offsets, List<Integer> p) {223return 0;224}225226public Integer visitTableSwitch(Instruction instr, int default_, int low, int high, int[] offsets, List<Integer> p) {227return 0;228}229230public Integer visitValue(Instruction instr, int value, List<Integer> p) {231return 0;232}233234public Integer visitUnknown(Instruction instr, List<Integer> p) {235return 0;236}237};238}239240241242