Skip to content

Commit fbc5b14

Browse files
author
emmanue1
committed
Add Java 9+ module support
1 parent 25b7e53 commit fbc5b14

File tree

14 files changed

+347
-81
lines changed

14 files changed

+347
-81
lines changed

app/src/main/java/org/jd/gui/service/treenode/TreeNodeFactoryService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public TreeNodeFactory get(Container.Entry entry) {
4343
}
4444

4545
protected TreeNodeFactory get(String containerType, Container.Entry entry) {
46-
String path = entry.getPath();;
46+
String path = entry.getPath();
4747
String type = entry.isDirectory() ? "dir" : "file";
4848
String prefix = containerType + ':' + type + ':';
4949
TreeNodeFactory factory = null;

services/src/main/java/org/jd/gui/service/container/JmodContainerFactoryProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public boolean accept(API api, Path rootPath) {
2626
if (rootPath.toUri().toString().toLowerCase().endsWith(".jmod!/")) {
2727
return true;
2828
} else {
29-
// Extension: accept uncompressed WAR file containing a folder 'WEB-INF'
29+
// Extension: accept uncompressed JMOD file containing a folder 'classes'
3030
try {
3131
return rootPath.getFileSystem().provider().getScheme().equals("file") && Files.exists(rootPath.resolve("classes"));
3232
} catch (InvalidPathException e) {

services/src/main/java/org/jd/gui/service/fileloader/AbstractFileLoaderProvider.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ protected <T extends JComponent & UriGettable> T load(API api, File file, Path r
4444
TreeNodeFactory treeNodeFactory = api.getTreeNodeFactory(parentEntry);
4545
Object data = (treeNodeFactory != null) ? treeNodeFactory.make(api, parentEntry).getUserObject() : null;
4646
Icon icon = (data instanceof TreeNodeData) ? ((TreeNodeData)data).getIcon() : null;
47+
String location = file.getPath();
4748

48-
api.addPanel(file.getName(), icon, "Location: " + file.getAbsolutePath(), mainPanel);
49+
api.addPanel(file.getName(), icon, "Location: " + location, mainPanel);
4950
return mainPanel;
5051
}
5152
}

services/src/main/java/org/jd/gui/service/indexer/JavaFileIndexerProvider.java

Lines changed: 60 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -122,43 +122,47 @@ public void enterPackageDeclaration(JavaParser.PackageDeclarationContext ctx) {
122122

123123
protected void enterTypeDeclaration(ParserRuleContext ctx) {
124124
// Add type declaration
125-
String typeName = ctx.getToken(JavaParser.Identifier, 0).getText();
126-
int length = sbTypeDeclaration.length();
125+
TerminalNode identifier = ctx.getToken(JavaParser.Identifier, 0);
127126

128-
if ((length == 0) || (sbTypeDeclaration.charAt(length-1) == '/')) {
129-
sbTypeDeclaration.append(typeName);
130-
} else {
131-
sbTypeDeclaration.append('$').append(typeName);
132-
}
127+
if (identifier != null) {
128+
String typeName = identifier.getText();
129+
int length = sbTypeDeclaration.length();
133130

134-
String internalTypeName = sbTypeDeclaration.toString();
135-
typeDeclarationSet.add(internalTypeName);
136-
nameToInternalTypeName.put(typeName, internalTypeName);
131+
if ((length == 0) || (sbTypeDeclaration.charAt(length - 1) == '/')) {
132+
sbTypeDeclaration.append(typeName);
133+
} else {
134+
sbTypeDeclaration.append('$').append(typeName);
135+
}
137136

138-
HashSet<String> superInternalTypeNameSet = new HashSet<>();
137+
String internalTypeName = sbTypeDeclaration.toString();
138+
typeDeclarationSet.add(internalTypeName);
139+
nameToInternalTypeName.put(typeName, internalTypeName);
139140

140-
// Add super type reference
141-
JavaParser.TypeContext superType = ctx.getRuleContext(JavaParser.TypeContext.class, 0);
142-
if (superType != null) {
143-
String superQualifiedTypeName = resolveInternalTypeName(superType.classOrInterfaceType().Identifier());
141+
HashSet<String> superInternalTypeNameSet = new HashSet<>();
144142

145-
if (superQualifiedTypeName.charAt(0) != '*')
146-
superInternalTypeNameSet.add(superQualifiedTypeName);
147-
}
143+
// Add super type reference
144+
JavaParser.TypeContext superType = ctx.getRuleContext(JavaParser.TypeContext.class, 0);
145+
if (superType != null) {
146+
String superQualifiedTypeName = resolveInternalTypeName(superType.classOrInterfaceType().Identifier());
147+
148+
if (superQualifiedTypeName.charAt(0) != '*')
149+
superInternalTypeNameSet.add(superQualifiedTypeName);
150+
}
148151

149-
// Add implementation references
150-
JavaParser.TypeListContext superInterfaces = ctx.getRuleContext(JavaParser.TypeListContext.class, 0);
151-
if (superInterfaces != null) {
152-
for (JavaParser.TypeContext superInterface : superInterfaces.type()) {
153-
String superQualifiedInterfaceName = resolveInternalTypeName(superInterface.classOrInterfaceType().Identifier());
152+
// Add implementation references
153+
JavaParser.TypeListContext superInterfaces = ctx.getRuleContext(JavaParser.TypeListContext.class, 0);
154+
if (superInterfaces != null) {
155+
for (JavaParser.TypeContext superInterface : superInterfaces.type()) {
156+
String superQualifiedInterfaceName = resolveInternalTypeName(superInterface.classOrInterfaceType().Identifier());
154157

155-
if (superQualifiedInterfaceName.charAt(0) != '*')
156-
superInternalTypeNameSet.add(superQualifiedInterfaceName);
158+
if (superQualifiedInterfaceName.charAt(0) != '*')
159+
superInternalTypeNameSet.add(superQualifiedInterfaceName);
160+
}
157161
}
158-
}
159162

160-
if (! superInternalTypeNameSet.isEmpty()) {
161-
superTypeNamesMap.put(internalTypeName, superInternalTypeNameSet);
163+
if (!superInternalTypeNameSet.isEmpty()) {
164+
superTypeNamesMap.put(internalTypeName, superInternalTypeNameSet);
165+
}
162166
}
163167
}
164168

@@ -197,19 +201,31 @@ public void enterConstDeclaration(JavaParser.ConstDeclarationContext ctx) {
197201

198202
public void enterFieldDeclaration(JavaParser.FieldDeclarationContext ctx) {
199203
for (JavaParser.VariableDeclaratorContext declaration : ctx.variableDeclarators().variableDeclarator()) {
200-
String name = declaration.variableDeclaratorId().Identifier().getText();
201-
fieldDeclarationSet.add(name);
204+
TerminalNode identifier = declaration.variableDeclaratorId().Identifier();
205+
206+
if (identifier != null) {
207+
String name = identifier.getText();
208+
fieldDeclarationSet.add(name);
209+
}
202210
}
203211
}
204212

205213
public void enterMethodDeclaration(JavaParser.MethodDeclarationContext ctx) {
206-
String name = ctx.Identifier().getText();
207-
methodDeclarationSet.add(name);
214+
TerminalNode identifier = ctx.Identifier();
215+
216+
if (identifier != null) {
217+
String name = identifier.getText();
218+
methodDeclarationSet.add(name);
219+
}
208220
}
209221

210222
public void enterInterfaceMethodDeclaration(JavaParser.InterfaceMethodDeclarationContext ctx) {
211-
String name = ctx.Identifier().getText();
212-
methodDeclarationSet.add(name);
223+
TerminalNode identifier = ctx.Identifier();
224+
225+
if (identifier != null) {
226+
String name = identifier.getText();
227+
methodDeclarationSet.add(name);
228+
}
213229
}
214230

215231
public void enterConstructorDeclaration(JavaParser.ConstructorDeclarationContext ctx) {
@@ -282,15 +298,18 @@ protected TerminalNode getToken(List<ParseTree> children, int i, int type) {
282298
protected TerminalNode getRightTerminalNode(ParseTree pt) {
283299
if (pt instanceof ParserRuleContext) {
284300
List<ParseTree> children = ((ParserRuleContext)pt).children;
285-
int size = children.size();
286301

287-
if (size > 0) {
288-
ParseTree last = children.get(size - 1);
302+
if (children != null) {
303+
int size = children.size();
289304

290-
if (last instanceof TerminalNode) {
291-
return (TerminalNode) last;
292-
} else {
293-
return getRightTerminalNode(last);
305+
if (size > 0) {
306+
ParseTree last = children.get(size - 1);
307+
308+
if (last instanceof TerminalNode) {
309+
return (TerminalNode) last;
310+
} else {
311+
return getRightTerminalNode(last);
312+
}
294313
}
295314
}
296315
}

services/src/main/java/org/jd/gui/service/treenode/ClassFileTreeNodeFactoryProvider.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.io.File;
2222
import java.io.IOException;
2323
import java.io.InputStream;
24+
import java.util.regex.Pattern;
2425

2526
public class ClassFileTreeNodeFactoryProvider extends AbstractTypeFileTreeNodeFactoryProvider {
2627
protected static final ImageIcon CLASS_FILE_ICON = new ImageIcon(ClassFileTreeNodeFactoryProvider.class.getClassLoader().getResource("org/jd/gui/images/classf_obj.png"));
@@ -37,6 +38,15 @@ public class ClassFileTreeNodeFactoryProvider extends AbstractTypeFileTreeNodeFa
3738

3839
@Override public String[] getSelectors() { return appendSelectors("*:file:*.class"); }
3940

41+
@Override
42+
public Pattern getPathPattern() {
43+
if (externalPathPattern == null) {
44+
return Pattern.compile("^((?!module-info\\.class).)*$");
45+
} else {
46+
return externalPathPattern;
47+
}
48+
}
49+
4050
@Override
4151
@SuppressWarnings("unchecked")
4252
public <T extends DefaultMutableTreeNode & ContainerEntryGettable & UriGettable> T make(API api, Container.Entry entry) {

services/src/main/java/org/jd/gui/service/treenode/JavaFileTreeNodeFactoryProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ public <T extends JComponent & UriGettable> T makePage(API a, Container.Entry e)
4343

4444
@Override
4545
public String makeTip(API api, Container.Entry entry) {
46-
File file = new File(entry.getContainer().getRoot().getUri());
46+
String location = new File(entry.getUri()).getPath();
4747
StringBuilder tip = new StringBuilder("<html>Location: ");
4848

49-
tip.append(file.getPath());
49+
tip.append(location);
5050
tip.append("</html>");
5151

5252
return tip.toString();
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) 2008-2019 Emmanuel Dupuy.
3+
* This project is distributed under the GPLv3 license.
4+
* This is a Copyleft license that gives the user the right to use,
5+
* copy and modify the code freely for non-commercial purposes.
6+
*/
7+
8+
package org.jd.gui.service.treenode;
9+
10+
import org.jd.gui.api.API;
11+
import org.jd.gui.api.feature.ContainerEntryGettable;
12+
import org.jd.gui.api.feature.UriGettable;
13+
import org.jd.gui.api.model.Container;
14+
import org.jd.gui.util.exception.ExceptionUtil;
15+
import org.jd.gui.view.component.ModuleInfoFilePage;
16+
import org.jd.gui.view.data.TreeNodeBean;
17+
18+
import javax.swing.*;
19+
import javax.swing.tree.DefaultMutableTreeNode;
20+
import java.io.File;
21+
import java.util.regex.Pattern;
22+
23+
public class ModuleInfoFileTreeNodeFactoryProvider extends ClassFileTreeNodeFactoryProvider {
24+
protected static final Factory FACTORY = new Factory();
25+
26+
static {
27+
// Early class loading
28+
try {
29+
Class.forName(ModuleInfoFilePage.class.getName());
30+
} catch (Exception e) {
31+
assert ExceptionUtil.printStackTrace(e);
32+
}
33+
}
34+
35+
@Override public String[] getSelectors() { return appendSelectors("*:file:*/module-info.class"); }
36+
37+
@Override public Pattern getPathPattern() { return externalPathPattern; }
38+
39+
@Override
40+
@SuppressWarnings("unchecked")
41+
public <T extends DefaultMutableTreeNode & ContainerEntryGettable & UriGettable> T make(API api, Container.Entry entry) {
42+
int lastSlashIndex = entry.getPath().lastIndexOf('/');
43+
String label = entry.getPath().substring(lastSlashIndex+1);
44+
return (T)new FileTreeNode(entry, new TreeNodeBean(label, CLASS_FILE_ICON), FACTORY);
45+
}
46+
47+
protected static class Factory implements AbstractTypeFileTreeNodeFactoryProvider.PageAndTipFactory {
48+
// --- PageAndTipFactory --- //
49+
@Override
50+
@SuppressWarnings("unchecked")
51+
public <T extends JComponent & UriGettable> T makePage(API a, Container.Entry e) {
52+
return (T)new ModuleInfoFilePage(a, e);
53+
}
54+
55+
@Override
56+
public String makeTip(API api, Container.Entry entry) {
57+
String location = new File(entry.getUri()).getPath();
58+
StringBuilder tip = new StringBuilder("<html>Location: ");
59+
60+
tip.append(location);
61+
tip.append("</html>");
62+
63+
return tip.toString();
64+
}
65+
}
66+
}

services/src/main/java/org/jd/gui/util/parser/antlr/AbstractJavaListener.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ protected String resolveInternalTypeName(List<TerminalNode> identifiers) {
114114
typeNameCache.put(name, qualifiedName);
115115
return qualifiedName;
116116
}
117-
} catch (ClassNotFoundException e) {
118-
assert ExceptionUtil.printStackTrace(e);
117+
} catch (ClassNotFoundException ignore) {
118+
// Ignore class loading error
119119
}
120120

121121
// Type not found

services/src/main/java/org/jd/gui/view/component/AbstractTextPage.java

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -171,23 +171,21 @@ public void setCaretPositionAndCenter(DocumentRange range) {
171171

172172
if (!foldsExpanded) {
173173
try {
174-
Rectangle r = textArea.modelToView(start);
174+
Rectangle rec = textArea.modelToView(start);
175175

176-
if (r != null) {
176+
if (rec != null) {
177177
// Visible
178-
setCaretPositionAndCenter(start, end, r);
178+
setCaretPositionAndCenter(start, end, rec);
179179
} else {
180180
// Not visible yet
181-
SwingUtilities.invokeLater(new Runnable() {
182-
public void run() {
183-
try {
184-
Rectangle r = textArea.modelToView(start);
185-
if (r != null) {
186-
setCaretPositionAndCenter(start, end, r);
187-
}
188-
} catch (BadLocationException e) {
189-
assert ExceptionUtil.printStackTrace(e);
181+
SwingUtilities.invokeLater(() -> {
182+
try {
183+
Rectangle r = textArea.modelToView(start);
184+
if (r != null) {
185+
setCaretPositionAndCenter(start, end, r);
190186
}
187+
} catch (BadLocationException e) {
188+
assert ExceptionUtil.printStackTrace(e);
191189
}
192190
});
193191
}

services/src/main/java/org/jd/gui/view/component/ClassFilePage.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ public void decompile(Map<String, String> preferences) {
8484

8585
// Decompile class file
8686
DECOMPILER.decompile(loader, printer, entryInternalName, configuration);
87-
setText(printer.getStringBuffer().toString());
8887
} catch (Throwable t) {
8988
assert ExceptionUtil.printStackTrace(t);
9089
setText("// INTERNAL ERROR //");
@@ -154,6 +153,11 @@ public void start(int maxLineNumber, int majorVersion, int minorVersion) {
154153
}
155154
}
156155

156+
@Override
157+
public void end() {
158+
setText(stringBuffer.toString());
159+
}
160+
157161
// --- Add strings --- //
158162
@Override
159163
public void printStringConstant(String constant, String ownerInternalName) {

0 commit comments

Comments
 (0)