Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
asm
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
yaoh wu
asm
Commits
a1f46f1f
Commit
a1f46f1f
authored
20 years ago
by
Eugene Kuleshov
Browse files
Options
Downloads
Patches
Plain Diff
added experimental signature decompiler
parent
33203ceb
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/org/objectweb/asm/util/TraceClassVisitor.java
+232
-16
232 additions, 16 deletions
src/org/objectweb/asm/util/TraceClassVisitor.java
test/conform/org/objectweb/asm/util/ClassSignatureDecompilerTest.java
+71
-0
71 additions, 0 deletions
.../org/objectweb/asm/util/ClassSignatureDecompilerTest.java
with
303 additions
and
16 deletions
src/org/objectweb/asm/util/TraceClassVisitor.java
+
232
−
16
View file @
a1f46f1f
...
...
@@ -32,6 +32,9 @@ package org.objectweb.asm.util;
import
java.io.FileInputStream
;
import
java.io.PrintWriter
;
import
java.util.ArrayList
;
import
java.util.Iterator
;
import
java.util.List
;
import
org.objectweb.asm.AnnotationVisitor
;
import
org.objectweb.asm.Attribute
;
...
...
@@ -40,6 +43,10 @@ import org.objectweb.asm.ClassVisitor;
import
org.objectweb.asm.MethodVisitor
;
import
org.objectweb.asm.Opcodes
;
import
org.objectweb.asm.FieldVisitor
;
import
org.objectweb.asm.signature.ClassSignatureVisitor
;
import
org.objectweb.asm.signature.SignatureReader
;
import
org.objectweb.asm.signature.TypeSignatureVisitor
;
/**
* A {@link ClassVisitor} that prints a disassembled view of the classes it
...
...
@@ -196,26 +203,36 @@ public class TraceClassVisitor extends TraceAbstractVisitor
buf
.
append
(
"class "
);
}
appendDescriptor
(
INTERNAL_NAME
,
name
);
buf
.
append
(
' '
);
if
(
superName
!=
null
&&
!
superName
.
equals
(
"java/lang/Object"
))
{
buf
.
append
(
"extends "
);
appendDescriptor
(
INTERNAL_NAME
,
superName
);
if
(
signature
!=
null
)
{
ClassSignatureDecompiler
classSignatureDecompiler
=
new
ClassSignatureDecompiler
(
access
,
name
);
SignatureReader
r
=
new
SignatureReader
(
signature
);
r
.
acceptClass
(
classSignatureDecompiler
);
buf
.
append
(
classSignatureDecompiler
.
toString
());
}
else
{
buf
.
append
(
' '
);
}
if
(
interfaces
!=
null
&&
interfaces
.
length
>
0
)
{
buf
.
append
(
"implements "
);
for
(
int
i
=
0
;
i
<
interfaces
.
length
;
++
i
)
{
appendDescriptor
(
INTERNAL_NAME
,
interfaces
[
i
]);
if
(
superName
!=
null
&&
!
superName
.
equals
(
"java/lang/Object"
))
{
buf
.
append
(
"extends "
);
appendDescriptor
(
INTERNAL_NAME
,
superName
);
buf
.
append
(
' '
);
}
if
(
interfaces
!=
null
&&
interfaces
.
length
>
0
)
{
buf
.
append
(
"implements "
);
for
(
int
i
=
0
;
i
<
interfaces
.
length
;
++
i
)
{
appendDescriptor
(
INTERNAL_NAME
,
interfaces
[
i
]);
buf
.
append
(
' '
);
}
}
// if (signature != null) {
// buf.append("/* ");
// appendDescriptor(CLASS_SIGNATURE, signature);
// buf.append(" */ {\n\n");
// }
}
if
(
signature
!=
null
)
{
buf
.
append
(
"/* "
);
appendDescriptor
(
CLASS_SIGNATURE
,
signature
);
buf
.
append
(
" */ {\n\n"
);
}
else
{
buf
.
append
(
"{\n\n"
);
}
buf
.
append
(
" {\n\n"
);
text
.
add
(
buf
.
toString
());
}
...
...
@@ -427,4 +444,203 @@ public class TraceClassVisitor extends TraceAbstractVisitor
buf
.
append
(
"strictfp "
);
}
}
/**
* <code>ClassSignatureVisitor</code> implementation that constructs
* Java class declaration based on information from sigature value.
*/
public
static
final
class
ClassSignatureDecompiler
implements
ClassSignatureVisitor
{
private
List
formalParams
=
new
ArrayList
();
private
TypeDecompiler
superClass
;
private
List
interfaces
=
new
ArrayList
();
private
boolean
isInterface
;
private
String
className
;
public
ClassSignatureDecompiler
(
int
access
,
String
name
)
{
this
.
isInterface
=
(
access
|
Opcodes
.
ACC_INTERFACE
)!=
0
;
this
.
className
=
name
;
}
public
void
visitFormalTypeParameter
(
String
name
)
{
formalParams
.
add
(
new
FormalParam
(
name
));
}
public
TypeSignatureVisitor
visitClassBound
()
{
FormalParam
param
=
(
FormalParam
)
formalParams
.
get
(
formalParams
.
size
()-
1
);
TypeDecompiler
boundDecompiler
=
new
TypeDecompiler
();
param
.
classBound
=
boundDecompiler
;
return
boundDecompiler
;
}
public
TypeSignatureVisitor
visitInterfaceBound
()
{
FormalParam
param
=
(
FormalParam
)
formalParams
.
get
(
formalParams
.
size
()-
1
);
TypeDecompiler
boundDecompiler
=
new
TypeDecompiler
();
param
.
interfaceBounds
.
add
(
boundDecompiler
);
return
boundDecompiler
;
}
public
TypeSignatureVisitor
visitSuperclass
()
{
superClass
=
new
TypeDecompiler
();
return
superClass
;
}
public
TypeSignatureVisitor
visitInterface
()
{
TypeSignatureVisitor
i
=
new
TypeDecompiler
();
interfaces
.
add
(
i
);
return
i
;
}
public
String
toString
()
{
StringBuffer
sb
=
new
StringBuffer
();
if
(
formalParams
.
size
()>
0
)
{
sb
.
append
(
"<"
);
String
d
=
""
;
for
(
Iterator
it
=
formalParams
.
iterator
();
it
.
hasNext
();)
{
sb
.
append
(
d
).
append
(
it
.
next
().
toString
());
d
=
", "
;
}
sb
.
append
(
">"
);
}
if
(
superClass
!=
null
&&
!
"java/lang/Object"
.
equals
(
superClass
.
type
))
{
sb
.
append
(
" extends "
).
append
(
superClass
.
toString
());
}
if
(
this
.
interfaces
.
size
()>
0
)
{
// TODO should use "extends" for interfaces
// sb.append( isInterface ? " extends " : " implements ");
sb
.
append
(
" implements "
);
String
d
=
""
;
for
(
Iterator
it
=
this
.
interfaces
.
iterator
();
it
.
hasNext
();)
{
sb
.
append
(
d
).
append
(
it
.
next
().
toString
());
d
=
", "
;
}
}
return
sb
.
toString
();
}
}
public
static
final
class
TypeDecompiler
extends
TypeSignatureAdapter
{
public
String
type
;
public
List
arguments
=
new
ArrayList
();
public
void
visitClassType
(
String
name
)
{
type
=
name
;
}
public
TypeSignatureVisitor
visitTypeArgument
(
char
tag
)
{
TypeArgumentDecompiler
argument
=
new
TypeArgumentDecompiler
(
tag
);
arguments
.
add
(
argument
);
return
argument
;
}
public
String
toString
()
{
StringBuffer
sb
=
new
StringBuffer
(
type
.
replace
(
'/'
,
'.'
));
if
(
arguments
.
size
()>
0
)
{
sb
.
append
(
"<"
);
String
d
=
""
;
for
(
Iterator
it
=
arguments
.
iterator
();
it
.
hasNext
();)
{
sb
.
append
(
d
).
append
(
it
.
next
().
toString
());
d
=
", "
;
}
sb
.
append
(
">"
);
}
return
sb
.
toString
();
}
}
public
static
final
class
TypeArgumentDecompiler
extends
TypeSignatureAdapter
{
public
char
tag
;
public
String
typeVariable
;
public
TypeArgumentDecompiler
(
char
tag
)
{
this
.
tag
=
tag
;
}
public
void
visitTypeVariable
(
String
name
)
{
typeVariable
=
name
;
}
public
String
toString
()
{
StringBuffer
sb
=
new
StringBuffer
();
if
(
tag
!=
' '
)
{
// TODO expand tag
sb
.
append
(
"["
).
append
(
tag
).
append
(
"]"
);
}
if
(
typeVariable
!=
null
)
{
sb
.
append
(
typeVariable
);
}
return
sb
.
toString
();
}
}
public
static
abstract
class
TypeSignatureAdapter
implements
TypeSignatureVisitor
{
public
void
visitClassType
(
String
name
)
{
throw
new
IllegalStateException
(
getClass
().
getName
());
}
public
void
visitInnerClassType
(
String
name
)
{
throw
new
IllegalStateException
(
getClass
().
getName
());
}
public
void
visitBaseType
(
char
descriptor
)
{
throw
new
IllegalStateException
(
getClass
().
getName
());
}
public
void
visitTypeVariable
(
String
name
)
{
throw
new
IllegalStateException
(
getClass
().
getName
());
}
public
TypeSignatureVisitor
visitArrayType
()
{
throw
new
IllegalStateException
(
getClass
().
getName
());
}
public
TypeSignatureVisitor
visitTypeArgument
(
char
tag
)
{
throw
new
IllegalStateException
(
getClass
().
getName
());
}
public
void
visitEnd
()
{
// throw new IllegalStateException();
}
}
public
static
class
FormalParam
{
public
String
name
;
public
TypeDecompiler
classBound
;
public
List
interfaceBounds
=
new
ArrayList
();
public
FormalParam
(
String
name
)
{
this
.
name
=
name
;
}
public
String
toString
()
{
StringBuffer
sb
=
new
StringBuffer
();
sb
.
append
(
name
);
if
(
classBound
!=
null
&&
!
"java/lang/Object"
.
equals
(
classBound
.
type
))
{
sb
.
append
(
" extends "
).
append
(
classBound
.
toString
());
}
if
(
interfaceBounds
.
size
()>
0
)
{
sb
.
append
(
" implements"
);
for
(
Iterator
it2
=
interfaceBounds
.
iterator
();
it2
.
hasNext
();)
{
TypeDecompiler
boundDecompiler
=
(
TypeDecompiler
)
it2
.
next
();
sb
.
append
(
" "
).
append
(
boundDecompiler
.
toString
());
}
}
return
sb
.
toString
();
}
}
}
This diff is collapsed.
Click to expand it.
test/conform/org/objectweb/asm/util/ClassSignatureDecompilerTest.java
0 → 100644
+
71
−
0
View file @
a1f46f1f
/* $Id: ClassSignatureDecompilerTest.java,v 1.1.2.1 2005-01-16 07:07:01 ekuleshov Exp $ */
package
org.objectweb.asm.util
;
import
org.objectweb.asm.Opcodes
;
import
org.objectweb.asm.signature.SignatureReader
;
import
org.objectweb.asm.util.TraceClassVisitor.ClassSignatureDecompiler
;
import
junit.framework.TestCase
;
/**
* ClassSignatureDecompilerTest
*
* @author Eugene Kuleshov
*/
public
class
ClassSignatureDecompilerTest
extends
TestCase
{
public
void
test1
()
throws
Exception
{
String
decl
=
"java.lang.Enum<E extends Enum<E>>"
;
String
signature
=
"<E:Ljava/lang/Enum<TE;>;>Ljava/lang/Object;Ljava/lang/Comparable<TE;>;Ljava/io/Serializable;"
;
String
className
=
"java/lang/Enum"
;
int
access
=
Opcodes
.
ACC_ENUM
|
Opcodes
.
ACC_PUBLIC
;
ClassSignatureDecompiler
d
=
new
ClassSignatureDecompiler
(
access
,
className
);
SignatureReader
r
=
new
SignatureReader
(
signature
);
r
.
acceptClass
(
d
);
assertEquals
(
decl
,
d
.
toString
());
}
public
void
test2
()
throws
Exception
{
String
decl
=
"java.lang.reflect.TypeVariable<D extends java.lang.reflect.GenericDeclaration> extends java.lang.reflect.Type"
;
String
signature
=
"<D::Ljava/lang/reflect/GenericDeclaration;>Ljava/lang/Object;Ljava/lang/reflect/Type;"
;
String
className
=
"java/lang/reflect/TypeVariable"
;
int
access
=
Opcodes
.
ACC_INTERFACE
|
Opcodes
.
ACC_PUBLIC
;
ClassSignatureDecompiler
d
=
new
ClassSignatureDecompiler
(
access
,
className
);
SignatureReader
r
=
new
SignatureReader
(
signature
);
r
.
acceptClass
(
d
);
assertEquals
(
decl
,
d
.
toString
());
}
public
void
test3
()
throws
Exception
{
String
decl
=
"java.util.concurrent.ConcurrentHashMap<K, V> extends java.util.AbstractMap<K, V> implements java.util.concurrent.ConcurrentMap<K, V>, java.io.Serializable"
;
String
signature
=
"<K:Ljava/lang/Object;V:Ljava/lang/Object;>Ljava/util/AbstractMap<TK;TV;>;Ljava/util/concurrent/ConcurrentMap<TK;TV;>;Ljava/io/Serializable;"
;
String
className
=
"java/util/concurrent/ConcurrentHashMap"
;
int
access
=
Opcodes
.
ACC_PUBLIC
;
ClassSignatureDecompiler
d
=
new
ClassSignatureDecompiler
(
access
,
className
);
SignatureReader
r
=
new
SignatureReader
(
signature
);
r
.
acceptClass
(
d
);
assertEquals
(
decl
,
d
.
toString
());
}
public
void
test4
()
throws
Exception
{
String
decl
=
"java.util.EnumMap<K extends java.lang.Enum<K>, V> extends java.util.AbstractMap<K, V> implements java.io.Serializable, java.lang.Cloneable"
;
String
signature
=
"<K:Ljava/lang/Enum<TK;>;V:Ljava/lang/Object;>Ljava/util/AbstractMap<TK;TV;>;Ljava/io/Serializable;Ljava/lang/Cloneable;"
;
String
className
=
"java/util/EnumMap"
;
int
access
=
Opcodes
.
ACC_PUBLIC
;
ClassSignatureDecompiler
d
=
new
ClassSignatureDecompiler
(
access
,
className
);
SignatureReader
r
=
new
SignatureReader
(
signature
);
r
.
acceptClass
(
d
);
assertEquals
(
decl
,
d
.
toString
());
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment