From da314bf6f245a30fcbadd2b9eb357ae712e7b783 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Thu, 6 Mar 2014 10:47:20 +0400 Subject: [PATCH] Makes JCL compatibility report to be more usable --- .../org/teavm/classlib/impl/JCLClass.java | 2 + .../org/teavm/classlib/impl/JCLClassType.java | 27 ++++ .../classlib/impl/JCLComparisonBuilder.java | 149 ++++++++++++++---- .../classlib/impl/JCLComparisonVisitor.java | 12 ++ .../java/org/teavm/classlib/impl/JCLItem.java | 1 + .../teavm/classlib/impl/JCLVisibility.java | 25 +++ .../main/resources/html/annotation_obj.png | Bin 0 -> 481 bytes .../src/main/resources/html/enum_obj.png | Bin 0 -> 513 bytes .../src/main/resources/html/int_obj.png | Bin 0 -> 745 bytes .../src/main/resources/html/jcl-class.html | 22 +++ .../src/main/resources/html/jcl-test.html | 46 ------ .../src/main/resources/html/jcl.css | 19 ++- 12 files changed, 225 insertions(+), 78 deletions(-) create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLClassType.java create mode 100644 teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLVisibility.java create mode 100644 teavm-classlib/src/main/resources/html/annotation_obj.png create mode 100644 teavm-classlib/src/main/resources/html/enum_obj.png create mode 100644 teavm-classlib/src/main/resources/html/int_obj.png create mode 100644 teavm-classlib/src/main/resources/html/jcl-class.html delete mode 100644 teavm-classlib/src/main/resources/html/jcl-test.html diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLClass.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLClass.java index a77f5d789..2391d1369 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLClass.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLClass.java @@ -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 items = new ArrayList<>(); public JCLClass(String name) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLClassType.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLClassType.java new file mode 100644 index 000000000..813ce8d74 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLClassType.java @@ -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 +} diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLComparisonBuilder.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLComparisonBuilder.java index d87005972..648872328 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLComparisonBuilder.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLComparisonBuilder.java @@ -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 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("
"); + if (link != null) { + out.write(""); + } out.write(escape(name)); + if (link != null) { + out.write(""); + } out.write("
\n"); out.write("" + (partialPercent != null ? partialPercent.toString() : "") + ""); out.write("" + (percent != null ? percent.toString() : "") + ""); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLComparisonVisitor.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLComparisonVisitor.java index 09b218461..816ae6e36 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLComparisonVisitor.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLComparisonVisitor.java @@ -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; diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLItem.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLItem.java index 8fa689343..471b9d16b 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLItem.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLItem.java @@ -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) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLVisibility.java b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLVisibility.java new file mode 100644 index 000000000..56be51ad0 --- /dev/null +++ b/teavm-classlib/src/main/java/org/teavm/classlib/impl/JCLVisibility.java @@ -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 +} diff --git a/teavm-classlib/src/main/resources/html/annotation_obj.png b/teavm-classlib/src/main/resources/html/annotation_obj.png new file mode 100644 index 0000000000000000000000000000000000000000..e1b272b2ee1a8574c247ea19b64bec0d78d7ba9e GIT binary patch literal 481 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMffdHQn*U0JxF4ZZOgG7% zWtKbJJa@KB`9jxsv9YaPo@2Rl8RoID6#M?Nit9 z=TBZyKYvsI<`c7bpPRYu`1aG+-+leL_u}nOKYoAx_2=`?-`AeMyz%1I({Eos|Niy= z|9_yh)CJWC9_zT|{U040URYf$yT~eL1RJAnnmRZY+=ib(~v8yWEK6w|%*Zn+M|AQ&-i8Mn_3hOzb PqZmA0{an^LB{Ts5i!;Tr literal 0 HcmV?d00001 diff --git a/teavm-classlib/src/main/resources/html/enum_obj.png b/teavm-classlib/src/main/resources/html/enum_obj.png new file mode 100644 index 0000000000000000000000000000000000000000..5e96f5e393580a6010cf6b6e44e6270be4c7d20c GIT binary patch literal 513 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMffdHQn*Pcj)z8IChSk?YmwFzld0vUj{8HBiW$p{h zJr|ALumV0h_>LZJ=tyk|4ie zpk9&ygZwN%MWANJByV>Yd%I+VQXq%3z$3C4NPB>>+sSM@AY-nli(`ny<<|b!d`$*C zZtPkHAIvVik_bNNd-U|K@AXzMn+*SbQt_QN*)0C_pN7@fZ>}o4Qe`&ftO>)5BYlVb z&htANOShc9CDy5~(s#s9v-QWT-;0BIJC{xn`lz%tC&5!`rb}Ri<^z3UfW7Q}7H zk6l-ku(2?HLviB9(v*!AXJ9es9 zm+a}R+TT{OySsLOSIxe@hJy>Io>{l_(#{RH&K!FZ=eIC3a?QG>SN?+m&}%~uczu4P z4|KFkNswPK#1|Bi4275ag@EQUCV9KN)O+kNd%QQTfirty7dy(08#15mYBv-${ws8Gnp?@W)zh5fO5RPm y?6*#T>e&g;e_ohkzg#@?e)*q+->1v}>o(tLXQX;oeWeu8^$eb_elF{r5}E)GekA(< literal 0 HcmV?d00001 diff --git a/teavm-classlib/src/main/resources/html/jcl-class.html b/teavm-classlib/src/main/resources/html/jcl-class.html new file mode 100644 index 000000000..5847fc957 --- /dev/null +++ b/teavm-classlib/src/main/resources/html/jcl-class.html @@ -0,0 +1,22 @@ + + + + JCL emulation information - ${CLASSNAME} + + + + + + + + + + + + + + ${CONTENT} + +
Item% of partially implemented% of fully implemented
+ + \ No newline at end of file diff --git a/teavm-classlib/src/main/resources/html/jcl-test.html b/teavm-classlib/src/main/resources/html/jcl-test.html deleted file mode 100644 index 715af11f5..000000000 --- a/teavm-classlib/src/main/resources/html/jcl-test.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - JCL emulation information - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Item% of partially implemented% of fully implemented
java.lang
100%0%
Object
50%
$id
clone()
getClass()
- - \ No newline at end of file diff --git a/teavm-classlib/src/main/resources/html/jcl.css b/teavm-classlib/src/main/resources/html/jcl.css index 3106bc5a0..00e67f58c 100644 --- a/teavm-classlib/src/main/resources/html/jcl.css +++ b/teavm-classlib/src/main/resources/html/jcl.css @@ -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); } \ No newline at end of file