mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Makes JCL compatibility report to be more usable
This commit is contained in:
parent
43b41b3a66
commit
da314bf6f2
|
@ -25,6 +25,8 @@ import java.util.List;
|
||||||
class JCLClass {
|
class JCLClass {
|
||||||
public final String name;
|
public final String name;
|
||||||
public JCLStatus status;
|
public JCLStatus status;
|
||||||
|
public JCLVisibility visibility = JCLVisibility.PUBLIC;
|
||||||
|
public JCLClassType type;
|
||||||
public final List<JCLItem> items = new ArrayList<>();
|
public final List<JCLItem> items = new ArrayList<>();
|
||||||
|
|
||||||
public JCLClass(String name) {
|
public JCLClass(String name) {
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.classlib.impl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
enum JCLClassType {
|
||||||
|
CLASS,
|
||||||
|
INTERFACE,
|
||||||
|
ENUM,
|
||||||
|
ANNOTATION
|
||||||
|
}
|
|
@ -87,10 +87,30 @@ public class JCLComparisonBuilder {
|
||||||
copyResource("html/methpro_obj.png");
|
copyResource("html/methpro_obj.png");
|
||||||
copyResource("html/methpub_obj.png");
|
copyResource("html/methpub_obj.png");
|
||||||
copyResource("html/package_obj.png");
|
copyResource("html/package_obj.png");
|
||||||
|
copyResource("html/int_obj.png");
|
||||||
|
copyResource("html/enum_obj.png");
|
||||||
try (Writer out = new OutputStreamWriter(new FileOutputStream(new File(
|
try (Writer out = new OutputStreamWriter(new FileOutputStream(new File(
|
||||||
outputDirectory, "jcl.html")), "UTF-8")) {
|
outputDirectory, "jcl.html")), "UTF-8")) {
|
||||||
generateHtml(out, packages);
|
generateHtml(out, packages);
|
||||||
}
|
}
|
||||||
|
File packagesDirectory = new File(outputDirectory, "packages");
|
||||||
|
packagesDirectory.mkdirs();
|
||||||
|
for (JCLPackage pkg : packages) {
|
||||||
|
File file = new File(packagesDirectory, pkg.name + ".html");
|
||||||
|
try (Writer out = new OutputStreamWriter(new FileOutputStream(file))) {
|
||||||
|
generatePackageHtml(out, pkg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
File classesDirectory = new File(outputDirectory, "classes");
|
||||||
|
classesDirectory.mkdirs();
|
||||||
|
for (JCLPackage pkg : packages) {
|
||||||
|
for (JCLClass cls : pkg.classes) {
|
||||||
|
File file = new File(classesDirectory, pkg.name + "." + cls.name + ".html");
|
||||||
|
try (Writer out = new OutputStreamWriter(new FileOutputStream(file))) {
|
||||||
|
generateClassHtml(out, pkg, cls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<JCLPackage> buildModel() throws IOException {
|
private List<JCLPackage> buildModel() throws IOException {
|
||||||
|
@ -185,39 +205,108 @@ public class JCLComparisonBuilder {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writeRow(out, "package", pkg.status, pkg.name,
|
writeRow(out, "package", "packages/" + pkg.name + ".html", pkg.status, pkg.name,
|
||||||
totalClasses > 0 ? fullClasses * 100 / totalClasses : null,
|
totalClasses > 0 ? fullClasses * 100 / totalClasses : null,
|
||||||
totalClasses > 0 ? partialClasses * 100 / totalClasses : null);
|
totalClasses > 0 ? partialClasses * 100 / totalClasses : null);
|
||||||
for (JCLClass cls : pkg.classes) {
|
|
||||||
int implemented = 0;
|
|
||||||
for (JCLItem item : cls.items) {
|
|
||||||
if (item.status != JCLStatus.MISSING) {
|
|
||||||
++implemented;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writeRow(out, "class", cls.status, cls.name,
|
|
||||||
!cls.items.isEmpty() ? implemented * 100 / cls.items.size() : null, null);
|
|
||||||
for (JCLItem item : cls.items) {
|
|
||||||
String type;
|
|
||||||
switch (item.type) {
|
|
||||||
case FIELD:
|
|
||||||
type = "field";
|
|
||||||
break;
|
|
||||||
case METHOD:
|
|
||||||
type = "method";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
type = "";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
writeRow(out, type, item.status, item.name, null, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
out.write(footer);
|
out.write(footer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeRow(Writer out, String type, JCLStatus status, String name, Integer percent,
|
private void generatePackageHtml(Writer out, JCLPackage pkg) throws IOException {
|
||||||
|
String template;
|
||||||
|
try (Reader reader = new InputStreamReader(classLoader.getResourceAsStream("html/jcl-class.html"), "UTF-8")) {
|
||||||
|
template = IOUtils.toString(reader);
|
||||||
|
}
|
||||||
|
template = template.replace("${CLASSNAME}", pkg.name);
|
||||||
|
int placeholderIndex = template.indexOf(TEMPLATE_PLACEHOLDER);
|
||||||
|
String header = template.substring(0, placeholderIndex);
|
||||||
|
String footer = template.substring(placeholderIndex + TEMPLATE_PLACEHOLDER.length());
|
||||||
|
out.write(header);
|
||||||
|
int totalClasses = pkg.classes.size();
|
||||||
|
int fullClasses = 0;
|
||||||
|
int partialClasses = 0;
|
||||||
|
for (JCLClass cls : pkg.classes) {
|
||||||
|
switch (cls.status) {
|
||||||
|
case FOUND:
|
||||||
|
fullClasses++;
|
||||||
|
partialClasses++;
|
||||||
|
break;
|
||||||
|
case PARTIAL:
|
||||||
|
partialClasses++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeRow(out, "package", null, pkg.status, pkg.name,
|
||||||
|
totalClasses > 0 ? fullClasses * 100 / totalClasses : null,
|
||||||
|
totalClasses > 0 ? partialClasses * 100 / totalClasses : null);
|
||||||
|
for (JCLClass cls : pkg.classes) {
|
||||||
|
writeClassRow(out, pkg, cls);
|
||||||
|
}
|
||||||
|
out.write(footer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateClassHtml(Writer out, JCLPackage pkg, JCLClass cls) throws IOException {
|
||||||
|
String template;
|
||||||
|
try (Reader reader = new InputStreamReader(classLoader.getResourceAsStream("html/jcl-class.html"), "UTF-8")) {
|
||||||
|
template = IOUtils.toString(reader);
|
||||||
|
}
|
||||||
|
template = template.replace("${CLASSNAME}", pkg.name + "." + cls.name);
|
||||||
|
int placeholderIndex = template.indexOf(TEMPLATE_PLACEHOLDER);
|
||||||
|
String header = template.substring(0, placeholderIndex);
|
||||||
|
String footer = template.substring(placeholderIndex + TEMPLATE_PLACEHOLDER.length());
|
||||||
|
out.write(header);
|
||||||
|
writeRow(out, "package", null, pkg.status, pkg.name, null, null);
|
||||||
|
writeClassRow(out, pkg, cls);
|
||||||
|
for (JCLItem item : cls.items) {
|
||||||
|
String type;
|
||||||
|
switch (item.type) {
|
||||||
|
case FIELD:
|
||||||
|
type = "field";
|
||||||
|
break;
|
||||||
|
case METHOD:
|
||||||
|
type = "method";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
type = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (item.visibility == JCLVisibility.PROTECTED) {
|
||||||
|
type = "protected " + type;
|
||||||
|
}
|
||||||
|
writeRow(out, type, null, item.status, item.name, null, null);
|
||||||
|
}
|
||||||
|
out.write(footer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeClassRow(Writer out, JCLPackage pkg, JCLClass cls) throws IOException {
|
||||||
|
int implemented = 0;
|
||||||
|
for (JCLItem item : cls.items) {
|
||||||
|
if (item.status != JCLStatus.MISSING) {
|
||||||
|
++implemented;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String type;
|
||||||
|
switch (cls.type) {
|
||||||
|
case INTERFACE:
|
||||||
|
type = "interface";
|
||||||
|
break;
|
||||||
|
case ANNOTATION:
|
||||||
|
type = "annotation";
|
||||||
|
break;
|
||||||
|
case ENUM:
|
||||||
|
type = "enum";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
type = "class";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
writeRow(out, type + " type", "../classes/" + pkg.name + "." + cls.name + ".html", cls.status, cls.name,
|
||||||
|
!cls.items.isEmpty() ? implemented * 100 / cls.items.size() : null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeRow(Writer out, String type, String link, JCLStatus status, String name, Integer percent,
|
||||||
Integer partialPercent) throws IOException {
|
Integer partialPercent) throws IOException {
|
||||||
out.write("<tr class=\"");
|
out.write("<tr class=\"");
|
||||||
switch (status) {
|
switch (status) {
|
||||||
|
@ -235,7 +324,13 @@ public class JCLComparisonBuilder {
|
||||||
out.write("<td><div class=\"");
|
out.write("<td><div class=\"");
|
||||||
out.write(type);
|
out.write(type);
|
||||||
out.write("\">");
|
out.write("\">");
|
||||||
|
if (link != null) {
|
||||||
|
out.write("<a href=\"" + link + "\">");
|
||||||
|
}
|
||||||
out.write(escape(name));
|
out.write(escape(name));
|
||||||
|
if (link != null) {
|
||||||
|
out.write("</a>");
|
||||||
|
}
|
||||||
out.write("</div></td>\n");
|
out.write("</div></td>\n");
|
||||||
out.write("<td class=\"percent\">" + (partialPercent != null ? partialPercent.toString() : "") + "</td>");
|
out.write("<td class=\"percent\">" + (partialPercent != null ? partialPercent.toString() : "") + "</td>");
|
||||||
out.write("<td class=\"percent\">" + (percent != null ? percent.toString() : "") + "</td>");
|
out.write("<td class=\"percent\">" + (percent != null ? percent.toString() : "") + "</td>");
|
||||||
|
|
|
@ -56,6 +56,16 @@ class JCLComparisonVisitor implements ClassVisitor {
|
||||||
classReader = classSource.get(javaName);
|
classReader = classSource.get(javaName);
|
||||||
jclClass = new JCLClass(simpleName);
|
jclClass = new JCLClass(simpleName);
|
||||||
jclClass.status = classReader != null ? JCLStatus.FOUND : JCLStatus.MISSING;
|
jclClass.status = classReader != null ? JCLStatus.FOUND : JCLStatus.MISSING;
|
||||||
|
jclClass.visibility = (access & Opcodes.ACC_PROTECTED) != 0 ? JCLVisibility.PROTECTED : JCLVisibility.PUBLIC;
|
||||||
|
if ((access & Opcodes.ACC_INTERFACE) != 0) {
|
||||||
|
jclClass.type = JCLClassType.INTERFACE;
|
||||||
|
} else if ((access & Opcodes.ACC_ANNOTATION) != 0) {
|
||||||
|
jclClass.type = JCLClassType.ANNOTATION;
|
||||||
|
} else if ((access & Opcodes.ACC_ENUM) != 0) {
|
||||||
|
jclClass.type = JCLClassType.ENUM;
|
||||||
|
} else {
|
||||||
|
jclClass.type = JCLClassType.CLASS;
|
||||||
|
}
|
||||||
jclPackage.classes.add(jclClass);
|
jclPackage.classes.add(jclClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +77,7 @@ class JCLComparisonVisitor implements ClassVisitor {
|
||||||
JCLItem item = new JCLItem(JCLItemType.FIELD, name + " : " + desc);
|
JCLItem item = new JCLItem(JCLItemType.FIELD, name + " : " + desc);
|
||||||
FieldReader field = classReader.getField(name);
|
FieldReader field = classReader.getField(name);
|
||||||
item.status = field != null ? JCLStatus.FOUND : JCLStatus.MISSING;
|
item.status = field != null ? JCLStatus.FOUND : JCLStatus.MISSING;
|
||||||
|
item.visibility = (access & Opcodes.ACC_PROTECTED) != 0 ? JCLVisibility.PROTECTED : JCLVisibility.PUBLIC;
|
||||||
jclClass.items.add(item);
|
jclClass.items.add(item);
|
||||||
if (item.status == JCLStatus.MISSING) {
|
if (item.status == JCLStatus.MISSING) {
|
||||||
jclClass.status = JCLStatus.PARTIAL;
|
jclClass.status = JCLStatus.PARTIAL;
|
||||||
|
@ -92,6 +103,7 @@ class JCLComparisonVisitor implements ClassVisitor {
|
||||||
JCLStatus.FOUND : JCLStatus.PARTIAL;
|
JCLStatus.FOUND : JCLStatus.PARTIAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
item.visibility = (access & Opcodes.ACC_PROTECTED) != 0 ? JCLVisibility.PROTECTED : JCLVisibility.PUBLIC;
|
||||||
jclClass.items.add(item);
|
jclClass.items.add(item);
|
||||||
if (item.status == JCLStatus.MISSING) {
|
if (item.status == JCLStatus.MISSING) {
|
||||||
jclClass.status = JCLStatus.PARTIAL;
|
jclClass.status = JCLStatus.PARTIAL;
|
||||||
|
|
|
@ -22,6 +22,7 @@ package org.teavm.classlib.impl;
|
||||||
class JCLItem {
|
class JCLItem {
|
||||||
public final JCLItemType type;
|
public final JCLItemType type;
|
||||||
public final String name;
|
public final String name;
|
||||||
|
public JCLVisibility visibility = JCLVisibility.PUBLIC;
|
||||||
public JCLStatus status;
|
public JCLStatus status;
|
||||||
|
|
||||||
public JCLItem(JCLItemType type, String name) {
|
public JCLItem(JCLItemType type, String name) {
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.classlib.impl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
enum JCLVisibility {
|
||||||
|
PUBLIC,
|
||||||
|
PROTECTED
|
||||||
|
}
|
BIN
teavm-classlib/src/main/resources/html/annotation_obj.png
Normal file
BIN
teavm-classlib/src/main/resources/html/annotation_obj.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 481 B |
BIN
teavm-classlib/src/main/resources/html/enum_obj.png
Normal file
BIN
teavm-classlib/src/main/resources/html/enum_obj.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 513 B |
BIN
teavm-classlib/src/main/resources/html/int_obj.png
Normal file
BIN
teavm-classlib/src/main/resources/html/int_obj.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 745 B |
22
teavm-classlib/src/main/resources/html/jcl-class.html
Normal file
22
teavm-classlib/src/main/resources/html/jcl-class.html
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>JCL emulation information - ${CLASSNAME}</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
||||||
|
<link rel="stylesheet" href="../jcl.css" type="text/css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Item</th>
|
||||||
|
<th>% of partially implemented</th>
|
||||||
|
<th>% of fully implemented</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
${CONTENT}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1,46 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>JCL emulation information</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
|
|
||||||
<link rel="stylesheet" href="jcl.css" type="text/css"/>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Item</th>
|
|
||||||
<th>% of partially implemented</th>
|
|
||||||
<th>% of fully implemented</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr class="full">
|
|
||||||
<td><div class="package">java.lang</div></td>
|
|
||||||
<td class="percent">100%</td>
|
|
||||||
<td class="percent">0%</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="partial">
|
|
||||||
<td><div class="class">Object</div></td>
|
|
||||||
<td class="percent"></td>
|
|
||||||
<td class="percent">50%</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="full">
|
|
||||||
<td><div class="field">$id</div></td>
|
|
||||||
<td class="percent"></td>
|
|
||||||
<td class="percent"></td>
|
|
||||||
</tr>
|
|
||||||
<tr class="full">
|
|
||||||
<td><div class="method">clone()</div></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr class="missing">
|
|
||||||
<td><div class="method">getClass()</div></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -36,7 +36,7 @@ th {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.package, .class, .protected-class, .field, .protected-field, .method, .protected-method {
|
.package, .type, .field, .method {
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
padding-right: 6px;
|
padding-right: 6px;
|
||||||
}
|
}
|
||||||
|
@ -45,11 +45,11 @@ th {
|
||||||
padding-left: 35px;
|
padding-left: 35px;
|
||||||
background-position: 16px 50%;
|
background-position: 16px 50%;
|
||||||
}
|
}
|
||||||
.class {
|
.type {
|
||||||
padding-left: 51px;
|
padding-left: 51px;
|
||||||
background-position: 32px 50%;
|
background-position: 32px 50%;
|
||||||
}
|
}
|
||||||
.field, .protected-field, .method, .protected-method {
|
.field, .method {
|
||||||
padding-left: 67px;
|
padding-left: 67px;
|
||||||
background-position: 48px 50%;
|
background-position: 48px 50%;
|
||||||
}
|
}
|
||||||
|
@ -60,15 +60,24 @@ th {
|
||||||
.class {
|
.class {
|
||||||
background-image: url(class_obj.png);
|
background-image: url(class_obj.png);
|
||||||
}
|
}
|
||||||
|
.annotation {
|
||||||
|
background-image: url(annotation_obj.png);
|
||||||
|
}
|
||||||
|
.interface {
|
||||||
|
background-image: url(int_obj.png);
|
||||||
|
}
|
||||||
|
.enum {
|
||||||
|
background-image: url(enum_obj.png);
|
||||||
|
}
|
||||||
.field {
|
.field {
|
||||||
background-image: url(field_public_obj.png);
|
background-image: url(field_public_obj.png);
|
||||||
}
|
}
|
||||||
.protected-field {
|
.protected.field {
|
||||||
background-image: url(field_protected_obj.png);
|
background-image: url(field_protected_obj.png);
|
||||||
}
|
}
|
||||||
.method {
|
.method {
|
||||||
background-image: url(methpub_obj.png);
|
background-image: url(methpub_obj.png);
|
||||||
}
|
}
|
||||||
.protected-method {
|
.protected.method {
|
||||||
background-image: url(methpro_obj.png);
|
background-image: url(methpro_obj.png);
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user