One step toward further minification

This commit is contained in:
Alexey Andreev 2015-02-12 19:08:44 +04:00
parent 727c02381a
commit 54ecf6e00f
9 changed files with 261 additions and 150 deletions

View File

@ -36,27 +36,18 @@ public class ObjectEnrichRenderer implements RendererListener {
} }
@Override @Override
public void beforeClass(ClassReader cls) throws IOException { public void complete() throws IOException {
} ClassReader cls = context.getClassSource().get("java.lang.Object");
MethodReader toString = cls.getMethod(new MethodDescriptor("toString", String.class));
@Override if (toString != null) {
public void afterClass(ClassReader cls) throws IOException { String clsName = context.getNaming().getNameFor(cls.getName());
if (cls.getName().equals("java.lang.Object")) { String toStringName = context.getNaming().getNameFor(toString.getReference());
MethodReader toString = cls.getMethod(new MethodDescriptor("toString", String.class)); context.getWriter().append(clsName).append(".prototype.toString").ws().append('=').ws()
if (toString != null) { .append("function()").ws().append('{').indent().softNewLine();
String clsName = context.getNaming().getNameFor(cls.getName()); context.getWriter().append("return this.").append(toStringName).ws().append('?').ws()
String toStringName = context.getNaming().getNameFor(toString.getReference()); .append("$rt_ustr(this.").append(toStringName).append("())").ws().append(':')
context.getWriter().append(clsName).append(".prototype.toString").ws().append('=').ws() .append("Object.prototype.toString.call(this);").softNewLine();
.append("function()").ws().append('{').indent().softNewLine(); context.getWriter().outdent().append("}").newLine();
context.getWriter().append("return this.").append(toStringName).ws().append('?').ws()
.append("$rt_ustr(this.").append(toStringName).append("())").ws().append(':')
.append("Object.prototype.toString.call(this);").softNewLine();
context.getWriter().outdent().append("}").newLine();
}
} }
} }
@Override
public void complete() throws IOException {
}
} }

View File

@ -205,7 +205,9 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
boolean added = true; boolean added = true;
if (callLocation != null && callLocation.getMethod() != null) { if (callLocation != null && callLocation.getMethod() != null) {
DefaultCallGraphNode callGraphNode = callGraph.getNode(callLocation.getMethod()); DefaultCallGraphNode callGraphNode = callGraph.getNode(callLocation.getMethod());
added = addClassAccess(callGraphNode, className, callLocation.getSourceLocation()); if (!addClassAccess(callGraphNode, className, callLocation.getSourceLocation())) {
added = false;
}
} }
if (!dep.isMissing() && added) { if (!dep.isMissing() && added) {
for (DependencyListener listener : listeners) { for (DependencyListener listener : listeners) {
@ -222,13 +224,13 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent {
ClassReader cls = classSource.get(className); ClassReader cls = classSource.get(className);
if (cls != null) { if (cls != null) {
if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) { if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) {
return addClassAccess(node, cls.getParent(), loc); addClassAccess(node, cls.getParent(), loc);
} }
for (String iface : cls.getInterfaces()) { for (String iface : cls.getInterfaces()) {
return addClassAccess(node, iface, loc); addClassAccess(node, iface, loc);
} }
} }
return false; return true;
} }
private ClassDependency createClassDependency(String className) { private ClassDependency createClassDependency(String className) {

View File

@ -349,6 +349,7 @@ class DependencyGraphBuilder {
@Override @Override
public void create(VariableReader receiver, String type) { public void create(VariableReader receiver, String type) {
dependencyChecker.linkClass(type, new CallLocation(caller.getMethod(), currentLocation));
nodes[receiver.getIndex()].propagate(dependencyChecker.getType(type)); nodes[receiver.getIndex()].propagate(dependencyChecker.getType(type));
} }
@ -427,8 +428,9 @@ class DependencyGraphBuilder {
private void invokeSpecial(VariableReader receiver, VariableReader instance, MethodReference method, private void invokeSpecial(VariableReader receiver, VariableReader instance, MethodReference method,
List<? extends VariableReader> arguments) { List<? extends VariableReader> arguments) {
MethodDependency methodDep = dependencyChecker.linkMethod(method, CallLocation callLocation = new CallLocation(caller.getMethod(), currentLocation);
new CallLocation(caller.getMethod(), currentLocation)); dependencyChecker.linkClass(method.getClassName(), callLocation).initClass(callLocation);
MethodDependency methodDep = dependencyChecker.linkMethod(method, callLocation);
if (methodDep.isMissing()) { if (methodDep.isMissing()) {
return; return;
} }
@ -494,14 +496,14 @@ class DependencyGraphBuilder {
@Override @Override
public void monitorEnter(VariableReader objectRef) { public void monitorEnter(VariableReader objectRef) {
dependencyChecker.linkMethod( dependencyChecker.linkMethod(
new MethodReference(Object.class, "monitorEnter", Object.class, void.class), new MethodReference(Object.class, "monitorEnter", Object.class, void.class),
new CallLocation(caller.getMethod(), currentLocation)).use(); new CallLocation(caller.getMethod(), currentLocation)).use();
} }
@Override @Override
public void monitorExit(VariableReader objectRef) { public void monitorExit(VariableReader objectRef) {
dependencyChecker.linkMethod( dependencyChecker.linkMethod(
new MethodReference(Object.class, "monitorExit", Object.class, void.class), new MethodReference(Object.class, "monitorExit", Object.class, void.class),
new CallLocation(caller.getMethod(), currentLocation)).use(); new CallLocation(caller.getMethod(), currentLocation)).use();
} }
}; };

View File

@ -270,8 +270,18 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
writer.append("function $rt_objcls() { return ").appendClass("java.lang.Object").append("; }").newLine(); writer.append("function $rt_objcls() { return ").appendClass("java.lang.Object").append("; }").newLine();
} }
public void render(ClassNode cls) throws RenderingException { public void render(List<ClassNode> classes) throws RenderingException {
debugEmitter.emitClass(cls.getName()); for (ClassNode cls : classes) {
renderDeclaration(cls);
}
for (ClassNode cls : classes) {
renderMethodBodies(cls);
}
renderClassMetadata(classes);
renderMethodStubs(classes);
}
private void renderDeclaration(ClassNode cls) throws RenderingException {
debugEmitter.addClass(cls.getName(), cls.getParentName()); debugEmitter.addClass(cls.getName(), cls.getParentName());
try { try {
writer.append("function ").appendClass(cls.getName()).append("()").ws().append("{") writer.append("function ").appendClass(cls.getName()).append("()").ws().append("{")
@ -306,52 +316,30 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
writer.appendClass(cls.getName()).append('.').appendField(fieldRef).ws().append("=").ws() writer.appendClass(cls.getName()).append('.').appendField(fieldRef).ws().append("=").ws()
.append(constantToString(value)).append(";").softNewLine(); .append(constantToString(value)).append(";").softNewLine();
} }
} catch (NamingException e) {
throw new RenderingException("Error rendering class " + cls.getName() + ". See a cause for details", e);
} catch (IOException e) {
throw new RenderingException("IO error occured", e);
}
}
private void renderMethodBodies(ClassNode cls) throws RenderingException {
debugEmitter.emitClass(cls.getName());
try {
List<MethodNode> nonInitMethods = new ArrayList<>(); List<MethodNode> nonInitMethods = new ArrayList<>();
List<MethodNode> virtualMethods = new ArrayList<>(); List<MethodNode> virtualMethods = new ArrayList<>();
MethodHolder clinit = classSource.get(cls.getName()).getMethod( MethodHolder clinit = classSource.get(cls.getName()).getMethod(
new MethodDescriptor("<clinit>", ValueType.VOID)); new MethodDescriptor("<clinit>", ValueType.VOID));
List<String> stubNames = new ArrayList<>();
List<MethodNode> clinitMethods = new ArrayList<>(); List<MethodNode> clinitMethods = new ArrayList<>();
for (MethodNode method : cls.getMethods()) { for (MethodNode method : cls.getMethods()) {
if (!method.getModifiers().contains(NodeModifier.STATIC) && if (clinit == null || (!method.getModifiers().contains(NodeModifier.STATIC) &&
!method.getReference().getName().equals("<init>")) { !method.getReference().getName().equals("<init>"))) {
nonInitMethods.add(method); nonInitMethods.add(method);
} else { } else {
clinitMethods.add(method); clinitMethods.add(method);
stubNames.add(naming.getFullNameFor(method.getReference()));
} }
} }
boolean needsClinit = clinit != null || !clinitMethods.isEmpty(); boolean needsClinit = clinit != null;
writer.append("$rt_declClass(").appendClass(cls.getName()).append(",").ws().append("{")
.indent().softNewLine();
writer.append("name").ws().append(":").ws().append("\"").append(escapeString(cls.getName()))
.append("\"");
if (cls.getModifiers().contains(NodeModifier.ENUM)) {
writer.append(",").softNewLine().append("enum").ws().append(":").ws().append("true");
}
if (!cls.getInterfaces().isEmpty()) {
writer.append(",").softNewLine().append("interfaces").ws().append(":").ws().append("[");
for (int i = 0; i < cls.getInterfaces().size(); ++i) {
String iface = cls.getInterfaces().get(i);
if (i > 0) {
writer.append(",").ws();
}
writer.appendClass(iface);
}
writer.append("]");
}
if (cls.getParentName() != null) {
writer.append(",").softNewLine();
writer.append("superclass").ws().append(":").ws().appendClass(cls.getParentName());
}
if (!cls.getModifiers().contains(NodeModifier.INTERFACE) && needsClinit) {
writer.append(",").softNewLine().append("clinit").ws().append(":").ws()
.append("function()").ws().append("{").ws()
.appendClass(cls.getName()).append("_$clinit();").ws().append("}");
}
writer.ws().append("});").newLine().outdent();
if (needsClinit) { if (needsClinit) {
writer.append("function ").appendClass(cls.getName()).append("_$clinit()").ws() writer.append("function ").appendClass(cls.getName()).append("_$clinit()").ws()
@ -380,23 +368,11 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
renderStaticDeclaration(method); renderStaticDeclaration(method);
} }
} }
if (stubNames.size() > 0) {
writer.append("$rt_methodStubs(").appendClass(cls.getName()).append("_$clinit")
.append(",").ws().append("[");
for (int i = 0; i < stubNames.size(); ++i) {
if (i > 0) {
writer.append(",").ws();
}
writer.append("'").append(stubNames.get(i)).append("'");
}
writer.append("]);").newLine();
}
} }
for (MethodNode method : nonInitMethods) { for (MethodNode method : nonInitMethods) {
renderBody(method, false); renderBody(method, false);
} }
renderVirtualDeclarations(cls.getName(), virtualMethods);
} catch (NamingException e) { } catch (NamingException e) {
throw new RenderingException("Error rendering class " + cls.getName() + ". See a cause for details", e); throw new RenderingException("Error rendering class " + cls.getName() + ". See a cause for details", e);
} catch (IOException e) { } catch (IOException e) {
@ -405,6 +381,128 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
debugEmitter.emitClass(null); debugEmitter.emitClass(null);
} }
private void renderMethodStubs(List<ClassNode> classes) {
try {
boolean first = true;
writer.append("$rt_methodStubs([");
for (int i = 0; i < classes.size(); ++i) {
ClassNode cls = classes.get(i);
MethodHolder clinit = classSource.get(cls.getName()).getMethod(
new MethodDescriptor("<clinit>", ValueType.VOID));
if (clinit == null) {
continue;
}
List<String> stubNames = new ArrayList<>();
for (MethodNode method : cls.getMethods()) {
if (method.getModifiers().contains(NodeModifier.STATIC) ||
method.getReference().getName().equals("<init>")) {
stubNames.add(naming.getFullNameFor(method.getReference()));
}
}
if (stubNames.isEmpty()) {
continue;
}
if (!first) {
writer.append(',').softNewLine();
}
first = false;
writer.appendClass(cls.getName()).append("_$clinit").append(",").ws();
if (stubNames.size() == 1) {
writer.append("'").append(stubNames.get(0)).append("'");
} else {
writer.append('[');
for (int j = 0; j < stubNames.size(); ++j) {
if (j > 0) {
writer.append(",").ws();
}
writer.append("'").append(stubNames.get(j)).append("'");
}
writer.append(']');
}
}
writer.append("]);").newLine();
} catch (NamingException e) {
throw new RenderingException("Error rendering method stubs. See a cause for details", e);
} catch (IOException e) {
throw new RenderingException("IO error occured", e);
}
}
private void renderClassMetadata(List<ClassNode> classes) {
try {
writer.append("$rt_declClasses([");
boolean first = true;
for (ClassNode cls : classes) {
if (!first) {
writer.append(',').softNewLine();
}
first = false;
writer.appendClass(cls.getName()).append(",").ws();
writer.append("\"").append(escapeString(cls.getName())).append("\",").ws();
if (cls.getParentName() != null) {
writer.appendClass(cls.getParentName());
} else {
writer.append("0");
}
writer.append(',').ws();
writer.append("[");
for (int i = 0; i < cls.getInterfaces().size(); ++i) {
String iface = cls.getInterfaces().get(i);
if (i > 0) {
writer.append(",").ws();
}
writer.appendClass(iface);
}
writer.append("],").ws();
int flags = 0;
if (cls.getModifiers().contains(NodeModifier.ENUM)) {
flags &= 1;
}
writer.append(flags).append(',').ws();
MethodHolder clinit = classSource.get(cls.getName()).getMethod(
new MethodDescriptor("<clinit>", ValueType.VOID));
if (clinit != null) {
writer.appendClass(cls.getName()).append("_$clinit");
} else {
writer.append('0');
}
writer.append(',').ws();
List<String> stubNames = new ArrayList<>();
List<MethodNode> virtualMethods = new ArrayList<>();
for (MethodNode method : cls.getMethods()) {
if (clinit != null && (method.getModifiers().contains(NodeModifier.STATIC) ||
method.getReference().getName().equals("<init>"))) {
stubNames.add(naming.getFullNameFor(method.getReference()));
}
if (!method.getModifiers().contains(NodeModifier.STATIC)) {
virtualMethods.add(method);
}
}
if (stubNames.size() == 1) {
writer.append("'").append(stubNames.get(0)).append("'");
} else {
writer.append('[');
for (int j = 0; j < stubNames.size(); ++j) {
if (j > 0) {
writer.append(",").ws();
}
writer.append("'").append(stubNames.get(j)).append("'");
}
writer.append(']');
}
writer.append(',').ws();
renderVirtualDeclarations(virtualMethods);
}
writer.append("]);").newLine();
} catch (NamingException e) {
throw new RenderingException("Error rendering class metadata. See a cause for details", e);
} catch (IOException e) {
throw new RenderingException("IO error occured", e);
}
}
private static Object getDefaultValue(ValueType type) { private static Object getDefaultValue(ValueType type) {
if (type instanceof ValueType.Primitive) { if (type instanceof ValueType.Primitive) {
ValueType.Primitive primitive = (ValueType.Primitive)type; ValueType.Primitive primitive = (ValueType.Primitive)type;
@ -454,22 +552,16 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
debugEmitter.emitMethod(null); debugEmitter.emitMethod(null);
} }
private void renderVirtualDeclarations(String className, List<MethodNode> methods) private void renderVirtualDeclarations(List<MethodNode> methods) throws NamingException, IOException {
throws NamingException, IOException { writer.append("[");
if (methods.isEmpty()) { boolean first = true;
return;
}
for (MethodNode method : methods) {
MethodReference ref = method.getReference();
if (ref.getDescriptor().getName().equals("<init>")) {
renderInitializer(method);
}
}
writer.append("$rt_virtualMethods(").appendClass(className).indent();
for (MethodNode method : methods) { for (MethodNode method : methods) {
debugEmitter.emitMethod(method.getReference().getDescriptor()); debugEmitter.emitMethod(method.getReference().getDescriptor());
MethodReference ref = method.getReference(); MethodReference ref = method.getReference();
writer.append(",").newLine(); if (!first) {
writer.append(",").ws();
}
first = false;
String methodName = method.isAsync() ? naming.getNameForAsync(ref) : naming.getNameFor(ref); String methodName = method.isAsync() ? naming.getNameForAsync(ref) : naming.getNameFor(ref);
if (method.isOriginalNamePreserved()) { if (method.isOriginalNamePreserved()) {
writer.append("[\"").append(methodName).append("\",").ws().append("\"").append(ref.getName()) writer.append("[\"").append(methodName).append("\",").ws().append("\"").append(ref.getName())
@ -509,7 +601,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
writer.append("$rt_asyncAdapter(").appendMethodBody(ref).append(')'); writer.append("$rt_asyncAdapter(").appendMethodBody(ref).append(')');
} }
} }
writer.append(");").newLine().outdent(); writer.append("]");
} }
private void renderStaticDeclaration(MethodNode method) throws NamingException, IOException { private void renderStaticDeclaration(MethodNode method) throws NamingException, IOException {

View File

@ -454,16 +454,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
// END Thread stuff // END Thread stuff
renderer.renderRuntime(); renderer.renderRuntime();
for (ClassNode clsNode : clsNodes) { renderer.render(clsNodes);
ClassReader cls = classSet.get(clsNode.getName());
for (RendererListener listener : rendererListeners) {
listener.beforeClass(cls);
}
renderer.render(clsNode);
for (RendererListener listener : rendererListeners) {
listener.afterClass(cls);
}
}
renderer.renderStringPool(); renderer.renderStringPool();
for (Map.Entry<String, TeaVMEntryPoint> entry : entryPoints.entrySet()) { for (Map.Entry<String, TeaVMEntryPoint> entry : entryPoints.entrySet()) {
sourceWriter.append("var ").append(entry.getKey()).ws().append("=").ws(); sourceWriter.append("var ").append(entry.getKey()).ws().append("=").ws();

View File

@ -17,7 +17,6 @@ package org.teavm.vm.spi;
import java.io.IOException; import java.io.IOException;
import org.teavm.javascript.RenderingContext; import org.teavm.javascript.RenderingContext;
import org.teavm.model.ClassReader;
import org.teavm.vm.BuildTarget; import org.teavm.vm.BuildTarget;
/** /**
@ -29,14 +28,6 @@ public abstract class AbstractRendererListener implements RendererListener {
public void begin(RenderingContext context, BuildTarget buildTarget) throws IOException { public void begin(RenderingContext context, BuildTarget buildTarget) throws IOException {
} }
@Override
public void beforeClass(ClassReader cls) throws IOException {
}
@Override
public void afterClass(ClassReader cls) throws IOException {
}
@Override @Override
public void complete() throws IOException { public void complete() throws IOException {
} }

View File

@ -17,7 +17,6 @@ package org.teavm.vm.spi;
import java.io.IOException; import java.io.IOException;
import org.teavm.javascript.RenderingContext; import org.teavm.javascript.RenderingContext;
import org.teavm.model.ClassReader;
import org.teavm.vm.BuildTarget; import org.teavm.vm.BuildTarget;
/** /**
@ -27,9 +26,5 @@ import org.teavm.vm.BuildTarget;
public interface RendererListener { public interface RendererListener {
void begin(RenderingContext context, BuildTarget buildTarget) throws IOException; void begin(RenderingContext context, BuildTarget buildTarget) throws IOException;
void beforeClass(ClassReader cls) throws IOException;
void afterClass(ClassReader cls) throws IOException;
void complete() throws IOException; void complete() throws IOException;
} }

View File

@ -336,14 +336,21 @@ function $rt_assertNotNaN(value) {
} }
return value; return value;
} }
function $rt_methodStubs(clinit, names) { function $rt_methodStubs(data) {
for (var i = 0; i < names.length; i = (i + 1) | 0) { for (var i = 0; i < data.length; i += 2) {
window[names[i]] = (function(name) { var clinit = data[i + 0];
return function() { var names = data[i + 1];
clinit(); if (!(names instanceof Array)) {
return window[name].apply(window, arguments); names = [names];
} }
})(names[i]); for (var j = 0; j < names.length; j = (j + 1) | 0) {
window[names[j]] = (function(name, clinit) {
return function() {
clinit();
return window[name].apply(window, arguments);
}
})(names[j], clinit);
}
} }
} }
var $rt_stdoutBuffer = ""; var $rt_stdoutBuffer = "";
@ -368,25 +375,58 @@ function $rt_putStderr(ch) {
$rt_stderrBuffer += String.fromCharCode(ch); $rt_stderrBuffer += String.fromCharCode(ch);
} }
} }
function $rt_declClass(cls, data) { function $rt_metadata(data) {
cls.$meta = {}; for (var i = 0; i < data.length; i += 8) {
var m = cls.$meta var cls = data[i + 0];
m.superclass = typeof(data.superclass) !== 'undefined' ? data.superclass : null; cls.$meta = {};
m.supertypes = data.interfaces ? data.interfaces.slice() : []; var m = cls.$meta;
if (data.superclass) { m.name = data[i + 1];
m.supertypes.push(data.superclass); m.binaryName = "L" + m.name + ";";
cls.prototype = new data.superclass(); var superclass = data[i + 2];
} else { m.superclass = superclass !== 0 ? superclass : null;
cls.prototype = new Object(); m.supertypes = data[i + 3];
if (m.superclass) {
m.supertypes.push(m.superclass);
cls.prototype = new m.superclass();
} else {
cls.prototype = new Object();
}
var flags = data[i + 4];
m.enum = (flags & 1) != 0;
m.primitive = false;
m.item = null;
cls.prototype.constructor = cls;
cls.classObject = null;
var clinit = data[i + 5];
cls.$clinit = clinit !== 0 ? clinit : function() {};
var names = data[i + 6];
if (!(names instanceof Array)) {
names = [names];
}
for (var j = 0; j < names.length; j = (j + 1) | 0) {
window[names[j]] = (function(cls, name) {
return function() {
var clinit = cls.$clinit;
cls.$clinit = function() {};
cls.$clinit();
return window[name].apply(window, arguments);
}
})(cls, names[j]);
}
var virtualMethods = data[i + 7];
for (var j = 0; j < virtualMethods.length; j += 2) {
name = virtualMethods[j + 0];
var func = virtualMethods[j + 1];
if (typeof name === 'string') {
name = [name];
}
for (var k = 0; k < name.length; ++k) {
cls.prototype[name[k]] = func;
}
}
} }
m.name = data.name;
m.binaryName = "L" + data.name + ";";
m.enum = data.enum;
m.item = null;
m.primitive = false;
cls.prototype.constructor = cls;
cls.classObject = null;
cls.$clinit = data.clinit ? data.clinit : function() {};
} }
function $rt_virtualMethods(cls) { function $rt_virtualMethods(cls) {
for (var i = 1; i < arguments.length; i += 2) { for (var i = 1; i < arguments.length; i += 2) {
@ -401,6 +441,22 @@ function $rt_virtualMethods(cls) {
} }
} }
} }
function $rt_virtualMethods(data) {
for (var i = 0; i < data.length; i += 2) {
var cls = data[i + 0];
var methods = data[i + 1];
for (var j = 0; j < methods.length; j += 2) {
var name = methods[j + 0];
var func = methods[j + 1];
if (typeof name === 'string') {
name = [name];
}
for (var k = 0; k < name.length; ++k) {
cls.prototype[name[k]] = func;
}
}
}
}
function $rt_asyncResult(value) { function $rt_asyncResult(value) {
return function() { return function() {
return value; return value;

View File

@ -20,7 +20,6 @@ import java.util.Map;
import org.teavm.codegen.SourceWriter; import org.teavm.codegen.SourceWriter;
import org.teavm.javascript.RenderingContext; import org.teavm.javascript.RenderingContext;
import org.teavm.jso.plugin.JSODependencyListener.ExposedClass; import org.teavm.jso.plugin.JSODependencyListener.ExposedClass;
import org.teavm.model.ClassReader;
import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.vm.BuildTarget; import org.teavm.vm.BuildTarget;
@ -43,14 +42,6 @@ class JSOAliasRenderer implements RendererListener {
writer = context.getWriter(); writer = context.getWriter();
} }
@Override
public void beforeClass(ClassReader cls) throws IOException {
}
@Override
public void afterClass(ClassReader cls) throws IOException {
}
@Override @Override
public void complete() throws IOException { public void complete() throws IOException {
if (!dependencyListener.isAnyAliasExists()) { if (!dependencyListener.isAnyAliasExists()) {