All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.adoptopenjdk.jitwatch.model.MemberSignatureParts Maven / Gradle / Ivy
/*
* Copyright (c) 2013-2016 Chris Newland.
* Licensed under https://github.com/AdoptOpenJDK/jitwatch/blob/master/LICENSE-BSD
* Instructions: https://github.com/AdoptOpenJDK/jitwatch/wiki
*/
package org.adoptopenjdk.jitwatch.model;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_CLOSE_ANGLE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_COMMA;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_DOT;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_NEWLINE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_OPEN_ANGLE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_QUESTION;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_SPACE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.DEBUG_LOGGING;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.DEBUG_LOGGING_ASSEMBLY;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_BYTECODE_STATIC_INITIALISER_SIGNATURE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_CLOSE_PARENTHESES;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_COMMA;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_CONSTRUCTOR_INIT;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_DOT;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_EMPTY;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_ENTITY_APOS;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_OPEN_PARENTHESES;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_QUOTE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_SLASH;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_SPACE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_STATIC_INIT;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.adoptopenjdk.jitwatch.model.bytecode.ClassBC;
import org.adoptopenjdk.jitwatch.util.ParseUtil;
import org.adoptopenjdk.jitwatch.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MemberSignatureParts
{
private String fullyQualifiedClassName;
private int modifier;
private List modifierList;
private Map genericsMap;
private String returnType;
private String memberName;
private List paramTypeList;
private ClassBC classBytecode;
private static final Pattern PATTERN_ASSEMBLY_SIGNATURE = Pattern.compile("^(.*)\\s'(.*)'\\s'(\\(.*\\))(.*)'\\sin\\s'(.*)'");
private static final Logger logger = LoggerFactory.getLogger(MemberSignatureParts.class);
// LinkedHashMap to ensure entry set iteration matches insertion order
private static final Map modifierMap = new LinkedHashMap();
static
{
addModifierMapping(Modifier.PUBLIC);
addModifierMapping(Modifier.PROTECTED);
addModifierMapping(Modifier.PRIVATE);
addModifierMapping(Modifier.ABSTRACT);
addModifierMapping(Modifier.STATIC);
addModifierMapping(Modifier.FINAL);
addModifierMapping(Modifier.SYNCHRONIZED);
addModifierMapping(Modifier.NATIVE);
addModifierMapping(Modifier.STRICT);
}
private static void addModifierMapping(int modifier)
{
modifierMap.put(Modifier.toString(modifier), modifier);
}
private MemberSignatureParts()
{
modifierList = new ArrayList<>();
genericsMap = new LinkedHashMap<>(); // preserve order
paramTypeList = new ArrayList<>();
modifier = 0;
}
// TODO really???
public void setClassBC(ClassBC classBytecode)
{
this.classBytecode = classBytecode;
}
private static void completeSignature(String origSig, MemberSignatureParts msp)
{
if (msp.memberName != null)
{
// Constructors will return void for returnType
if (S_CONSTRUCTOR_INIT.equals(msp.memberName) || msp.memberName.equals(msp.fullyQualifiedClassName))
{
msp.memberName = StringUtil.getUnqualifiedClassName(msp.fullyQualifiedClassName);
msp.returnType = Void.TYPE.getName();
if (DEBUG_LOGGING)
{
logger.debug("Found constructor: {} ", msp.memberName);
}
}
}
else
{
if (DEBUG_LOGGING)
{
logger.debug("MemberSignatureParts.memberName was null for signature: '{}'\n{}", origSig, msp);
}
}
}
public static MemberSignatureParts fromParts(String fullyQualifiedClassName, String memberName, String returnType,
List paramTypes)
{
MemberSignatureParts msp = new MemberSignatureParts();
msp.fullyQualifiedClassName = fullyQualifiedClassName;
msp.memberName = memberName;
msp.paramTypeList.addAll(paramTypes);
msp.returnType = returnType;
completeSignature(fullyQualifiedClassName + S_COMMA + memberName + S_COMMA + returnType, msp);
return msp;
}
public static MemberSignatureParts fromLogCompilationSignature(String toParse) throws LogParseException
{
MemberSignatureParts msp = new MemberSignatureParts();
String[] parts = ParseUtil.splitLogSignatureWithRegex(toParse);
msp.fullyQualifiedClassName = parts[0];
msp.memberName = parts[1];
String paramTypes = parts[2];
String returnType = parts[3];
setParamsAndReturn(msp, paramTypes, returnType);
completeSignature(toParse, msp);
return msp;
}
private static boolean isStaticInitialiser(String bytecodeSignature)
{
boolean isClinit = false;
if (bytecodeSignature != null && bytecodeSignature.startsWith(S_BYTECODE_STATIC_INITIALISER_SIGNATURE))
{
isClinit = true;
}
return isClinit;
}
// TODO unit test me!
public static MemberSignatureParts fromBytecodeComment(String toParse) throws LogParseException
{
String logCompilationSignature = ParseUtil.bytecodeCommentSignatureToLogCompilationSignature(toParse);
return fromLogCompilationSignature(logCompilationSignature);
}
public static MemberSignatureParts fromBytecodeSignature(String fqClassName, String toParse)
{
MemberSignatureParts msp = new MemberSignatureParts();
msp.fullyQualifiedClassName = fqClassName;
if (isStaticInitialiser(toParse))
{
msp.memberName = S_STATIC_INIT;
msp.returnType = Void.TYPE.getName();
return msp;
}
StringBuilder builder = new StringBuilder();
builder.append("^[ ]*");
for (String mod : modifierMap.keySet())
{
builder.append(S_OPEN_PARENTHESES).append(mod).append(S_SPACE).append(S_CLOSE_PARENTHESES).append(C_QUESTION);
}
String regexGenerics = "(<[\\p{L}0-9_\\.\\$\\ ,/]+> )?";
String regexReturnType = "(.* )?"; // optional could be constructor
String regexMethodName = ParseUtil.METHOD_NAME_REGEX_GROUP;
String regexParams = "(\\(.*\\))";
String regexRest = "(.*)";
builder.append(regexGenerics);
builder.append(regexReturnType);
builder.append(regexMethodName);
builder.append(regexParams);
builder.append(regexRest);
// logger.info("\n{}\n{}", toParse, builder);
final Pattern patternBytecodeSignature = Pattern.compile(builder.toString());
Matcher matcher = patternBytecodeSignature.matcher(toParse);
int modifierCount = modifierMap.size();
if (matcher.find())
{
int count = matcher.groupCount();
for (int i = 1; i < count; i++)
{
String group = matcher.group(i);
if (group != null)
{
group = group.trim();
}
if (group != null && i <= modifierCount)
{
msp.modifierList.add(group);
// add bitset value for this modifier
msp.modifier += modifierMap.get(group);
}
if (i == modifierCount + 1)
{
if (group != null)
{
msp.buildGenerics(group);
}
}
if (i == modifierCount + 2)
{
if (group != null)
{
msp.returnType = group;
}
}
if (i == modifierCount + 3)
{
if (group != null)
{
msp.memberName = group;
}
}
if (i == modifierCount + 4)
{
if (group != null)
{
msp.buildParamTypes(group);
}
}
}
}
completeSignature(toParse, msp);
return msp;
}
public static MemberSignatureParts fromAssembly(final String toParse) throws LogParseException
{
MemberSignatureParts msp = new MemberSignatureParts();
String line = toParse.replace(S_ENTITY_APOS, S_QUOTE);
Matcher matcher = PATTERN_ASSEMBLY_SIGNATURE.matcher(line);
if (matcher.find())
{
if (DEBUG_LOGGING_ASSEMBLY)
{
for (int i = 0; i < matcher.groupCount(); i++)
{
logger.debug("part[{}] = '{}'", i, matcher.group(i));
}
}
String memberName = matcher.group(2);
String paramTypes = matcher.group(3).replace(S_OPEN_PARENTHESES, S_EMPTY).replace(S_CLOSE_PARENTHESES, S_EMPTY);
String returnType = matcher.group(4);
String className = matcher.group(5).replace(S_SLASH, S_DOT);
msp.memberName = memberName;
msp.fullyQualifiedClassName = className;
setParamsAndReturn(msp, paramTypes, returnType);
}
completeSignature(toParse, msp);
return msp;
}
private static void setParamsAndReturn(MemberSignatureParts msp, String paramTypes, String returnType) throws LogParseException
{
Class>[] paramClasses = ParseUtil.getClassTypes(paramTypes);
Class>[] returnClasses = ParseUtil.getClassTypes(returnType);
Class> returnClass;
if (returnClasses.length == 1)
{
returnClass = returnClasses[0];
}
else
{
returnClass = Void.class;
}
for (Class> paramClass : paramClasses)
{
msp.paramTypeList.add(paramClass.getName());
}
msp.returnType = returnClass.getName();
}
private void buildGenerics(String genericsString)
{
String stripped = genericsString.substring(1, genericsString.length() - 1);
String[] substitutions = stripped.split(S_COMMA);
for (String sub : substitutions)
{
sub = sub.replace(S_SLASH, S_DOT); // in package names
if (sub.contains(" extends "))
{
String[] pair = sub.split(" extends ");
String child = pair[0].trim();
String parent = pair[1].trim();
genericsMap.put(child, parent);
}
else
{
genericsMap.put(sub, null);
}
}
}
private void buildParamTypes(String paramString)
{
int angleBracketDepth = 0;
String stripped = paramString.substring(1, paramString.length() - 1);
if (stripped.length() > 0)
{
StringBuilder paramBuilder = new StringBuilder();
for (int i = 0; i < stripped.length(); i++)
{
char c = stripped.charAt(i);
if (c == C_COMMA)
{
if (angleBracketDepth == 0)
{
// finished param
addParam(paramBuilder);
}
else
{
paramBuilder.append(c);
}
}
else if (c == C_OPEN_ANGLE)
{
angleBracketDepth++;
paramBuilder.append(c);
}
else if (c == C_CLOSE_ANGLE)
{
angleBracketDepth--;
paramBuilder.append(c);
}
else
{
paramBuilder.append(c);
}
}
// last param
addParam(paramBuilder);
}
}
private void addParam(StringBuilder paramBuilder)
{
String param = paramBuilder.toString().trim();
int lastSpacePos = param.lastIndexOf(C_SPACE);
if (lastSpacePos != -1)
{
boolean first = true;
boolean validParamName = true;
// check every character after space to see if valid Java identifier
for (int i = lastSpacePos + 1; i < param.length(); i++)
{
char c = param.charAt(i);
if (first && !Character.isJavaIdentifierStart(c))
{
validParamName = false;
break;
}
else if (!Character.isJavaIdentifierPart(c))
{
validParamName = false;
break;
}
first = false;
}
if (validParamName)
{
param = param.substring(0, lastSpacePos);
}
}
paramTypeList.add(param);
paramBuilder.delete(0, paramBuilder.length());
}
public int getModifier()
{
return modifier;
}
public List getModifiers()
{
return modifierList;
}
public Map getGenerics()
{
return genericsMap;
}
public String getReturnType()
{
return returnType;
}
public String applyGenericSubstitutionsForClassLoading(final String typeName)
{
String result = typeName;
if (typeName != null)
{
if (genericsMap.containsKey(typeName))
{
result = genericsMap.get(typeName);
}
else if (classBytecode != null && classBytecode.getGenericsMap().containsKey(typeName))
{
result = classBytecode.getGenericsMap().get(typeName);
}
}
return result;
}
public String getMemberName()
{
return memberName;
}
public List getParamTypes()
{
return paramTypeList;
}
public String getFullyQualifiedClassName()
{
return fullyQualifiedClassName;
}
public String getPackageName()
{
return StringUtil.getAbbreviatedFQName(getFullyQualifiedClassName());
}
@Override
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("modifiers : ");
if (modifierList.size() > 0)
{
for (String mod : modifierList)
{
sb.append(mod).append(C_COMMA);
}
sb.deleteCharAt(sb.length() - 1);
}
sb.append(C_NEWLINE);
sb.append("generics : ");
if (genericsMap.size() > 0)
{
for (Map.Entry entry : genericsMap.entrySet())
{
if (entry.getValue() != null)
{
sb.append(entry.getKey()).append("=>").append(entry.getValue());
}
else
{
sb.append(entry.getKey());
}
sb.append(C_COMMA);
}
sb.deleteCharAt(sb.length() - 1);
}
sb.append(C_NEWLINE);
sb.append("class : ").append(fullyQualifiedClassName).append(C_NEWLINE);
sb.append("returnType: ").append(returnType).append(C_NEWLINE);
sb.append("memberName: ").append(memberName).append(C_NEWLINE);
sb.append("paramTypes: ");
if (paramTypeList.size() > 0)
{
for (String param : paramTypeList)
{
sb.append(param).append(C_COMMA);
}
sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
}
public String toStringSingleLine()
{
StringBuilder sb = new StringBuilder();
sb.append(fullyQualifiedClassName).append(C_DOT).append(memberName).append(S_OPEN_PARENTHESES);
if (paramTypeList.size() > 0)
{
for (String param : paramTypeList)
{
sb.append(param).append(C_COMMA);
}
sb.deleteCharAt(sb.length() - 1);
}
sb.append(S_CLOSE_PARENTHESES);
return sb.toString();
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((fullyQualifiedClassName == null) ? 0 : fullyQualifiedClassName.hashCode());
result = prime * result + ((genericsMap == null) ? 0 : genericsMap.hashCode());
result = prime * result + ((memberName == null) ? 0 : memberName.hashCode());
result = prime * result + modifier;
result = prime * result + ((modifierList == null) ? 0 : modifierList.hashCode());
result = prime * result + ((paramTypeList == null) ? 0 : paramTypeList.hashCode());
result = prime * result + ((returnType == null) ? 0 : returnType.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
MemberSignatureParts other = (MemberSignatureParts) obj;
if (fullyQualifiedClassName == null)
{
if (other.fullyQualifiedClassName != null)
{
return false;
}
}
else if (!fullyQualifiedClassName.equals(other.fullyQualifiedClassName))
{
return false;
}
if (genericsMap == null)
{
if (other.genericsMap != null)
{
return false;
}
}
else if (!genericsMap.equals(other.genericsMap))
{
return false;
}
if (memberName == null)
{
if (other.memberName != null)
{
return false;
}
}
else if (!memberName.equals(other.memberName))
{
return false;
}
if (modifier != other.modifier)
{
return false;
}
if (modifierList == null)
{
if (other.modifierList != null)
{
return false;
}
}
else if (!modifierList.equals(other.modifierList))
{
return false;
}
if (paramTypeList == null)
{
if (other.paramTypeList != null)
{
return false;
}
}
else if (!paramTypeList.equals(other.paramTypeList))
{
return false;
}
if (returnType == null)
{
if (other.returnType != null)
{
return false;
}
}
else if (!returnType.equals(other.returnType))
{
return false;
}
return true;
}
}