Skip to content

Commit 8208c27

Browse files
committed
Fixed anonymous class discovery: Test<String> t = new<String>Test<String>() {}
1 parent 2145db4 commit 8208c27

File tree

2 files changed

+47
-33
lines changed

2 files changed

+47
-33
lines changed

plugins/sources/src/org/graalvm/visualvm/sources/java/JavaClass.java

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -182,46 +182,59 @@ private static List<JavaClass> populateAnonymousClasses(String source, List<Java
182182

183183
String _source = JavaSourceUtils.maskClasses(source, innerClasses);
184184

185-
Pattern pattern = Pattern.compile(JavaSourceUtils.ANONYMOUS_CLASS_REGEX);
186-
Matcher matcher = pattern.matcher(_source);
185+
Pattern pattern = Pattern.compile(JavaSourceUtils.ANONYMOUS_CLASS_START_REGEX);
186+
Matcher startMatcher = pattern.matcher(_source);
187+
Matcher endMatcher = null;
187188

188-
while (startOffset <= endOffset && matcher.find(startOffset)) {
189-
startOffset = matcher.end();
189+
while (startOffset <= endOffset && startMatcher.find(startOffset)) {
190+
startOffset = startMatcher.end();
190191

191192
// Generics
192-
if (_source.charAt(startOffset) == '<') { // NOI18N
193-
startOffset = JavaSourceUtils.skipBlock(_source, startOffset, '<', '>'); // NOI18N
194-
startOffset = JavaSourceUtils.skipWhiteSpaces(_source, startOffset);
193+
if (_source.charAt(startOffset - 1) == '<') { // NOI18N
194+
startOffset = JavaSourceUtils.skipBlock(_source, startOffset - 1, '<', '>'); // NOI18N
195195
}
196196

197-
// Array definition
198-
if (_source.charAt(startOffset) == '[') { // NOI18N
199-
while (_source.charAt(startOffset) == '[' && startOffset < endOffset) // NOI18N
200-
startOffset = JavaSourceUtils.skipBlock(_source, startOffset, '[', ']'); // NOI18N
201-
startOffset = JavaSourceUtils.skipWhiteSpaces(_source, startOffset);
202-
// Anonymous class
203-
} else {
204-
// Not expected
205-
if (_source.charAt(startOffset) != '(') { // NOI18N
206-
// nothing we can do here, just search again
207-
} else {
208-
// TODO do not skipBlock to search the parameters as well
209-
// but the numbering of anonymous classes becomes broken
210-
startOffset = JavaSourceUtils.skipBlock(_source, startOffset, '(', ')'); // NOI18N
197+
if (endMatcher == null) {
198+
pattern = Pattern.compile(JavaSourceUtils.ANONYMOUS_CLASS_END_REGEX);
199+
endMatcher = pattern.matcher(_source);
200+
}
201+
202+
if (endMatcher.find(startOffset)) {
203+
startOffset = endMatcher.end();
204+
205+
// Generics
206+
if (_source.charAt(startOffset) == '<') { // NOI18N
207+
startOffset = JavaSourceUtils.skipBlock(_source, startOffset, '<', '>'); // NOI18N
208+
startOffset = JavaSourceUtils.skipWhiteSpaces(_source, startOffset);
209+
}
210+
211+
// Array definition
212+
if (_source.charAt(startOffset) == '[') { // NOI18N
213+
while (_source.charAt(startOffset) == '[' && startOffset < endOffset) // NOI18N
214+
startOffset = JavaSourceUtils.skipBlock(_source, startOffset, '[', ']'); // NOI18N
211215
startOffset = JavaSourceUtils.skipWhiteSpaces(_source, startOffset);
212-
// Object creation only
213-
if (_source.charAt(startOffset) != '{') { // NOI18N
216+
// Anonymous class
217+
} else {
218+
// Not expected
219+
if (_source.charAt(startOffset) != '(') { // NOI18N
214220
// nothing we can do here, just search again
215-
// Anonymous class
216221
} else {
217-
int nameOffset = JavaSourceUtils.skipWhiteSpaces(_source, matcher.start() + "_new".length()); // NOI18N
218-
219-
int[] bodyOffsets = JavaSourceUtils.getBlockBounds(_source, startOffset, '{', '}'); // NOI18N
220-
if (bodyOffsets[0] == -1 || bodyOffsets[1] == -1 || bodyOffsets[1] > endOffset) break;
221-
222-
classes.add(new JavaClass(Integer.toString(classes.size() + 1), source, nameOffset, bodyOffsets[0], bodyOffsets[1]));
223-
224-
startOffset = bodyOffsets[1] + 1;
222+
// TODO do not skipBlock to search the parameters as well
223+
// but the numbering of anonymous classes becomes broken
224+
startOffset = JavaSourceUtils.skipBlock(_source, startOffset, '(', ')'); // NOI18N
225+
startOffset = JavaSourceUtils.skipWhiteSpaces(_source, startOffset);
226+
// Object creation only
227+
if (_source.charAt(startOffset) != '{') { // NOI18N
228+
// nothing we can do here, just search again
229+
// Anonymous class
230+
} else {
231+
int[] bodyOffsets = JavaSourceUtils.getBlockBounds(_source, startOffset, '{', '}'); // NOI18N
232+
if (bodyOffsets[0] == -1 || bodyOffsets[1] == -1 || bodyOffsets[1] > endOffset) break;
233+
234+
classes.add(new JavaClass(Integer.toString(classes.size() + 1), source, endMatcher.start(JavaSourceUtils.REGEX_GROUP_NAME), bodyOffsets[0], bodyOffsets[1]));
235+
236+
startOffset = bodyOffsets[1] + 1;
237+
}
225238
}
226239
}
227240
}

plugins/sources/src/org/graalvm/visualvm/sources/java/JavaSourceUtils.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ final class JavaSourceUtils {
5555

5656
static final String ANONYMOUS_LOCAL_CLASSNAME_REGEX = "(?<" + REGEX_GROUP_INDEX + ">[\\d]+)(?<" + REGEX_GROUP_NAME + ">[\\D]*)"; // NOI18N
5757
static final String CLASS_REGEX = "(^|[\\W&&[^.]])(class|interface|enum)\\s+(?<" + REGEX_GROUP_NAME + ">" + IDENTIFIER_REGEX + ")[^\\p{javaJavaIdentifierPart}]"; // NOI18N
58-
static final String ANONYMOUS_CLASS_REGEX = "\\Wnew\\s+" + FULLY_QUALIFIED_IDENTIFIER_REGEX + "\\s*"; // NOI18N
58+
static final String ANONYMOUS_CLASS_START_REGEX = "\\Wnew(\\s+|\\s*\\<)"; // NOI18N
59+
static final String ANONYMOUS_CLASS_END_REGEX = "\\G\\s*(?<" + REGEX_GROUP_NAME + ">" + FULLY_QUALIFIED_IDENTIFIER_REGEX + ")\\s*"; // NOI18N
5960

6061
static final String CLASS_INITIALIZER_REGEX = "\\Wstatic\\s*\\{"; // NOI18N
6162
static final String INSTANCE_INITIALIZER_REGEX = "[\\{\\};]\\s*\\{"; // NOI18N

0 commit comments

Comments
 (0)