Path: blob/master/test/hotspot/jtreg/compiler/compilercontrol/share/method/MethodDescriptor.java
41161 views
/*1* Copyright (c) 2015, 2016, 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.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223package compiler.compilercontrol.share.method;2425import jdk.test.lib.util.Triple;2627import java.lang.reflect.Executable;28import java.util.function.Function;29import java.util.regex.Pattern;3031/**32* Method descriptor for Compiler Control commands.33* It represents method pattern used for matching in Compiler Control34* and CompileCommand option35*/36public class MethodDescriptor {37public final ClassType aClass; // Represents class and package38public final MethodType aMethod; // Represents method39public final SignatureType aSignature; // Represents signature4041/**42* Constructor43*44* @param method executable to build method descriptor from45*/46public MethodDescriptor(Executable method) {47aClass = new ClassType(method);48aMethod = new MethodType(method);49aSignature = new SignatureType(method);50}5152/**53* Sets signature separators for all elements54*/55public void setSeparators(56Triple<Separator, Separator, Separator> separators) {57aClass.setSeparator(separators.getFirst());58aMethod.setSeparator(separators.getSecond());59aSignature.setSeparator(separators.getThird());60}6162/**63* Sets custom strings for each element64*/65public void setStrings(Triple<String, String, String> strings) {66aClass.setElement(strings.getFirst());67aMethod.setElement(strings.getSecond());68aSignature.setElement(strings.getThird());69}7071/**72* Sets patterns for all elements73*/74public void setPatterns(75Triple<PatternType, PatternType, PatternType> patterns) {76aClass.setPattern(patterns.getFirst());77aMethod.setPattern(patterns.getSecond());78aSignature.setPattern(patterns.getThird());79}8081/**82* Separates elements in the MethodDescriptor83*/84public static enum Separator {85SLASH("/"),86DOT("."),87COMMA(","),88DOUBLECOLON("::"),89SPACE(" "),90NONE("");9192public final String symbol;9394Separator(String symbol) {95this.symbol = symbol;96}9798/**99* Validates method descriptor separators100*101* @param md method descriptor to validate102* @return true if descriptor's separators are valid103*/104public static boolean isValid(MethodDescriptor md) {105Separator cls = md.getClassSeparator();106Separator method = md.getMethodSeparator();107Separator sign = md.getSignatureSeparator();108if (sign == SPACE || sign == NONE || sign == COMMA) {109// if it looks like java/lang/String.indexOf110if ((cls == SLASH || cls == NONE)111// allow space and comma instead of dot112&& (method == DOT || method == SPACE113|| method == COMMA)) {114return true;115}116// if it looks like java.lang.String::indexOf117if ((cls == DOT || cls == NONE) && method == DOUBLECOLON) {118return true;119}120}121return false;122}123}124125/**126* Type of the pattern127*/128public static enum PatternType {129PREFIX,130ANY,131SUFFIX,132SUBSTRING,133EXACT134}135136public Separator getClassSeparator() {137return aClass.getSeparator();138}139140public Separator getMethodSeparator() {141return aMethod.getSeparator();142}143144public Separator getSignatureSeparator() {145return aSignature.getSeparator();146}147148/**149* Gets regular expression to match methods150*151* @return string representation of the regular expression152*/153public String getRegexp() {154// regexp should have a . as a method separator155// and / as a package/class separator156return aClass.getRegexp().replaceAll("\\.", "/")157.replaceAll("/\\*", ".*")158+ Pattern.quote(Separator.DOT.symbol)159+ aMethod.getRegexp() + aSignature.getRegexp();160}161162/**163* Gets method descriptor string representation.164* This string is used as a pattern in CompilerControl and CompileCommand165*/166public String getString() {167return aClass.getElement() + getMethodSeparator().symbol168+ aMethod.getElement() + getSignatureSeparator().symbol169+ aSignature.getElement();170}171172/**173* Convert method descriptor to be regexp-compatible174*175* @return string representation of the method signature176*/177public String getCanonicalString() {178return aClass.getElement().replaceAll("\\.", "/") + Separator.DOT.symbol179+ aMethod.getElement() + aSignature.getElement();180}181182/**183* Shows if this descriptor is a valid pattern for CompilerControl184*185* @return true, if descriptor is valid, false otherwise186*/187public boolean isValid() {188return aClass.isValid() && aMethod.isValid() && aSignature.isValid()189&& Separator.isValid(this);190}191192/**193* Sets custom string from element mutate function194* to the appropriate element of method descriptor195*/196public void applyMutates(Triple<Function<String, String>,197Function<String, String>,198Function<String, String>> mutators) {199String elementString = aClass.getElement();200aClass.setElement(mutators.getFirst().apply(elementString));201elementString = aMethod.getElement();202aMethod.setElement(mutators.getSecond().apply(elementString));203elementString = aSignature.getElement();204aSignature.setElement(mutators.getThird().apply(elementString));205}206}207208209