2015-09-24 20:13:04 +03:00
|
|
|
/*
|
2016-08-19 10:06:30 -04:00
|
|
|
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
2015-09-24 20:13:04 +03:00
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
|
|
* accompanied this code).
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License version
|
|
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*
|
|
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
|
|
* questions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package compiler.compilercontrol.share.method;
|
|
|
|
|
2016-08-19 10:06:30 -04:00
|
|
|
import jdk.test.lib.util.Triple;
|
2015-09-24 20:13:04 +03:00
|
|
|
|
|
|
|
import java.lang.reflect.Executable;
|
|
|
|
import java.util.function.Function;
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Method descriptor for Compiler Control commands.
|
|
|
|
* It represents method pattern used for matching in Compiler Control
|
|
|
|
* and CompileCommand option
|
|
|
|
*/
|
|
|
|
public class MethodDescriptor {
|
|
|
|
public final ClassType aClass; // Represents class and package
|
|
|
|
public final MethodType aMethod; // Represents method
|
|
|
|
public final SignatureType aSignature; // Represents signature
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
|
|
|
* @param method executable to build method descriptor from
|
|
|
|
*/
|
|
|
|
public MethodDescriptor(Executable method) {
|
|
|
|
aClass = new ClassType(method);
|
|
|
|
aMethod = new MethodType(method);
|
|
|
|
aSignature = new SignatureType(method);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets signature separators for all elements
|
|
|
|
*/
|
|
|
|
public void setSeparators(
|
|
|
|
Triple<Separator, Separator, Separator> separators) {
|
|
|
|
aClass.setSeparator(separators.getFirst());
|
|
|
|
aMethod.setSeparator(separators.getSecond());
|
|
|
|
aSignature.setSeparator(separators.getThird());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets custom strings for each element
|
|
|
|
*/
|
|
|
|
public void setStrings(Triple<String, String, String> strings) {
|
|
|
|
aClass.setElement(strings.getFirst());
|
|
|
|
aMethod.setElement(strings.getSecond());
|
|
|
|
aSignature.setElement(strings.getThird());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets patterns for all elements
|
|
|
|
*/
|
|
|
|
public void setPatterns(
|
|
|
|
Triple<PatternType, PatternType, PatternType> patterns) {
|
|
|
|
aClass.setPattern(patterns.getFirst());
|
|
|
|
aMethod.setPattern(patterns.getSecond());
|
|
|
|
aSignature.setPattern(patterns.getThird());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Separates elements in the MethodDescriptor
|
|
|
|
*/
|
|
|
|
public static enum Separator {
|
|
|
|
SLASH("/"),
|
|
|
|
DOT("."),
|
|
|
|
COMMA(","),
|
|
|
|
DOUBLECOLON("::"),
|
|
|
|
SPACE(" "),
|
|
|
|
NONE("");
|
|
|
|
|
|
|
|
public final String symbol;
|
|
|
|
|
|
|
|
Separator(String symbol) {
|
|
|
|
this.symbol = symbol;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Validates method descriptor separators
|
|
|
|
*
|
|
|
|
* @param md method descriptor to validate
|
|
|
|
* @return true if descriptor's separators are valid
|
|
|
|
*/
|
|
|
|
public static boolean isValid(MethodDescriptor md) {
|
|
|
|
Separator cls = md.getClassSeparator();
|
|
|
|
Separator method = md.getMethodSeparator();
|
|
|
|
Separator sign = md.getSignatureSeparator();
|
|
|
|
if (sign == SPACE || sign == NONE || sign == COMMA) {
|
|
|
|
// if it looks like java/lang/String.indexOf
|
|
|
|
if ((cls == SLASH || cls == NONE)
|
|
|
|
// allow space and comma instead of dot
|
|
|
|
&& (method == DOT || method == SPACE
|
|
|
|
|| method == COMMA)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// if it looks like java.lang.String::indexOf
|
|
|
|
if ((cls == DOT || cls == NONE) && method == DOUBLECOLON) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Type of the pattern
|
|
|
|
*/
|
|
|
|
public static enum PatternType {
|
|
|
|
PREFIX,
|
|
|
|
ANY,
|
|
|
|
SUFFIX,
|
|
|
|
SUBSTRING,
|
|
|
|
EXACT
|
|
|
|
}
|
|
|
|
|
|
|
|
public Separator getClassSeparator() {
|
|
|
|
return aClass.getSeparator();
|
|
|
|
}
|
|
|
|
|
|
|
|
public Separator getMethodSeparator() {
|
|
|
|
return aMethod.getSeparator();
|
|
|
|
}
|
|
|
|
|
|
|
|
public Separator getSignatureSeparator() {
|
|
|
|
return aSignature.getSeparator();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets regular expression to match methods
|
|
|
|
*
|
|
|
|
* @return string representation of the regular expression
|
|
|
|
*/
|
|
|
|
public String getRegexp() {
|
|
|
|
// regexp should have a . as a method separator
|
|
|
|
// and / as a package/class separator
|
|
|
|
return aClass.getRegexp().replaceAll("\\.", "/")
|
|
|
|
.replaceAll("/\\*", ".*")
|
|
|
|
+ Pattern.quote(Separator.DOT.symbol)
|
|
|
|
+ aMethod.getRegexp() + aSignature.getRegexp();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets method descriptor string representation.
|
|
|
|
* This string is used as a pattern in CompilerControl and CompileCommand
|
|
|
|
*/
|
|
|
|
public String getString() {
|
|
|
|
return aClass.getElement() + getMethodSeparator().symbol
|
|
|
|
+ aMethod.getElement() + getSignatureSeparator().symbol
|
|
|
|
+ aSignature.getElement();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert method descriptor to be regexp-compatible
|
|
|
|
*
|
|
|
|
* @return string representation of the method signature
|
|
|
|
*/
|
|
|
|
public String getCanonicalString() {
|
|
|
|
return aClass.getElement().replaceAll("\\.", "/") + Separator.DOT.symbol
|
|
|
|
+ aMethod.getElement() + aSignature.getElement();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shows if this descriptor is a valid pattern for CompilerControl
|
|
|
|
*
|
|
|
|
* @return true, if descriptor is valid, false otherwise
|
|
|
|
*/
|
|
|
|
public boolean isValid() {
|
|
|
|
return aClass.isValid() && aMethod.isValid() && aSignature.isValid()
|
|
|
|
&& Separator.isValid(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets custom string from element mutate function
|
|
|
|
* to the appropriate element of method descriptor
|
|
|
|
*/
|
|
|
|
public void applyMutates(Triple<Function<String, String>,
|
|
|
|
Function<String, String>,
|
|
|
|
Function<String, String>> mutators) {
|
|
|
|
String elementString = aClass.getElement();
|
|
|
|
aClass.setElement(mutators.getFirst().apply(elementString));
|
|
|
|
elementString = aMethod.getElement();
|
|
|
|
aMethod.setElement(mutators.getSecond().apply(elementString));
|
|
|
|
elementString = aSignature.getElement();
|
|
|
|
aSignature.setElement(mutators.getThird().apply(elementString));
|
|
|
|
}
|
|
|
|
}
|