Skip to content

Commit 5337fde

Browse files
committed
svm: use signature hash for storing @BasedOnJDKFile infos to disk
1 parent 7268248 commit 5337fde

File tree

1 file changed

+81
-4
lines changed

1 file changed

+81
-4
lines changed

substratevm/src/com.oracle.svm.processor/src/com/oracle/svm/processor/BasedOnJDKFileProcessor.java

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
import java.io.PrintWriter;
3434
import java.net.URLEncoder;
3535
import java.nio.charset.StandardCharsets;
36+
import java.security.MessageDigest;
37+
import java.security.NoSuchAlgorithmException;
3638
import java.util.HashSet;
3739
import java.util.List;
3840
import java.util.Objects;
@@ -50,6 +52,8 @@
5052
import javax.lang.model.element.PackageElement;
5153
import javax.lang.model.element.TypeElement;
5254
import javax.lang.model.element.VariableElement;
55+
import javax.lang.model.type.ArrayType;
56+
import javax.lang.model.type.TypeMirror;
5357
import javax.tools.Diagnostic.Kind;
5458
import javax.tools.FileObject;
5559
import javax.tools.StandardLocation;
@@ -135,10 +139,14 @@ private void processAnnotation(Element annotatedElement, AnnotationMirror annota
135139
return;
136140
}
137141

138-
String qualifiedName = getQualifiedName(annotatedElement);
142+
String qualifiedShortName = getQualifiedName(annotatedElement);
143+
String qualifiedSignature = getQualifiedSignature(annotatedElement);
144+
String simpleName = getSimpleName(annotatedElement);
145+
String qualifiedName = qualifiedShortName + qualifiedSignature;
146+
String qualifiedNameHash = byteArrayToHexString(sha256encode(qualifiedName));
139147

140148
Element[] originatingElements = new Element[]{annotatedElement};
141-
String uniqueName = getUniqueName(qualifiedName, targetSourceInfo.committish, targetSourceInfo.path, targetSourceInfo.lineStart, targetSourceInfo.lineEnd);
149+
String uniqueName = getUniqueName(qualifiedName, qualifiedNameHash, simpleName, targetSourceInfo.committish, targetSourceInfo.path, targetSourceInfo.lineStart, targetSourceInfo.lineEnd);
142150

143151
String filename = "jdk_source_info/" + URLEncoder.encode(uniqueName, StandardCharsets.UTF_8) + ".json";
144152
SourceInfo annotatedSourceInfo = getAnnotatedSourceInfo(annotatedElement);
@@ -164,6 +172,23 @@ private void processAnnotation(Element annotatedElement, AnnotationMirror annota
164172
}
165173
}
166174

175+
private static byte[] sha256encode(String text) {
176+
try {
177+
MessageDigest digest = MessageDigest.getInstance("SHA-256");
178+
return digest.digest(text.getBytes(StandardCharsets.UTF_8));
179+
} catch (NoSuchAlgorithmException e) {
180+
throw new RuntimeException(e);
181+
}
182+
}
183+
184+
private static String byteArrayToHexString(byte[] a) {
185+
StringBuilder sb = new StringBuilder(a.length * 2);
186+
for (byte b : a) {
187+
sb.append(String.format("%02x", b));
188+
}
189+
return sb.toString();
190+
}
191+
167192
private static String getQualifiedName(Element annotatedElement) {
168193
if (annotatedElement instanceof TypeElement typeElement) {
169194
return typeElement.getQualifiedName().toString();
@@ -182,6 +207,52 @@ private static String getQualifiedName(Element annotatedElement) {
182207
throw new RuntimeException("Unexpected element class: " + annotatedElement.getClass().getSimpleName());
183208
}
184209

210+
private static String getSimpleName(Element annotatedElement) {
211+
if (annotatedElement instanceof ExecutableElement executableElement) {
212+
TypeElement enclosingElement = (TypeElement) executableElement.getEnclosingElement();
213+
String simpleName = executableElement.getSimpleName().toString();
214+
if ("<init>".equals(simpleName)) {
215+
// constructor
216+
return enclosingElement.getSimpleName().toString();
217+
}
218+
return enclosingElement.getSimpleName().toString() + "#" + simpleName;
219+
}
220+
return null;
221+
}
222+
223+
private static String getQualifiedSignature(Element annotatedElement) {
224+
if (annotatedElement instanceof ExecutableElement executableElement) {
225+
return getMethodDescriptor(executableElement);
226+
}
227+
return "";
228+
}
229+
230+
private static String getDescriptorForClass(TypeMirror c) {
231+
return switch (c.getKind()) {
232+
case BOOLEAN -> "Z";
233+
case BYTE -> "B";
234+
case CHAR -> "C";
235+
case SHORT -> "S";
236+
case INT -> "I";
237+
case LONG -> "J";
238+
case FLOAT -> "F";
239+
case DOUBLE -> "D";
240+
case VOID -> "V";
241+
case ARRAY -> "[" + getDescriptorForClass(((ArrayType) c).getComponentType());
242+
case DECLARED -> "L" + c.toString().replace('.', '/') + ";";
243+
default -> throw new RuntimeException("Unexpected null type: " + c);
244+
};
245+
}
246+
247+
private static String getMethodDescriptor(ExecutableElement m) {
248+
String s = "(";
249+
for (var parameter : m.getParameters()) {
250+
s += getDescriptorForClass(parameter.asType());
251+
}
252+
s += ')';
253+
return s + getDescriptorForClass(m.getReturnType());
254+
}
255+
185256
private SourceInfo parseBasedOnJDKFileAnnotation(String annotationValue) {
186257
Matcher blobMatcher = BLOB_PATTERN.matcher(annotationValue);
187258
if (blobMatcher.matches()) {
@@ -228,9 +299,15 @@ private SourceInfo getAnnotatedSourceInfo(Element annotatedElement) {
228299
return new SourceInfo(null, sourceFileName, lineMap.getLineNumber(start), lineMap.getLineNumber(end));
229300
}
230301

231-
private static String getUniqueName(String qualifiedName, String committish, String path, long lineStart, long lineEnd) {
302+
private static String getUniqueName(String qualifiedName, String qualifiedNameHash, String simpleName, String committish, String path, long lineStart, long lineEnd) {
232303
String strippedPath = path.charAt(path.length() - 1) == '/' ? path.substring(0, path.length() - 1) : path;
233-
return String.format("%s/%s/%s-%s/%s", committish, strippedPath, lineStart, lineEnd, qualifiedName);
304+
if (simpleName == null) {
305+
// packages, classes
306+
return String.format("%s/%s/%s-%s/%s", committish, strippedPath, lineStart, lineEnd, qualifiedName);
307+
} else {
308+
// methods, ctors
309+
return String.format("%s/%s/%s-%s/%s_%s", committish, strippedPath, lineStart, lineEnd, simpleName, qualifiedNameHash);
310+
}
234311
}
235312

236313
private static void printSourceInfo(PrintWriter writer, SourceInfo annotatedSourceInfo, String indent) {

0 commit comments

Comments
 (0)