Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_langtools
提交
59abb7e2
D
dragonwell8_langtools
项目概览
openanolis
/
dragonwell8_langtools
通知
0
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_langtools
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
59abb7e2
编写于
10月 16, 2009
作者:
J
jjg
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6888367: classfile library parses signature attributes incorrectly
Reviewed-by: ksrini
上级
a8ccf641
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
701 addition
and
105 deletion
+701
-105
src/share/classes/com/sun/tools/classfile/Signature.java
src/share/classes/com/sun/tools/classfile/Signature.java
+50
-53
src/share/classes/com/sun/tools/classfile/Type.java
src/share/classes/com/sun/tools/classfile/Type.java
+136
-48
src/share/classes/com/sun/tools/javap/ClassWriter.java
src/share/classes/com/sun/tools/javap/ClassWriter.java
+3
-3
src/share/classes/com/sun/tools/javap/LocalVariableTypeTableWriter.java
...ses/com/sun/tools/javap/LocalVariableTypeTableWriter.java
+1
-1
test/tools/javap/classfile/6888367/T6888367.java
test/tools/javap/classfile/6888367/T6888367.java
+511
-0
未找到文件。
src/share/classes/com/sun/tools/classfile/Signature.java
浏览文件 @
59abb7e2
...
...
@@ -27,6 +27,7 @@ package com.sun.tools.classfile;
import
java.util.ArrayList
;
import
java.util.List
;
import
com.sun.tools.classfile.Type.*
;
/**
* See JVMS3 4.4.4.
...
...
@@ -50,19 +51,19 @@ public class Signature extends Descriptor {
@Override
public
int
getParameterCount
(
ConstantPool
constant_pool
)
throws
ConstantPoolException
{
Type
.
MethodType
m
=
(
Type
.
MethodType
)
getType
(
constant_pool
);
return
m
.
arg
Types
.
size
();
MethodType
m
=
(
MethodType
)
getType
(
constant_pool
);
return
m
.
param
Types
.
size
();
}
@Override
public
String
getParameterTypes
(
ConstantPool
constant_pool
)
throws
ConstantPoolException
{
Type
.
MethodType
m
=
(
Type
.
MethodType
)
getType
(
constant_pool
);
MethodType
m
=
(
MethodType
)
getType
(
constant_pool
);
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"("
);
String
sep
=
""
;
for
(
Type
argType:
m
.
arg
Types
)
{
for
(
Type
paramType:
m
.
param
Types
)
{
sb
.
append
(
sep
);
sb
.
append
(
arg
Type
);
sb
.
append
(
param
Type
);
sep
=
", "
;
}
sb
.
append
(
")"
);
...
...
@@ -71,7 +72,7 @@ public class Signature extends Descriptor {
@Override
public
String
getReturnType
(
ConstantPool
constant_pool
)
throws
ConstantPoolException
{
Type
.
MethodType
m
=
(
Type
.
MethodType
)
getType
(
constant_pool
);
MethodType
m
=
(
MethodType
)
getType
(
constant_pool
);
return
m
.
returnType
.
toString
();
}
...
...
@@ -84,12 +85,12 @@ public class Signature extends Descriptor {
this
.
sig
=
sig
;
sigp
=
0
;
List
<
Type
>
typeArg
Types
=
null
;
List
<
Type
ParamType
>
typeParam
Types
=
null
;
if
(
sig
.
charAt
(
sigp
)
==
'<'
)
type
ArgTypes
=
parseTypeArg
Types
();
type
ParamTypes
=
parseTypeParam
Types
();
if
(
sig
.
charAt
(
sigp
)
==
'('
)
{
List
<
Type
>
arg
Types
=
parseTypeSignatures
(
')'
);
List
<
Type
>
param
Types
=
parseTypeSignatures
(
')'
);
Type
returnType
=
parseTypeSignature
();
List
<
Type
>
throwsTypes
=
null
;
while
(
sigp
<
sig
.
length
()
&&
sig
.
charAt
(
sigp
)
==
'^'
)
{
...
...
@@ -98,16 +99,19 @@ public class Signature extends Descriptor {
throwsTypes
=
new
ArrayList
<
Type
>();
throwsTypes
.
add
(
parseTypeSignature
());
}
return
new
Type
.
MethodType
(
typeArgTypes
,
arg
Types
,
returnType
,
throwsTypes
);
return
new
MethodType
(
typeParamTypes
,
param
Types
,
returnType
,
throwsTypes
);
}
else
{
Type
t
=
parseTypeSignature
();
if
(
type
Arg
Types
==
null
&&
sigp
==
sig
.
length
())
if
(
type
Param
Types
==
null
&&
sigp
==
sig
.
length
())
return
t
;
Type
superclass
=
t
;
List
<
Type
>
superinterfaces
=
new
ArrayList
<
Type
>();
while
(
sigp
<
sig
.
length
())
List
<
Type
>
superinterfaces
=
null
;
while
(
sigp
<
sig
.
length
())
{
if
(
superinterfaces
==
null
)
superinterfaces
=
new
ArrayList
<
Type
>();
superinterfaces
.
add
(
parseTypeSignature
());
return
new
Type
.
ClassSigType
(
typeArgTypes
,
superclass
,
superinterfaces
);
}
return
new
ClassSigType
(
typeParamTypes
,
superclass
,
superinterfaces
);
}
}
...
...
@@ -116,61 +120,61 @@ public class Signature extends Descriptor {
switch
(
sig
.
charAt
(
sigp
))
{
case
'B'
:
sigp
++;
return
new
Type
.
SimpleType
(
"byte"
);
return
new
SimpleType
(
"byte"
);
case
'C'
:
sigp
++;
return
new
Type
.
SimpleType
(
"char"
);
return
new
SimpleType
(
"char"
);
case
'D'
:
sigp
++;
return
new
Type
.
SimpleType
(
"double"
);
return
new
SimpleType
(
"double"
);
case
'F'
:
sigp
++;
return
new
Type
.
SimpleType
(
"float"
);
return
new
SimpleType
(
"float"
);
case
'I'
:
sigp
++;
return
new
Type
.
SimpleType
(
"int"
);
return
new
SimpleType
(
"int"
);
case
'J'
:
sigp
++;
return
new
Type
.
SimpleType
(
"long"
);
return
new
SimpleType
(
"long"
);
case
'L'
:
return
parseClassTypeSignature
();
case
'S'
:
sigp
++;
return
new
Type
.
SimpleType
(
"short"
);
return
new
SimpleType
(
"short"
);
case
'T'
:
return
parseTypeVariableSignature
();
case
'V'
:
sigp
++;
return
new
Type
.
SimpleType
(
"void"
);
return
new
SimpleType
(
"void"
);
case
'Z'
:
sigp
++;
return
new
Type
.
SimpleType
(
"boolean"
);
return
new
SimpleType
(
"boolean"
);
case
'['
:
sigp
++;
return
new
Type
.
ArrayType
(
parseTypeSignature
());
return
new
ArrayType
(
parseTypeSignature
());
case
'*'
:
sigp
++;
return
new
Type
.
WildcardType
();
return
new
WildcardType
();
case
'+'
:
sigp
++;
return
new
Type
.
WildcardType
(
"extends"
,
parseTypeSignature
());
return
new
WildcardType
(
WildcardType
.
Kind
.
EXTENDS
,
parseTypeSignature
());
case
'-'
:
sigp
++;
return
new
Type
.
WildcardType
(
"super"
,
parseTypeSignature
());
return
new
WildcardType
(
WildcardType
.
Kind
.
SUPER
,
parseTypeSignature
());
default
:
throw
new
IllegalStateException
(
debugInfo
());
...
...
@@ -194,30 +198,22 @@ public class Signature extends Descriptor {
private
Type
parseClassTypeSignatureRest
()
{
StringBuilder
sb
=
new
StringBuilder
();
Type
t
=
null
;
char
sigch
;
while
(
true
)
{
List
<
Type
>
argTypes
=
null
;
ClassType
t
=
null
;
char
sigch
;
do
{
switch
(
sigch
=
sig
.
charAt
(
sigp
))
{
case
'/'
:
sigp
++;
sb
.
append
(
"."
);
case
'<'
:
argTypes
=
parseTypeSignatures
(
'>'
);
break
;
case
'.'
:
sigp
++;
if
(
t
==
null
)
t
=
new
Type
.
SimpleType
(
sb
.
toString
());
return
new
Type
.
InnerClassType
(
t
,
parseClassTypeSignatureRest
());
case
';'
:
sigp
++;
if
(
t
==
null
)
t
=
new
Type
.
SimpleType
(
sb
.
toString
());
return
t
;
case
'<'
:
List
<
Type
>
argTypes
=
parseTypeSignatures
(
'>'
);
t
=
new
Type
.
ClassType
(
sb
.
toString
(),
argTypes
);
t
=
new
ClassType
(
t
,
sb
.
toString
(),
argTypes
);
sb
.
setLength
(
0
);
argTypes
=
null
;
break
;
default
:
...
...
@@ -225,21 +221,22 @@ public class Signature extends Descriptor {
sb
.
append
(
sigch
);
break
;
}
}
}
while
(
sigch
!=
';'
);
return
t
;
}
private
List
<
Type
>
parseTypeArg
Types
()
{
private
List
<
Type
ParamType
>
parseTypeParam
Types
()
{
assert
sig
.
charAt
(
sigp
)
==
'<'
;
sigp
++;
List
<
Type
>
types
=
null
;
types
=
new
ArrayList
<
Type
>();
List
<
TypeParamType
>
types
=
new
ArrayList
<
TypeParamType
>();
while
(
sig
.
charAt
(
sigp
)
!=
'>'
)
types
.
add
(
parseType
Arg
Type
());
types
.
add
(
parseType
Param
Type
());
sigp
++;
return
types
;
}
private
Type
parseTypeArg
Type
()
{
private
Type
ParamType
parseTypeParam
Type
()
{
int
sep
=
sig
.
indexOf
(
":"
,
sigp
);
String
name
=
sig
.
substring
(
sigp
,
sep
);
Type
classBound
=
null
;
...
...
@@ -253,13 +250,13 @@ public class Signature extends Descriptor {
interfaceBounds
=
new
ArrayList
<
Type
>();
interfaceBounds
.
add
(
parseTypeSignature
());
}
return
new
Type
.
TypeArg
Type
(
name
,
classBound
,
interfaceBounds
);
return
new
Type
Param
Type
(
name
,
classBound
,
interfaceBounds
);
}
private
Type
parseTypeVariableSignature
()
{
sigp
++;
int
sep
=
sig
.
indexOf
(
';'
,
sigp
);
Type
t
=
new
Type
.
SimpleType
(
sig
.
substring
(
sigp
,
sep
));
Type
t
=
new
SimpleType
(
sig
.
substring
(
sigp
,
sep
));
sigp
=
sep
+
1
;
return
t
;
}
...
...
src/share/classes/com/sun/tools/classfile/Type.java
浏览文件 @
59abb7e2
...
...
@@ -31,6 +31,9 @@ import java.util.List;
import
java.util.Set
;
/*
* Family of classes used to represent the parsed form of a {@link Descriptor}
* or {@link Signature}.
*
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
* you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
...
...
@@ -62,11 +65,26 @@ public abstract class Type {
R
visitMethodType
(
MethodType
type
,
P
p
);
R
visitClassSigType
(
ClassSigType
type
,
P
p
);
R
visitClassType
(
ClassType
type
,
P
p
);
R
visitInnerClassType
(
InnerClassType
type
,
P
p
);
R
visitTypeArgType
(
TypeArgType
type
,
P
p
);
R
visitTypeParamType
(
TypeParamType
type
,
P
p
);
R
visitWildcardType
(
WildcardType
type
,
P
p
);
}
/**
* Represents a type signature with a simple name. The name may be that of a
* primitive type, such "{@code int}, {@code float}, etc
* or that of a type argument, such as {@code T}, {@code K}, {@code V}, etc.
*
* See:
* JVMS 4.3.2
* BaseType:
* {@code B}, {@code C}, {@code D}, {@code F}, {@code I},
* {@code J}, {@code S}, {@code Z};
* VoidDescriptor:
* {@code V};
* JVMS 4.3.4
* TypeVariableSignature:
* {@code T} Identifier {@code ;}
*/
public
static
class
SimpleType
extends
Type
{
public
SimpleType
(
String
name
)
{
this
.
name
=
name
;
...
...
@@ -91,6 +109,14 @@ public abstract class Type {
public
final
String
name
;
}
/**
* Represents an array type signature.
*
* See:
* JVMS 4.3.4
* ArrayTypeSignature:
* {@code [} TypeSignature {@code ]}
*/
public
static
class
ArrayType
extends
Type
{
public
ArrayType
(
Type
elemType
)
{
this
.
elemType
=
elemType
;
...
...
@@ -108,17 +134,26 @@ public abstract class Type {
public
final
Type
elemType
;
}
/**
* Represents a method type signature.
*
* See;
* JVMS 4.3.4
* MethodTypeSignature:
* FormalTypeParameters_opt {@code (} TypeSignature* {@code)} ReturnType
* ThrowsSignature*
*/
public
static
class
MethodType
extends
Type
{
public
MethodType
(
List
<?
extends
Type
>
arg
Types
,
Type
resultType
)
{
this
(
null
,
arg
Types
,
resultType
,
null
);
public
MethodType
(
List
<?
extends
Type
>
param
Types
,
Type
resultType
)
{
this
(
null
,
param
Types
,
resultType
,
null
);
}
public
MethodType
(
List
<?
extends
Type
>
typeArg
Types
,
List
<?
extends
Type
>
arg
Types
,
public
MethodType
(
List
<?
extends
Type
ParamType
>
typeParam
Types
,
List
<?
extends
Type
>
param
Types
,
Type
returnType
,
List
<?
extends
Type
>
throwsTypes
)
{
this
.
type
ArgTypes
=
typeArg
Types
;
this
.
argTypes
=
arg
Types
;
this
.
type
ParamTypes
=
typeParam
Types
;
this
.
paramTypes
=
param
Types
;
this
.
returnType
=
returnType
;
this
.
throwsTypes
=
throwsTypes
;
}
...
...
@@ -130,22 +165,32 @@ public abstract class Type {
@Override
public
String
toString
()
{
StringBuilder
sb
=
new
StringBuilder
();
appendIfNotEmpty
(
sb
,
"<"
,
type
Arg
Types
,
"> "
);
appendIfNotEmpty
(
sb
,
"<"
,
type
Param
Types
,
"> "
);
sb
.
append
(
returnType
);
append
(
sb
,
" ("
,
arg
Types
,
")"
);
append
(
sb
,
" ("
,
param
Types
,
")"
);
appendIfNotEmpty
(
sb
,
" throws "
,
throwsTypes
,
""
);
return
sb
.
toString
();
}
public
final
List
<?
extends
Type
>
typeArg
Types
;
public
final
List
<?
extends
Type
>
arg
Types
;
public
final
List
<?
extends
Type
ParamType
>
typeParam
Types
;
public
final
List
<?
extends
Type
>
param
Types
;
public
final
Type
returnType
;
public
final
List
<?
extends
Type
>
throwsTypes
;
}
/**
* Represents a class signature. These describe the signature of
* a class that has type arguments.
*
* See:
* JVMS 4.3.4
* ClassSignature:
* FormalTypeParameters_opt SuperclassSignature SuperinterfaceSignature*
*/
public
static
class
ClassSigType
extends
Type
{
public
ClassSigType
(
List
<
Type
>
typeArgTypes
,
Type
superclassType
,
List
<
Type
>
superinterfaceTypes
)
{
this
.
typeArgTypes
=
typeArgTypes
;
public
ClassSigType
(
List
<
TypeParamType
>
typeParamTypes
,
Type
superclassType
,
List
<
Type
>
superinterfaceTypes
)
{
this
.
typeParamTypes
=
typeParamTypes
;
this
.
superclassType
=
superclassType
;
this
.
superinterfaceTypes
=
superinterfaceTypes
;
}
...
...
@@ -157,7 +202,7 @@ public abstract class Type {
@Override
public
String
toString
()
{
StringBuilder
sb
=
new
StringBuilder
();
appendIfNotEmpty
(
sb
,
"<"
,
type
Arg
Types
,
">"
);
appendIfNotEmpty
(
sb
,
"<"
,
type
Param
Types
,
">"
);
if
(
superclassType
!=
null
)
{
sb
.
append
(
" extends "
);
sb
.
append
(
superclassType
);
...
...
@@ -166,13 +211,30 @@ public abstract class Type {
return
sb
.
toString
();
}
public
final
List
<
Type
>
typeArg
Types
;
public
final
List
<
Type
ParamType
>
typeParam
Types
;
public
final
Type
superclassType
;
public
final
List
<
Type
>
superinterfaceTypes
;
}
/**
* Represents a class type signature. This is used to represent a
* reference to a class, such as in a field, parameter, return type, etc.
*
* See:
* JVMS 4.3.4
* ClassTypeSignature:
* {@code L} PackageSpecifier_opt SimpleClassTypeSignature
* ClassTypeSignatureSuffix* {@code ;}
* PackageSpecifier:
* Identifier {@code /} PackageSpecifier*
* SimpleClassTypeSignature:
* Identifier TypeArguments_opt }
* ClassTypeSignatureSuffix:
* {@code .} SimpleClassTypeSignature
*/
public
static
class
ClassType
extends
Type
{
public
ClassType
(
String
name
,
List
<
Type
>
typeArgs
)
{
public
ClassType
(
ClassType
outerType
,
String
name
,
List
<
Type
>
typeArgs
)
{
this
.
outerType
=
outerType
;
this
.
name
=
name
;
this
.
typeArgs
=
typeArgs
;
}
...
...
@@ -181,47 +243,54 @@ public abstract class Type {
return
visitor
.
visitClassType
(
this
,
data
);
}
public
String
getBinaryName
()
{
if
(
outerType
==
null
)
return
name
;
else
return
(
outerType
.
getBinaryName
()
+
"$"
+
name
);
}
@Override
public
String
toString
()
{
StringBuilder
sb
=
new
StringBuilder
();
if
(
outerType
!=
null
)
{
sb
.
append
(
outerType
);
sb
.
append
(
"."
);
}
sb
.
append
(
name
);
appendIfNotEmpty
(
sb
,
"<"
,
typeArgs
,
">"
);
return
sb
.
toString
();
}
public
final
ClassType
outerType
;
public
final
String
name
;
public
final
List
<
Type
>
typeArgs
;
}
public
static
class
InnerClassType
extends
Type
{
public
InnerClassType
(
Type
outerType
,
Type
innerType
)
{
this
.
outerType
=
outerType
;
this
.
innerType
=
innerType
;
}
public
<
R
,
D
>
R
accept
(
Visitor
<
R
,
D
>
visitor
,
D
data
)
{
return
visitor
.
visitInnerClassType
(
this
,
data
);
}
@Override
public
String
toString
()
{
return
outerType
+
"."
+
innerType
;
}
public
final
Type
outerType
;
public
final
Type
innerType
;
}
public
static
class
TypeArgType
extends
Type
{
public
TypeArgType
(
String
name
,
Type
classBound
,
List
<
Type
>
interfaceBounds
)
{
/**
* Represents a FormalTypeParameter. These are used to declare the type
* parameters for generic classes and methods.
*
* See:
* JVMS 4.3.4
* FormalTypeParameters:
* {@code <} FormalTypeParameter+ {@code >}
* FormalTypeParameter:
* Identifier ClassBound InterfaceBound*
* ClassBound:
* {@code :} FieldTypeSignature_opt
* InterfaceBound:
* {@code :} FieldTypeSignature
*/
public
static
class
TypeParamType
extends
Type
{
public
TypeParamType
(
String
name
,
Type
classBound
,
List
<
Type
>
interfaceBounds
)
{
this
.
name
=
name
;
this
.
classBound
=
classBound
;
this
.
interfaceBounds
=
interfaceBounds
;
}
public
<
R
,
D
>
R
accept
(
Visitor
<
R
,
D
>
visitor
,
D
data
)
{
return
visitor
.
visitType
Arg
Type
(
this
,
data
);
return
visitor
.
visitType
Param
Type
(
this
,
data
);
}
@Override
...
...
@@ -249,12 +318,25 @@ public abstract class Type {
public
final
List
<
Type
>
interfaceBounds
;
}
/**
* Represents a wildcard type argument. A type argument that is not a
* wildcard type argument will be represented by a ClassType, ArrayType, etc.
*
* See:
* JVMS 4.3.4
* TypeArgument:
* WildcardIndicator_opt FieldTypeSignature
* {@code *}
* WildcardIndicator:
* {@code +}
* {@code -}
*/
public
static
class
WildcardType
extends
Type
{
public
enum
Kind
{
UNBOUNDED
,
EXTENDS
,
SUPER
};
public
WildcardType
()
{
this
(
null
,
null
);
this
(
Kind
.
UNBOUNDED
,
null
);
}
public
WildcardType
(
String
kind
,
Type
boundType
)
{
public
WildcardType
(
Kind
kind
,
Type
boundType
)
{
this
.
kind
=
kind
;
this
.
boundType
=
boundType
;
}
...
...
@@ -265,13 +347,19 @@ public abstract class Type {
@Override
public
String
toString
()
{
if
(
kind
==
null
)
return
"?"
;
else
return
"? "
+
kind
+
" "
+
boundType
;
switch
(
kind
)
{
case
UNBOUNDED:
return
"?"
;
case
EXTENDS:
return
"? extends "
+
boundType
;
case
SUPER:
return
"? super "
+
boundType
;
default
:
throw
new
AssertionError
();
}
}
public
final
String
kind
;
public
final
Kind
kind
;
public
final
Type
boundType
;
}
}
src/share/classes/com/sun/tools/javap/ClassWriter.java
浏览文件 @
59abb7e2
...
...
@@ -179,10 +179,10 @@ public class ClassWriter extends BasicWriter {
// The signature parser cannot disambiguate between a
// FieldType and a ClassSignatureType that only contains a superclass type.
if
(
t
instanceof
Type
.
ClassSigType
)
print
(
t
);
print
(
getJavaName
(
t
.
toString
())
);
else
{
print
(
" extends "
);
print
(
t
);
print
(
getJavaName
(
t
.
toString
())
);
}
}
catch
(
ConstantPoolException
e
)
{
print
(
report
(
e
));
...
...
@@ -310,7 +310,7 @@ public class ClassWriter extends BasicWriter {
writeModifiers
(
flags
.
getMethodModifiers
());
if
(
methodType
!=
null
)
{
writeListIfNotEmpty
(
"<"
,
methodType
.
type
Arg
Types
,
"> "
);
writeListIfNotEmpty
(
"<"
,
methodType
.
type
Param
Types
,
"> "
);
}
if
(
getName
(
m
).
equals
(
"<init>"
))
{
print
(
getJavaName
(
classFile
));
...
...
src/share/classes/com/sun/tools/javap/LocalVariableTypeTableWriter.java
浏览文件 @
59abb7e2
...
...
@@ -125,7 +125,7 @@ public class LocalVariableTypeTableWriter extends InstructionDetailWriter {
print
(
" // "
);
Descriptor
d
=
new
Signature
(
entry
.
signature_index
);
try
{
print
(
d
.
getFieldType
(
constant_pool
));
print
(
d
.
getFieldType
(
constant_pool
)
.
toString
().
replace
(
"/"
,
"."
)
);
}
catch
(
InvalidDescriptor
e
)
{
print
(
report
(
e
));
}
catch
(
ConstantPoolException
e
)
{
...
...
test/tools/javap/classfile/6888367/T6888367.java
0 → 100644
浏览文件 @
59abb7e2
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import
java.io.*
;
import
java.net.*
;
import
java.util.*
;
import
com.sun.tools.classfile.*
;
import
com.sun.tools.classfile.Type.ArrayType
;
import
com.sun.tools.classfile.Type.ClassSigType
;
import
com.sun.tools.classfile.Type.ClassType
;
import
com.sun.tools.classfile.Type.MethodType
;
import
com.sun.tools.classfile.Type.SimpleType
;
import
com.sun.tools.classfile.Type.TypeParamType
;
import
com.sun.tools.classfile.Type.WildcardType
;
/*
* @test
* @bug 6888367
* @summary classfile library parses signature attributes incorrectly
*/
/*
* This test is a pretty detailed test both of javac signature generation and classfile
* signature parsing. The first part of the test tests all the examples given in the
* second part of the test. Each example comes with one or two annotations, @Desc, @Sig,
* for the descriptor and signature of the annotated declaration. Annotations are
* provided whenever the annotated item is expected to have a corresponding value.
* Each annotation has two argument values. The first arg is the expected value of the
* descriptor/signature as found in the class file. This value is mostly for documentation
* purposes in reading the test. The second value is the rendering of the descriptor or
* signature using a custom Type visitor that explicitly includes an indication of the
* Type classes being used to represent the descriptor/signature. Thus we test
* that the descriptor/signature is being parsed into the expected type tree structure.
*/
public
class
T6888367
{
public
static
void
main
(
String
...
args
)
throws
Exception
{
new
T6888367
().
run
();
}
public
void
run
()
throws
Exception
{
ClassFile
cf
=
getClassFile
(
"Test"
);
testFields
(
cf
);
testMethods
(
cf
);
testInnerClasses
(
cf
);
// recursive
if
(
errors
>
0
)
throw
new
Exception
(
errors
+
" errors found"
);
}
void
testFields
(
ClassFile
cf
)
throws
Exception
{
String
cn
=
cf
.
getName
();
ConstantPool
cp
=
cf
.
constant_pool
;
for
(
Field
f:
cf
.
fields
)
{
test
(
"field "
+
cn
+
"."
+
f
.
getName
(
cp
),
f
.
descriptor
,
f
.
attributes
,
cp
);
}
}
void
testMethods
(
ClassFile
cf
)
throws
Exception
{
String
cn
=
cf
.
getName
();
ConstantPool
cp
=
cf
.
constant_pool
;
for
(
Method
m:
cf
.
methods
)
{
test
(
"method "
+
cn
+
"."
+
m
.
getName
(
cp
),
m
.
descriptor
,
m
.
attributes
,
cp
);
}
}
void
testInnerClasses
(
ClassFile
cf
)
throws
Exception
{
ConstantPool
cp
=
cf
.
constant_pool
;
InnerClasses_attribute
ic
=
(
InnerClasses_attribute
)
cf
.
attributes
.
get
(
Attribute
.
InnerClasses
);
for
(
InnerClasses_attribute
.
Info
info:
ic
.
classes
)
{
String
outerClassName
=
cp
.
getClassInfo
(
info
.
outer_class_info_index
).
getName
();
if
(!
outerClassName
.
equals
(
cf
.
getName
()))
{
continue
;
}
String
innerClassName
=
cp
.
getClassInfo
(
info
.
inner_class_info_index
).
getName
();
ClassFile
icf
=
getClassFile
(
innerClassName
);
test
(
"class "
+
innerClassName
,
null
,
icf
.
attributes
,
icf
.
constant_pool
);
testInnerClasses
(
icf
);
}
}
void
test
(
String
name
,
Descriptor
desc
,
Attributes
attrs
,
ConstantPool
cp
)
throws
Exception
{
AnnotValues
d
=
getDescValue
(
attrs
,
cp
);
AnnotValues
s
=
getSigValue
(
attrs
,
cp
);
if
(
d
==
null
&&
s
==
null
)
// not a test field or method if no @Desc or @Sig given
return
;
System
.
err
.
println
(
name
);
if
(
desc
!=
null
)
{
System
.
err
.
println
(
" descriptor: "
+
desc
.
getValue
(
cp
));
checkEqual
(
d
.
raw
,
desc
.
getValue
(
cp
));
Type
dt
=
new
Signature
(
desc
.
index
).
getType
(
cp
);
checkEqual
(
d
.
type
,
tp
.
print
(
dt
));
}
Signature_attribute
sa
=
(
Signature_attribute
)
attrs
.
get
(
Attribute
.
Signature
);
if
(
sa
!=
null
)
System
.
err
.
println
(
" signature: "
+
sa
.
getSignature
(
cp
));
if
(
s
!=
null
||
sa
!=
null
)
{
if
(
s
!=
null
&&
sa
!=
null
)
{
checkEqual
(
s
.
raw
,
sa
.
getSignature
(
cp
));
Type
st
=
new
Signature
(
sa
.
signature_index
).
getType
(
cp
);
checkEqual
(
s
.
type
,
tp
.
print
(
st
));
}
else
if
(
s
!=
null
)
error
(
"@Sig annotation found but not Signature attribute"
);
else
error
(
"Signature attribute found but no @Sig annotation"
);
}
System
.
err
.
println
();
}
ClassFile
getClassFile
(
String
name
)
throws
IOException
,
ConstantPoolException
{
URL
url
=
getClass
().
getResource
(
name
+
".class"
);
InputStream
in
=
url
.
openStream
();
try
{
return
ClassFile
.
read
(
in
);
}
finally
{
in
.
close
();
}
}
AnnotValues
getDescValue
(
Attributes
attrs
,
ConstantPool
cp
)
throws
Exception
{
return
getAnnotValues
(
Desc
.
class
.
getName
(),
attrs
,
cp
);
}
AnnotValues
getSigValue
(
Attributes
attrs
,
ConstantPool
cp
)
throws
Exception
{
return
getAnnotValues
(
Sig
.
class
.
getName
(),
attrs
,
cp
);
}
static
class
AnnotValues
{
AnnotValues
(
String
raw
,
String
type
)
{
this
.
raw
=
raw
;
this
.
type
=
type
;
}
final
String
raw
;
final
String
type
;
}
AnnotValues
getAnnotValues
(
String
annotName
,
Attributes
attrs
,
ConstantPool
cp
)
throws
Exception
{
RuntimeInvisibleAnnotations_attribute
annots
=
(
RuntimeInvisibleAnnotations_attribute
)
attrs
.
get
(
Attribute
.
RuntimeInvisibleAnnotations
);
if
(
annots
!=
null
)
{
for
(
Annotation
a:
annots
.
annotations
)
{
if
(
cp
.
getUTF8Value
(
a
.
type_index
).
equals
(
"L"
+
annotName
+
";"
))
{
Annotation
.
Primitive_element_value
pv0
=
(
Annotation
.
Primitive_element_value
)
a
.
element_value_pairs
[
0
].
value
;
Annotation
.
Primitive_element_value
pv1
=
(
Annotation
.
Primitive_element_value
)
a
.
element_value_pairs
[
1
].
value
;
return
new
AnnotValues
(
cp
.
getUTF8Value
(
pv0
.
const_value_index
),
cp
.
getUTF8Value
(
pv1
.
const_value_index
));
}
}
}
return
null
;
}
void
checkEqual
(
String
expect
,
String
found
)
{
if
(!(
expect
==
null
?
found
==
null
:
expect
.
equals
(
found
)))
{
System
.
err
.
println
(
"expected: "
+
expect
);
System
.
err
.
println
(
" found: "
+
found
);
error
(
"unexpected values found"
);
}
}
void
error
(
String
msg
)
{
System
.
err
.
println
(
"error: "
+
msg
);
errors
++;
}
int
errors
;
TypePrinter
tp
=
new
TypePrinter
();
class
TypePrinter
implements
Type
.
Visitor
<
String
,
Void
>
{
String
print
(
Type
t
)
{
return
t
==
null
?
null
:
t
.
accept
(
this
,
null
);
}
String
print
(
String
pre
,
List
<?
extends
Type
>
ts
,
String
post
)
{
if
(
ts
==
null
)
return
null
;
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
pre
);
String
sep
=
""
;
for
(
Type
t:
ts
)
{
sb
.
append
(
sep
);
sb
.
append
(
print
(
t
));
sep
=
","
;
}
sb
.
append
(
post
);
return
sb
.
toString
();
}
public
String
visitSimpleType
(
SimpleType
type
,
Void
p
)
{
return
"S{"
+
type
.
name
+
"}"
;
}
public
String
visitArrayType
(
ArrayType
type
,
Void
p
)
{
return
"A{"
+
print
(
type
.
elemType
)
+
"}"
;
}
public
String
visitMethodType
(
MethodType
type
,
Void
p
)
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"M{"
);
if
(
type
.
typeParamTypes
!=
null
)
sb
.
append
(
print
(
"<"
,
type
.
typeParamTypes
,
">"
));
sb
.
append
(
print
(
type
.
returnType
));
sb
.
append
(
print
(
"("
,
type
.
paramTypes
,
")"
));
if
(
type
.
throwsTypes
!=
null
)
sb
.
append
(
print
(
""
,
type
.
throwsTypes
,
""
));
sb
.
append
(
"}"
);
return
sb
.
toString
();
}
public
String
visitClassSigType
(
ClassSigType
type
,
Void
p
)
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"CS{"
);
if
(
type
.
typeParamTypes
!=
null
)
sb
.
append
(
print
(
"<"
,
type
.
typeParamTypes
,
">"
));
sb
.
append
(
print
(
type
.
superclassType
));
if
(
type
.
superinterfaceTypes
!=
null
)
sb
.
append
(
print
(
"i("
,
type
.
superinterfaceTypes
,
")"
));
sb
.
append
(
"}"
);
return
sb
.
toString
();
}
public
String
visitClassType
(
ClassType
type
,
Void
p
)
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"C{"
);
if
(
type
.
outerType
!=
null
)
{
sb
.
append
(
print
(
type
.
outerType
));
sb
.
append
(
"."
);
}
sb
.
append
(
type
.
name
);
if
(
type
.
typeArgs
!=
null
)
sb
.
append
(
print
(
"<"
,
type
.
typeArgs
,
">"
));
sb
.
append
(
"}"
);
return
sb
.
toString
();
}
public
String
visitTypeParamType
(
TypeParamType
type
,
Void
p
)
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"TA{"
);
sb
.
append
(
type
.
name
);
if
(
type
.
classBound
!=
null
)
{
sb
.
append
(
":c"
);
sb
.
append
(
print
(
type
.
classBound
));
}
if
(
type
.
interfaceBounds
!=
null
)
sb
.
append
(
print
(
":i"
,
type
.
interfaceBounds
,
""
));
sb
.
append
(
"}"
);
return
sb
.
toString
();
}
public
String
visitWildcardType
(
WildcardType
type
,
Void
p
)
{
switch
(
type
.
kind
)
{
case
UNBOUNDED:
return
"W{?}"
;
case
EXTENDS:
return
"W{e,"
+
print
(
type
.
boundType
)
+
"}"
;
case
SUPER:
return
"W{s,"
+
print
(
type
.
boundType
)
+
"}"
;
default
:
throw
new
AssertionError
();
}
}
};
}
@interface
Desc
{
String
d
();
String
t
();
}
@interface
Sig
{
String
s
();
String
t
();
}
class
Clss
{
}
interface
Intf
{
}
class
GenClss
<
T
>
{
}
class
Test
{
// fields
@Desc
(
d
=
"Z"
,
t
=
"S{boolean}"
)
boolean
z
;
@Desc
(
d
=
"B"
,
t
=
"S{byte}"
)
byte
b
;
@Desc
(
d
=
"C"
,
t
=
"S{char}"
)
char
c
;
@Desc
(
d
=
"D"
,
t
=
"S{double}"
)
double
d
;
@Desc
(
d
=
"F"
,
t
=
"S{float}"
)
float
f
;
@Desc
(
d
=
"I"
,
t
=
"S{int}"
)
int
i
;
@Desc
(
d
=
"J"
,
t
=
"S{long}"
)
long
l
;
@Desc
(
d
=
"S"
,
t
=
"S{short}"
)
short
s
;
@Desc
(
d
=
"LClss;"
,
t
=
"C{Clss}"
)
Clss
clss
;
@Desc
(
d
=
"LIntf;"
,
t
=
"C{Intf}"
)
Intf
intf
;
@Desc
(
d
=
"[I"
,
t
=
"A{S{int}}"
)
int
[]
ai
;
@Desc
(
d
=
"[LClss;"
,
t
=
"A{C{Clss}}"
)
Clss
[]
aClss
;
@Desc
(
d
=
"LGenClss;"
,
t
=
"C{GenClss}"
)
@Sig
(
s
=
"LGenClss<LClss;>;"
,
t
=
"C{GenClss<C{Clss}>}"
)
GenClss
<
Clss
>
genClass
;
// methods, return types
@Desc
(
d
=
"()V"
,
t
=
"M{S{void}()}"
)
void
mv0
()
{
}
@Desc
(
d
=
"()I"
,
t
=
"M{S{int}()}"
)
int
mi0
()
{
return
0
;
}
@Desc
(
d
=
"()LClss;"
,
t
=
"M{C{Clss}()}"
)
Clss
mclss0
()
{
return
null
;
}
@Desc
(
d
=
"()[I"
,
t
=
"M{A{S{int}}()}"
)
int
[]
mai0
()
{
return
null
;
}
@Desc
(
d
=
"()[LClss;"
,
t
=
"M{A{C{Clss}}()}"
)
Clss
[]
maClss0
()
{
return
null
;
}
@Desc
(
d
=
"()LGenClss;"
,
t
=
"M{C{GenClss}()}"
)
@Sig
(
s
=
"()LGenClss<LClss;>;"
,
t
=
"M{C{GenClss<C{Clss}>}()}"
)
GenClss
<
Clss
>
mgenClss0
()
{
return
null
;
}
@Desc
(
d
=
"()LGenClss;"
,
t
=
"M{C{GenClss}()}"
)
@Sig
(
s
=
"()LGenClss<*>;"
,
t
=
"M{C{GenClss<W{?}>}()}"
)
GenClss
<?>
mgenClssW0
()
{
return
null
;
}
@Desc
(
d
=
"()LGenClss;"
,
t
=
"M{C{GenClss}()}"
)
@Sig
(
s
=
"()LGenClss<+LClss;>;"
,
t
=
"M{C{GenClss<W{e,C{Clss}}>}()}"
)
GenClss
<?
extends
Clss
>
mgenClssWExtClss0
()
{
return
null
;
}
@Desc
(
d
=
"()LGenClss;"
,
t
=
"M{C{GenClss}()}"
)
@Sig
(
s
=
"()LGenClss<-LClss;>;"
,
t
=
"M{C{GenClss<W{s,C{Clss}}>}()}"
)
GenClss
<?
super
Clss
>
mgenClssWSupClss0
()
{
return
null
;
}
@Desc
(
d
=
"()Ljava/lang/Object;"
,
t
=
"M{C{java/lang/Object}()}"
)
@Sig
(
s
=
"<T:Ljava/lang/Object;>()TT;"
,
t
=
"M{<TA{T:cC{java/lang/Object}}>S{T}()}"
)
<
T
>
T
mt0
()
{
return
null
;
}
@Desc
(
d
=
"()LGenClss;"
,
t
=
"M{C{GenClss}()}"
)
@Sig
(
s
=
"<T:Ljava/lang/Object;>()LGenClss<+TT;>;"
,
t
=
"M{<TA{T:cC{java/lang/Object}}>C{GenClss<W{e,S{T}}>}()}"
)
<
T
>
GenClss
<?
extends
T
>
mgenClssWExtT0
()
{
return
null
;
}
@Desc
(
d
=
"()LGenClss;"
,
t
=
"M{C{GenClss}()}"
)
@Sig
(
s
=
"<T:Ljava/lang/Object;>()LGenClss<-TT;>;"
,
t
=
"M{<TA{T:cC{java/lang/Object}}>C{GenClss<W{s,S{T}}>}()}"
)
<
T
>
GenClss
<?
super
T
>
mgenClssWSupT0
()
{
return
null
;
}
// methods, arg types
@Desc
(
d
=
"(I)V"
,
t
=
"M{S{void}(S{int})}"
)
void
mi1
(
int
arg
)
{
}
@Desc
(
d
=
"(LClss;)V"
,
t
=
"M{S{void}(C{Clss})}"
)
void
mclss1
(
Clss
arg
)
{
}
@Desc
(
d
=
"([I)V"
,
t
=
"M{S{void}(A{S{int}})}"
)
void
mai1
(
int
[]
arg
)
{
}
@Desc
(
d
=
"([LClss;)V"
,
t
=
"M{S{void}(A{C{Clss}})}"
)
void
maClss1
(
Clss
[]
arg
)
{
}
@Desc
(
d
=
"(LGenClss;)V"
,
t
=
"M{S{void}(C{GenClss})}"
)
@Sig
(
s
=
"(LGenClss<LClss;>;)V"
,
t
=
"M{S{void}(C{GenClss<C{Clss}>})}"
)
void
mgenClss1
(
GenClss
<
Clss
>
arg
)
{
}
@Desc
(
d
=
"(LGenClss;)V"
,
t
=
"M{S{void}(C{GenClss})}"
)
@Sig
(
s
=
"(LGenClss<*>;)V"
,
t
=
"M{S{void}(C{GenClss<W{?}>})}"
)
void
mgenClssW1
(
GenClss
<?>
arg
)
{
}
@Desc
(
d
=
"(LGenClss;)V"
,
t
=
"M{S{void}(C{GenClss})}"
)
@Sig
(
s
=
"(LGenClss<+LClss;>;)V"
,
t
=
"M{S{void}(C{GenClss<W{e,C{Clss}}>})}"
)
void
mgenClssWExtClss1
(
GenClss
<?
extends
Clss
>
arg
)
{
}
@Desc
(
d
=
"(LGenClss;)V"
,
t
=
"M{S{void}(C{GenClss})}"
)
@Sig
(
s
=
"(LGenClss<-LClss;>;)V"
,
t
=
"M{S{void}(C{GenClss<W{s,C{Clss}}>})}"
)
void
mgenClssWSupClss1
(
GenClss
<?
super
Clss
>
arg
)
{
}
@Desc
(
d
=
"(Ljava/lang/Object;)V"
,
t
=
"M{S{void}(C{java/lang/Object})}"
)
@Sig
(
s
=
"<T:Ljava/lang/Object;>(TT;)V"
,
t
=
"M{<TA{T:cC{java/lang/Object}}>S{void}(S{T})}"
)
<
T
>
void
mt1
(
T
arg
)
{
}
@Desc
(
d
=
"(LGenClss;)V"
,
t
=
"M{S{void}(C{GenClss})}"
)
@Sig
(
s
=
"<T:Ljava/lang/Object;>(LGenClss<+TT;>;)V"
,
t
=
"M{<TA{T:cC{java/lang/Object}}>S{void}(C{GenClss<W{e,S{T}}>})}"
)
<
T
>
void
mgenClssWExtT1
(
GenClss
<?
extends
T
>
arg
)
{
}
@Desc
(
d
=
"(LGenClss;)V"
,
t
=
"M{S{void}(C{GenClss})}"
)
@Sig
(
s
=
"<T:Ljava/lang/Object;>(LGenClss<-TT;>;)V"
,
t
=
"M{<TA{T:cC{java/lang/Object}}>S{void}(C{GenClss<W{s,S{T}}>})}"
)
<
T
>
void
mgenClssWSupT1
(
GenClss
<?
super
T
>
arg
)
{
}
// methods, throws
@Desc
(
d
=
"()V"
,
t
=
"M{S{void}()}"
)
void
m_E
()
throws
Exception
{
}
@Desc
(
d
=
"()V"
,
t
=
"M{S{void}()}"
)
@Sig
(
s
=
"<T:Ljava/lang/Throwable;>()V^TT;"
,
t
=
"M{<TA{T:cC{java/lang/Throwable}}>S{void}()S{T}}"
)
<
T
extends
Throwable
>
void
m_T
()
throws
T
{
}
// inner classes
static
class
X
{
// no sig
class
P
{
}
@Sig
(
s
=
"<TQ:Ljava/lang/Object;>LTest$X$P;"
,
t
=
"CS{<TA{TQ:cC{java/lang/Object}}>C{Test$X$P}}"
)
class
Q
<
TQ
>
extends
P
{
}
@Sig
(
s
=
"<TR:Ljava/lang/Object;>LTest$X$Q<TTR;>;"
,
t
=
"CS{<TA{TR:cC{java/lang/Object}}>C{Test$X$Q<S{TR}>}}"
)
class
R
<
TR
>
extends
Q
<
TR
>
{
}
}
@Sig
(
s
=
"<TY:Ljava/lang/Object;>Ljava/lang/Object;"
,
t
=
"CS{<TA{TY:cC{java/lang/Object}}>C{java/lang/Object}}"
)
static
class
Y
<
TY
>
{
// no sig
class
P
{
}
@Sig
(
s
=
"<TQ:Ljava/lang/Object;>LTest$Y<TTY;>.P;"
,
t
=
"CS{<TA{TQ:cC{java/lang/Object}}>C{C{Test$Y<S{TY}>}.P}}"
)
class
Q
<
TQ
>
extends
P
{
}
@Sig
(
s
=
"<TR:Ljava/lang/Object;>LTest$Y<TTY;>.Q<TTR;>;"
,
t
=
"CS{<TA{TR:cC{java/lang/Object}}>C{C{Test$Y<S{TY}>}.Q<S{TR}>}}"
)
class
R
<
TR
>
extends
Q
<
TR
>
{
// no sig
class
R1
{
}
@Sig
(
s
=
"<TR2:Ljava/lang/Object;>LTest$Y<TTY;>.R<TTR;>.R1;"
,
t
=
"CS{<TA{TR2:cC{java/lang/Object}}>C{C{C{Test$Y<S{TY}>}.R<S{TR}>}.R1}}"
)
class
R2
<
TR2
>
extends
R1
{
}
}
@Sig
(
s
=
"LTest$Y<TTY;>.Q<TTY;>;"
,
t
=
"C{C{Test$Y<S{TY}>}.Q<S{TY}>}"
)
class
S
extends
Q
<
TY
>
{
// no sig
class
S1
{
}
@Sig
(
s
=
"<TS2:Ljava/lang/Object;>LTest$Y<TTY;>.S.S1;"
,
t
=
"CS{<TA{TS2:cC{java/lang/Object}}>C{C{C{Test$Y<S{TY}>}.S}.S1}}"
)
class
S2
<
TS2
>
extends
S1
{
}
@Sig
(
s
=
"LTest$Y<TTY;>.S.S2<TTY;>;"
,
t
=
"C{C{C{Test$Y<S{TY}>}.S}.S2<S{TY}>}"
)
class
S3
extends
S2
<
TY
>
{
}
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录