mirror of
https://github.com/konsoletyper/teavm.git
synced 2024-11-27 01:30:35 +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 {
|
||||
public final String name;
|
||||
public JCLStatus status;
|
||||
public JCLVisibility visibility = JCLVisibility.PUBLIC;
|
||||
public JCLClassType type;
|
||||
public final List<JCLItem> items = new ArrayList<>();
|
||||
|
||||
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/methpub_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(
|
||||
outputDirectory, "jcl.html")), "UTF-8")) {
|
||||
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 {
|
||||
@ -185,39 +205,108 @@ public class JCLComparisonBuilder {
|
||||
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 ? 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);
|
||||
}
|
||||
|
||||
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 {
|
||||
out.write("<tr class=\"");
|
||||
switch (status) {
|
||||
@ -235,7 +324,13 @@ public class JCLComparisonBuilder {
|
||||
out.write("<td><div class=\"");
|
||||
out.write(type);
|
||||
out.write("\">");
|
||||
if (link != null) {
|
||||
out.write("<a href=\"" + link + "\">");
|
||||
}
|
||||
out.write(escape(name));
|
||||
if (link != null) {
|
||||
out.write("</a>");
|
||||
}
|
||||
out.write("</div></td>\n");
|
||||
out.write("<td class=\"percent\">" + (partialPercent != null ? partialPercent.toString() : "") + "</td>");
|
||||
out.write("<td class=\"percent\">" + (percent != null ? percent.toString() : "") + "</td>");
|
||||
|
@ -56,6 +56,16 @@ class JCLComparisonVisitor implements ClassVisitor {
|
||||
classReader = classSource.get(javaName);
|
||||
jclClass = new JCLClass(simpleName);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -67,6 +77,7 @@ class JCLComparisonVisitor implements ClassVisitor {
|
||||
JCLItem item = new JCLItem(JCLItemType.FIELD, name + " : " + desc);
|
||||
FieldReader field = classReader.getField(name);
|
||||
item.status = field != null ? JCLStatus.FOUND : JCLStatus.MISSING;
|
||||
item.visibility = (access & Opcodes.ACC_PROTECTED) != 0 ? JCLVisibility.PROTECTED : JCLVisibility.PUBLIC;
|
||||
jclClass.items.add(item);
|
||||
if (item.status == JCLStatus.MISSING) {
|
||||
jclClass.status = JCLStatus.PARTIAL;
|
||||
@ -92,6 +103,7 @@ class JCLComparisonVisitor implements ClassVisitor {
|
||||
JCLStatus.FOUND : JCLStatus.PARTIAL;
|
||||
}
|
||||
}
|
||||
item.visibility = (access & Opcodes.ACC_PROTECTED) != 0 ? JCLVisibility.PROTECTED : JCLVisibility.PUBLIC;
|
||||
jclClass.items.add(item);
|
||||
if (item.status == JCLStatus.MISSING) {
|
||||
jclClass.status = JCLStatus.PARTIAL;
|
||||
|
@ -22,6 +22,7 @@ package org.teavm.classlib.impl;
|
||||
class JCLItem {
|
||||
public final JCLItemType type;
|
||||
public final String name;
|
||||
public JCLVisibility visibility = JCLVisibility.PUBLIC;
|
||||
public JCLStatus status;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
.package, .class, .protected-class, .field, .protected-field, .method, .protected-method {
|
||||
.package, .type, .field, .method {
|
||||
background-repeat: no-repeat;
|
||||
padding-right: 6px;
|
||||
}
|
||||
@ -45,11 +45,11 @@ th {
|
||||
padding-left: 35px;
|
||||
background-position: 16px 50%;
|
||||
}
|
||||
.class {
|
||||
.type {
|
||||
padding-left: 51px;
|
||||
background-position: 32px 50%;
|
||||
}
|
||||
.field, .protected-field, .method, .protected-method {
|
||||
.field, .method {
|
||||
padding-left: 67px;
|
||||
background-position: 48px 50%;
|
||||
}
|
||||
@ -60,15 +60,24 @@ th {
|
||||
.class {
|
||||
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 {
|
||||
background-image: url(field_public_obj.png);
|
||||
}
|
||||
.protected-field {
|
||||
.protected.field {
|
||||
background-image: url(field_protected_obj.png);
|
||||
}
|
||||
.method {
|
||||
background-image: url(methpub_obj.png);
|
||||
}
|
||||
.protected-method {
|
||||
.protected.method {
|
||||
background-image: url(methpro_obj.png);
|
||||
}
|
Loading…
Reference in New Issue
Block a user