Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_langtools
提交
7dd21645
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看板
提交
7dd21645
编写于
7月 17, 2013
作者:
L
lana
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
ba41a7fc
0cf33533
变更
21
隐藏空白更改
内联
并排
Showing
21 changed file
with
1043 addition
and
84 deletion
+1043
-84
.hgtags
.hgtags
+1
-0
src/share/classes/com/sun/tools/javac/code/Types.java
src/share/classes/com/sun/tools/javac/code/Types.java
+86
-0
src/share/classes/com/sun/tools/javac/comp/Attr.java
src/share/classes/com/sun/tools/javac/comp/Attr.java
+19
-21
src/share/classes/com/sun/tools/javac/comp/Check.java
src/share/classes/com/sun/tools/javac/comp/Check.java
+0
-18
src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
...hare/classes/com/sun/tools/javac/comp/LambdaToMethod.java
+61
-32
src/share/classes/com/sun/tools/javac/comp/TransTypes.java
src/share/classes/com/sun/tools/javac/comp/TransTypes.java
+9
-4
src/share/classes/com/sun/tools/javac/tree/JCTree.java
src/share/classes/com/sun/tools/javac/tree/JCTree.java
+5
-3
src/share/classes/com/sun/tools/javac/util/Names.java
src/share/classes/com/sun/tools/javac/util/Names.java
+4
-4
test/tools/javac/generics/bridges/Bridge.java
test/tools/javac/generics/bridges/Bridge.java
+28
-0
test/tools/javac/generics/bridges/BridgeHarness.java
test/tools/javac/generics/bridges/BridgeHarness.java
+218
-0
test/tools/javac/generics/bridges/Bridges.java
test/tools/javac/generics/bridges/Bridges.java
+25
-0
test/tools/javac/generics/bridges/tests/TestBridgeWithDefault.java
...s/javac/generics/bridges/tests/TestBridgeWithDefault.java
+31
-0
test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical01.java
...bridges/tests/TestClassAndInterfaceBridgeIdentical01.java
+45
-0
test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical02.java
...bridges/tests/TestClassAndInterfaceBridgeIdentical02.java
+45
-0
test/tools/javac/generics/bridges/tests/TestNoBridgeInSiblingsSuper.java
...c/generics/bridges/tests/TestNoBridgeInSiblingsSuper.java
+34
-0
test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges01.java
...avac/generics/bridges/tests/TestNoDuplicateBridges01.java
+29
-0
test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges02.java
...avac/generics/bridges/tests/TestNoDuplicateBridges02.java
+38
-0
test/tools/javac/lambda/bridge/TestMetafactoryBridges.java
test/tools/javac/lambda/bridge/TestMetafactoryBridges.java
+359
-0
test/tools/javac/lambda/lambdaExpression/LambdaTest6.java
test/tools/javac/lambda/lambdaExpression/LambdaTest6.java
+1
-1
test/tools/javac/lambda/methodReference/BridgeMethod.java
test/tools/javac/lambda/methodReference/BridgeMethod.java
+1
-1
test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java
...lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java
+4
-0
未找到文件。
.hgtags
浏览文件 @
7dd21645
...
...
@@ -219,3 +219,4 @@ e19283cd30a43fca94d8f7639c73ef66db493b1e jdk8-b90
4cb1136231275a1f8af53f5bfdef0b488e4b5bab jdk8-b95
988aef3a8c3adac482363293f65e77ec4c5ce98d jdk8-b96
6a11a81a8824c17f6cd2ec8f8492e1229b694e96 jdk8-b97
ce5a90df517bdceb2739d7dd3e6764b070def802 jdk8-b98
src/share/classes/com/sun/tools/javac/code/Types.java
浏览文件 @
7dd21645
...
...
@@ -33,10 +33,15 @@ import java.util.Map;
import
java.util.Set
;
import
java.util.WeakHashMap
;
import
javax.tools.JavaFileObject
;
import
com.sun.tools.javac.code.Attribute.RetentionPolicy
;
import
com.sun.tools.javac.code.Lint.LintCategory
;
import
com.sun.tools.javac.code.Type.UndetVar.InferenceBound
;
import
com.sun.tools.javac.comp.AttrContext
;
import
com.sun.tools.javac.comp.Check
;
import
com.sun.tools.javac.comp.Enter
;
import
com.sun.tools.javac.comp.Env
;
import
com.sun.tools.javac.jvm.ClassReader
;
import
com.sun.tools.javac.util.*
;
import
static
com
.
sun
.
tools
.
javac
.
code
.
BoundKind
.*;
...
...
@@ -83,6 +88,7 @@ public class Types {
final
boolean
allowDefaultMethods
;
final
ClassReader
reader
;
final
Check
chk
;
final
Enter
enter
;
JCDiagnostic
.
Factory
diags
;
List
<
Warner
>
warnStack
=
List
.
nil
();
final
Name
capturedName
;
...
...
@@ -109,6 +115,7 @@ public class Types {
allowDefaultMethods
=
source
.
allowDefaultMethods
();
reader
=
ClassReader
.
instance
(
context
);
chk
=
Check
.
instance
(
context
);
enter
=
Enter
.
instance
(
context
);
capturedName
=
names
.
fromString
(
"<captured wildcard>"
);
messages
=
JavacMessages
.
instance
(
context
);
diags
=
JCDiagnostic
.
Factory
.
instance
(
context
);
...
...
@@ -605,6 +612,84 @@ public class Types {
return
site
;
}
}
/**
* Create a symbol for a class that implements a given functional interface
* and overrides its functional descriptor. This routine is used for two
* main purposes: (i) checking well-formedness of a functional interface;
* (ii) perform functional interface bridge calculation.
*/
public
ClassSymbol
makeFunctionalInterfaceClass
(
Env
<
AttrContext
>
env
,
Name
name
,
List
<
Type
>
targets
,
long
cflags
)
{
Assert
.
check
(
targets
.
nonEmpty
()
&&
isFunctionalInterface
(
targets
.
head
));
Symbol
descSym
=
findDescriptorSymbol
(
targets
.
head
.
tsym
);
Type
descType
=
findDescriptorType
(
targets
.
head
);
ClassSymbol
csym
=
new
ClassSymbol
(
cflags
,
name
,
env
.
enclClass
.
sym
.
outermostClass
());
csym
.
completer
=
null
;
csym
.
members_field
=
new
Scope
(
csym
);
MethodSymbol
instDescSym
=
new
MethodSymbol
(
descSym
.
flags
(),
descSym
.
name
,
descType
,
csym
);
csym
.
members_field
.
enter
(
instDescSym
);
Type
.
ClassType
ctype
=
new
Type
.
ClassType
(
Type
.
noType
,
List
.<
Type
>
nil
(),
csym
);
ctype
.
supertype_field
=
syms
.
objectType
;
ctype
.
interfaces_field
=
targets
;
csym
.
type
=
ctype
;
csym
.
sourcefile
=
((
ClassSymbol
)
csym
.
owner
).
sourcefile
;
return
csym
;
}
/**
* Find the minimal set of methods that are overridden by the functional
* descriptor in 'origin'. All returned methods are assumed to have different
* erased signatures.
*/
public
List
<
Symbol
>
functionalInterfaceBridges
(
TypeSymbol
origin
)
{
Assert
.
check
(
isFunctionalInterface
(
origin
));
Symbol
descSym
=
findDescriptorSymbol
(
origin
);
CompoundScope
members
=
membersClosure
(
origin
.
type
,
false
);
ListBuffer
<
Symbol
>
overridden
=
ListBuffer
.
lb
();
outer:
for
(
Symbol
m2
:
members
.
getElementsByName
(
descSym
.
name
,
bridgeFilter
))
{
if
(
m2
==
descSym
)
continue
;
else
if
(
descSym
.
overrides
(
m2
,
origin
,
Types
.
this
,
false
))
{
for
(
Symbol
m3
:
overridden
)
{
if
(
isSameType
(
m3
.
erasure
(
Types
.
this
),
m2
.
erasure
(
Types
.
this
))
||
(
m3
.
overrides
(
m2
,
origin
,
Types
.
this
,
false
)
&&
(
pendingBridges
((
ClassSymbol
)
origin
,
m3
.
enclClass
())
||
(((
MethodSymbol
)
m2
).
binaryImplementation
((
ClassSymbol
)
m3
.
owner
,
Types
.
this
)
!=
null
))))
{
continue
outer
;
}
}
overridden
.
add
(
m2
);
}
}
return
overridden
.
toList
();
}
//where
private
Filter
<
Symbol
>
bridgeFilter
=
new
Filter
<
Symbol
>()
{
public
boolean
accepts
(
Symbol
t
)
{
return
t
.
kind
==
Kinds
.
MTH
&&
t
.
name
!=
names
.
init
&&
t
.
name
!=
names
.
clinit
&&
(
t
.
flags
()
&
SYNTHETIC
)
==
0
;
}
};
private
boolean
pendingBridges
(
ClassSymbol
origin
,
TypeSymbol
s
)
{
//a symbol will be completed from a classfile if (a) symbol has
//an associated file object with CLASS kind and (b) the symbol has
//not been entered
if
(
origin
.
classfile
!=
null
&&
origin
.
classfile
.
getKind
()
==
JavaFileObject
.
Kind
.
CLASS
&&
enter
.
getEnv
(
origin
)
==
null
)
{
return
false
;
}
if
(
origin
==
s
)
{
return
true
;
}
for
(
Type
t
:
interfaces
(
origin
.
type
))
{
if
(
pendingBridges
((
ClassSymbol
)
t
.
tsym
,
s
))
{
return
true
;
}
}
return
false
;
}
// </editor-fold>
/**
...
...
@@ -2672,6 +2757,7 @@ public class Types {
public
boolean
accepts
(
Symbol
s
)
{
return
s
.
kind
==
Kinds
.
MTH
&&
s
.
name
==
msym
.
name
&&
(
s
.
flags
()
&
SYNTHETIC
)
==
0
&&
s
.
isInheritedIn
(
site
.
tsym
,
Types
.
this
)
&&
overrideEquivalent
(
memberType
(
site
,
s
),
memberType
(
site
,
msym
));
}
...
...
src/share/classes/com/sun/tools/javac/comp/Attr.java
浏览文件 @
7dd21645
...
...
@@ -2330,13 +2330,12 @@ public class Attr extends JCTree.Visitor {
if
(
pt
()
!=
Type
.
recoveryType
)
{
target
=
targetChecker
.
visit
(
target
,
that
);
lambdaType
=
types
.
findDescriptorType
(
target
);
chk
.
checkFunctionalInterface
(
that
,
target
);
}
else
{
target
=
Type
.
recoveryType
;
lambdaType
=
fallbackDescriptorType
(
that
);
}
setFunctionalInfo
(
that
,
pt
(),
lambdaType
,
target
,
resultInfo
.
checkContext
.
inferenceContext
()
);
setFunctionalInfo
(
localEnv
,
that
,
pt
(),
lambdaType
,
target
,
resultInfo
.
checkContext
);
if
(
lambdaType
.
hasTag
(
FORALL
))
{
//lambda expression target desc cannot be a generic method
...
...
@@ -2715,13 +2714,12 @@ public class Attr extends JCTree.Visitor {
if
(
pt
()
!=
Type
.
recoveryType
)
{
target
=
targetChecker
.
visit
(
pt
(),
that
);
desc
=
types
.
findDescriptorType
(
target
);
chk
.
checkFunctionalInterface
(
that
,
target
);
}
else
{
target
=
Type
.
recoveryType
;
desc
=
fallbackDescriptorType
(
that
);
}
setFunctionalInfo
(
that
,
pt
(),
desc
,
target
,
resultInfo
.
checkContext
.
inferenceContext
()
);
setFunctionalInfo
(
localEnv
,
that
,
pt
(),
desc
,
target
,
resultInfo
.
checkContext
);
List
<
Type
>
argtypes
=
desc
.
getParameterTypes
();
Resolve
.
MethodCheck
referenceCheck
=
rs
.
resolveMethodCheck
;
...
...
@@ -2941,31 +2939,37 @@ public class Attr extends JCTree.Visitor {
* might contain inference variables, we might need to register an hook in the
* current inference context.
*/
private
void
setFunctionalInfo
(
final
JCFunctionalExpression
fExpr
,
final
Type
pt
,
final
Type
descriptorType
,
final
Type
primaryTarget
,
InferenceContext
inference
Context
)
{
if
(
inferenceContext
.
free
(
descriptorType
))
{
inferenceContext
.
addFreeTypeListener
(
List
.
of
(
pt
,
descriptorType
),
new
FreeTypeListener
()
{
private
void
setFunctionalInfo
(
final
Env
<
AttrContext
>
env
,
final
JCFunctionalExpression
fExpr
,
final
Type
pt
,
final
Type
descriptorType
,
final
Type
primaryTarget
,
final
CheckContext
check
Context
)
{
if
(
checkContext
.
inferenceContext
()
.
free
(
descriptorType
))
{
checkContext
.
inferenceContext
()
.
addFreeTypeListener
(
List
.
of
(
pt
,
descriptorType
),
new
FreeTypeListener
()
{
public
void
typesInferred
(
InferenceContext
inferenceContext
)
{
setFunctionalInfo
(
fExpr
,
pt
,
inferenceContext
.
asInstType
(
descriptorType
),
inferenceContext
.
asInstType
(
primaryTarget
),
inference
Context
);
setFunctionalInfo
(
env
,
fExpr
,
pt
,
inferenceContext
.
asInstType
(
descriptorType
),
inferenceContext
.
asInstType
(
primaryTarget
),
check
Context
);
}
});
}
else
{
ListBuffer
<
Type
Symbol
>
targets
=
ListBuffer
.
lb
();
ListBuffer
<
Type
>
targets
=
ListBuffer
.
lb
();
if
(
pt
.
hasTag
(
CLASS
))
{
if
(
pt
.
isCompound
())
{
targets
.
append
(
primaryTarget
.
tsym
);
//this goes first
targets
.
append
(
types
.
removeWildcards
(
primaryTarget
)
);
//this goes first
for
(
Type
t
:
((
IntersectionClassType
)
pt
()).
interfaces_field
)
{
if
(
t
!=
primaryTarget
)
{
targets
.
append
(
t
.
tsym
);
targets
.
append
(
t
ypes
.
removeWildcards
(
t
)
);
}
}
}
else
{
targets
.
append
(
pt
.
tsym
);
targets
.
append
(
types
.
removeWildcards
(
primaryTarget
)
);
}
}
fExpr
.
targets
=
targets
.
toList
();
fExpr
.
descriptorType
=
descriptorType
;
if
(
checkContext
.
deferredAttrContext
().
mode
==
DeferredAttr
.
AttrMode
.
CHECK
&&
pt
!=
Type
.
recoveryType
)
{
//check that functional interface class is well-formed
ClassSymbol
csym
=
types
.
makeFunctionalInterfaceClass
(
env
,
names
.
empty
,
List
.
of
(
fExpr
.
targets
.
head
),
ABSTRACT
);
chk
.
checkImplementations
(
env
.
tree
,
csym
,
csym
);
}
}
}
...
...
@@ -4644,9 +4648,6 @@ public class Attr extends JCTree.Visitor {
@Override
public
void
visitLambda
(
JCLambda
that
)
{
super
.
visitLambda
(
that
);
if
(
that
.
descriptorType
==
null
)
{
that
.
descriptorType
=
syms
.
unknownType
;
}
if
(
that
.
targets
==
null
)
{
that
.
targets
=
List
.
nil
();
}
...
...
@@ -4658,9 +4659,6 @@ public class Attr extends JCTree.Visitor {
if
(
that
.
sym
==
null
)
{
that
.
sym
=
new
MethodSymbol
(
0
,
names
.
empty
,
syms
.
unknownType
,
syms
.
noSymbol
);
}
if
(
that
.
descriptorType
==
null
)
{
that
.
descriptorType
=
syms
.
unknownType
;
}
if
(
that
.
targets
==
null
)
{
that
.
targets
=
List
.
nil
();
}
...
...
src/share/classes/com/sun/tools/javac/comp/Check.java
浏览文件 @
7dd21645
...
...
@@ -2276,24 +2276,6 @@ public class Check {
c
.
flags_field
|=
ACYCLIC
;
}
/**
* Check that functional interface methods would make sense when seen
* from the perspective of the implementing class
*/
void
checkFunctionalInterface
(
JCTree
tree
,
Type
funcInterface
)
{
ClassType
c
=
new
ClassType
(
Type
.
noType
,
List
.<
Type
>
nil
(),
null
);
ClassSymbol
csym
=
new
ClassSymbol
(
0
,
names
.
empty
,
c
,
syms
.
noSymbol
);
c
.
interfaces_field
=
List
.
of
(
types
.
removeWildcards
(
funcInterface
));
c
.
supertype_field
=
syms
.
objectType
;
c
.
tsym
=
csym
;
csym
.
members_field
=
new
Scope
(
csym
);
Symbol
descSym
=
types
.
findDescriptorSymbol
(
funcInterface
.
tsym
);
Type
descType
=
types
.
findDescriptorType
(
funcInterface
);
csym
.
members_field
.
enter
(
new
MethodSymbol
(
PUBLIC
,
descSym
.
name
,
descType
,
csym
));
csym
.
completer
=
null
;
checkImplementations
(
tree
,
csym
,
csym
);
}
/** Check that all methods which implement some
* method conform to the method they implement.
* @param tree The class definition whose members are checked.
...
...
src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
浏览文件 @
7dd21645
...
...
@@ -100,6 +100,9 @@ public class LambdaToMethod extends TreeTranslator {
/** Flag for alternate metafactories indicating the lambda object has multiple targets */
public
static
final
int
FLAG_MARKERS
=
1
<<
1
;
/** Flag for alternate metafactories indicating the lambda object requires multiple bridges */
public
static
final
int
FLAG_BRIDGES
=
1
<<
2
;
private
class
KlassInfo
{
/**
...
...
@@ -321,7 +324,7 @@ public class LambdaToMethod extends TreeTranslator {
int
refKind
=
referenceKind
(
sym
);
//convert to an invokedynamic call
result
=
makeMeta
FactoryIndyCall
(
tree
,
context
.
needsAltMetafactory
(),
context
.
isSerializable
()
,
refKind
,
sym
,
indy_args
);
result
=
makeMeta
factoryIndyCall
(
context
,
refKind
,
sym
,
indy_args
);
}
private
JCIdent
makeThis
(
Type
type
,
Symbol
owner
)
{
...
...
@@ -382,7 +385,7 @@ public class LambdaToMethod extends TreeTranslator {
//build a sam instance using an indy call to the meta-factory
result
=
makeMeta
FactoryIndyCall
(
tree
,
localContext
.
needsAltMetafactory
(),
localContext
.
isSerializable
()
,
localContext
.
referenceKind
(),
refSym
,
indy_args
);
result
=
makeMeta
factoryIndyCall
(
localContext
,
localContext
.
referenceKind
(),
refSym
,
indy_args
);
}
/**
...
...
@@ -606,8 +609,8 @@ public class LambdaToMethod extends TreeTranslator {
make
.
Return
(
makeIndyCall
(
pos
,
syms
.
lambdaMetafactory
,
names
.
altMeta
F
actory
,
staticArgs
,
indyType
,
serArgs
.
toList
())),
names
.
altMeta
f
actory
,
staticArgs
,
indyType
,
serArgs
.
toList
()
,
samSym
.
name
)),
null
);
ListBuffer
<
JCStatement
>
stmts
=
kInfo
.
deserializeCases
.
get
(
implMethodName
);
if
(
stmts
==
null
)
{
...
...
@@ -905,22 +908,26 @@ public class LambdaToMethod extends TreeTranslator {
kInfo
.
addMethod
(
new
MemberReferenceBridger
(
tree
,
localContext
).
bridge
());
}
private
MethodType
typeToMethodType
(
Type
mt
)
{
Type
type
=
types
.
erasure
(
mt
);
return
new
MethodType
(
type
.
getParameterTypes
(),
type
.
getReturnType
(),
type
.
getThrownTypes
(),
syms
.
methodClass
);
}
/**
* Generate an indy method call to the meta factory
*/
private
JCExpression
makeMetaFactoryIndyCall
(
JCFunctionalExpression
tree
,
boolean
needsAltMetafactory
,
boolean
isSerializable
,
int
refKind
,
Symbol
refSym
,
List
<
JCExpression
>
indy_args
)
{
private
JCExpression
makeMetafactoryIndyCall
(
TranslationContext
<?>
context
,
int
refKind
,
Symbol
refSym
,
List
<
JCExpression
>
indy_args
)
{
JCFunctionalExpression
tree
=
context
.
tree
;
//determine the static bsm args
Type
mtype
=
types
.
erasure
(
tree
.
descriptorType
);
MethodSymbol
samSym
=
(
MethodSymbol
)
types
.
findDescriptorSymbol
(
tree
.
type
.
tsym
);
List
<
Object
>
staticArgs
=
List
.<
Object
>
of
(
new
Pool
.
MethodHandle
(
ClassFile
.
REF_invokeInterface
,
types
.
findDescriptorSymbol
(
tree
.
type
.
tsym
),
types
),
typeToMethodType
(
samSym
.
type
),
new
Pool
.
MethodHandle
(
refKind
,
refSym
,
types
),
new
MethodType
(
mtype
.
getParameterTypes
(),
mtype
.
getReturnType
(),
mtype
.
getThrownTypes
(),
syms
.
methodClass
));
typeToMethodType
(
tree
.
getDescriptorType
(
types
)));
//computed indy arg types
ListBuffer
<
Type
>
indy_args_types
=
ListBuffer
.
lb
();
...
...
@@ -934,31 +941,46 @@ public class LambdaToMethod extends TreeTranslator {
List
.<
Type
>
nil
(),
syms
.
methodClass
);
Name
metafactoryName
=
needsAltMetafactory
?
names
.
altMeta
Factory
:
names
.
metaF
actory
;
Name
metafactoryName
=
context
.
needsAltMetafactory
()
?
names
.
altMeta
factory
:
names
.
metaf
actory
;
if
(
needsAltMetafactory
)
{
if
(
context
.
needsAltMetafactory
()
)
{
ListBuffer
<
Object
>
markers
=
ListBuffer
.
lb
();
for
(
Symbol
t
:
tree
.
targets
.
tail
)
{
if
(
t
!=
syms
.
serializableType
.
tsym
)
{
markers
.
append
(
t
);
for
(
Type
t
:
tree
.
targets
.
tail
)
{
if
(
t
.
tsym
!=
syms
.
serializableType
.
tsym
)
{
markers
.
append
(
t
.
tsym
);
}
}
int
flags
=
isSerializable
?
FLAG_SERIALIZABLE
:
0
;
int
flags
=
context
.
isSerializable
()
?
FLAG_SERIALIZABLE
:
0
;
boolean
hasMarkers
=
markers
.
nonEmpty
();
flags
|=
hasMarkers
?
FLAG_MARKERS
:
0
;
boolean
hasBridges
=
context
.
bridges
.
nonEmpty
();
if
(
hasMarkers
)
{
flags
|=
FLAG_MARKERS
;
}
if
(
hasBridges
)
{
flags
|=
FLAG_BRIDGES
;
}
staticArgs
=
staticArgs
.
append
(
flags
);
if
(
hasMarkers
)
{
staticArgs
=
staticArgs
.
append
(
markers
.
length
());
staticArgs
=
staticArgs
.
appendList
(
markers
.
toList
());
}
if
(
isSerializable
)
{
if
(
hasBridges
)
{
staticArgs
=
staticArgs
.
append
(
context
.
bridges
.
length
()
-
1
);
for
(
Symbol
s
:
context
.
bridges
)
{
Type
s_erasure
=
s
.
erasure
(
types
);
if
(!
types
.
isSameType
(
s_erasure
,
samSym
.
erasure
(
types
)))
{
staticArgs
=
staticArgs
.
append
(
s
.
erasure
(
types
));
}
}
}
if
(
context
.
isSerializable
())
{
addDeserializationCase
(
refKind
,
refSym
,
tree
.
type
,
samSym
,
tree
,
staticArgs
,
indyType
);
}
}
return
makeIndyCall
(
tree
,
syms
.
lambdaMetafactory
,
metafactoryName
,
staticArgs
,
indyType
,
indy_args
);
return
makeIndyCall
(
tree
,
syms
.
lambdaMetafactory
,
metafactoryName
,
staticArgs
,
indyType
,
indy_args
,
samSym
.
name
);
}
/**
...
...
@@ -966,7 +988,8 @@ public class LambdaToMethod extends TreeTranslator {
* arguments types
*/
private
JCExpression
makeIndyCall
(
DiagnosticPosition
pos
,
Type
site
,
Name
bsmName
,
List
<
Object
>
staticArgs
,
MethodType
indyType
,
List
<
JCExpression
>
indyArgs
)
{
List
<
Object
>
staticArgs
,
MethodType
indyType
,
List
<
JCExpression
>
indyArgs
,
Name
methName
)
{
int
prevPos
=
make
.
pos
;
try
{
make
.
at
(
pos
);
...
...
@@ -978,7 +1001,7 @@ public class LambdaToMethod extends TreeTranslator {
bsmName
,
bsm_staticArgs
,
List
.<
Type
>
nil
());
DynamicMethodSymbol
dynSym
=
new
DynamicMethodSymbol
(
names
.
lambda
,
new
DynamicMethodSymbol
(
methName
,
syms
.
noSymbol
,
bsm
.
isStatic
()
?
ClassFile
.
REF_invokeStatic
:
...
...
@@ -1299,7 +1322,6 @@ public class LambdaToMethod extends TreeTranslator {
// Make lambda holding the new-class call
JCLambda
slam
=
make
.
Lambda
(
params
,
nc
);
slam
.
descriptorType
=
tree
.
descriptorType
;
slam
.
targets
=
tree
.
targets
;
slam
.
type
=
tree
.
type
;
slam
.
pos
=
tree
.
pos
;
...
...
@@ -1634,23 +1656,30 @@ public class LambdaToMethod extends TreeTranslator {
/** the enclosing translation context (set for nested lambdas/mref) */
TranslationContext
<?>
prev
;
/** list of methods to be bridged by the meta-factory */
List
<
Symbol
>
bridges
;
TranslationContext
(
T
tree
)
{
this
.
tree
=
tree
;
this
.
owner
=
owner
();
this
.
depth
=
frameStack
.
size
()
-
1
;
this
.
prev
=
context
();
ClassSymbol
csym
=
types
.
makeFunctionalInterfaceClass
(
attrEnv
,
names
.
empty
,
tree
.
targets
,
ABSTRACT
|
INTERFACE
);
this
.
bridges
=
types
.
functionalInterfaceBridges
(
csym
);
}
/** does this functional expression need to be created using alternate metafactory? */
boolean
needsAltMetafactory
()
{
return
(
tree
.
targets
.
length
()
>
1
||
isSerializable
());
return
tree
.
targets
.
length
()
>
1
||
isSerializable
()
||
bridges
.
length
()
>
1
;
}
/** does this functional expression require serialization support? */
boolean
isSerializable
()
{
for
(
Symbol
target
:
tree
.
targets
)
{
if
(
types
.
asSuper
(
target
.
type
,
syms
.
serializableType
.
tsym
)
!=
null
)
{
for
(
Type
target
:
tree
.
targets
)
{
if
(
types
.
asSuper
(
target
,
syms
.
serializableType
.
tsym
)
!=
null
)
{
return
true
;
}
}
...
...
@@ -1833,7 +1862,7 @@ public class LambdaToMethod extends TreeTranslator {
}
Type
generatedLambdaSig
()
{
return
types
.
erasure
(
tree
.
descriptorType
);
return
types
.
erasure
(
tree
.
getDescriptorType
(
types
)
);
}
}
...
...
@@ -1909,7 +1938,7 @@ public class LambdaToMethod extends TreeTranslator {
}
Type
bridgedRefSig
()
{
return
types
.
erasure
(
types
.
findDescriptorSymbol
(
tree
.
targets
.
head
).
type
);
return
types
.
erasure
(
types
.
findDescriptorSymbol
(
tree
.
targets
.
head
.
tsym
).
type
);
}
}
}
...
...
src/share/classes/com/sun/tools/javac/comp/TransTypes.java
浏览文件 @
7dd21645
...
...
@@ -68,6 +68,7 @@ public class TransTypes extends TreeTranslator {
private
TreeMaker
make
;
private
Enter
enter
;
private
boolean
allowEnums
;
private
boolean
allowInterfaceBridges
;
private
Types
types
;
private
final
Resolve
resolve
;
...
...
@@ -91,6 +92,7 @@ public class TransTypes extends TreeTranslator {
Source
source
=
Source
.
instance
(
context
);
allowEnums
=
source
.
allowEnums
();
addBridges
=
source
.
addBridges
();
allowInterfaceBridges
=
source
.
allowDefaultMethods
();
types
=
Types
.
instance
(
context
);
make
=
TreeMaker
.
instance
(
context
);
resolve
=
Resolve
.
instance
(
context
);
...
...
@@ -252,7 +254,8 @@ public class TransTypes extends TreeTranslator {
// Create a bridge method symbol and a bridge definition without a body.
Type
bridgeType
=
meth
.
erasure
(
types
);
long
flags
=
impl
.
flags
()
&
AccessFlags
|
SYNTHETIC
|
BRIDGE
;
long
flags
=
impl
.
flags
()
&
AccessFlags
|
SYNTHETIC
|
BRIDGE
|
(
origin
.
isInterface
()
?
DEFAULT
:
0
);
if
(
hypothetical
)
flags
|=
HYPOTHETICAL
;
MethodSymbol
bridge
=
new
MethodSymbol
(
flags
,
meth
.
name
,
...
...
@@ -387,11 +390,12 @@ public class TransTypes extends TreeTranslator {
}
}
// where
Filter
<
Symbol
>
overrideBridgeFilter
=
new
Filter
<
Symbol
>()
{
private
Filter
<
Symbol
>
overrideBridgeFilter
=
new
Filter
<
Symbol
>()
{
public
boolean
accepts
(
Symbol
s
)
{
return
(
s
.
flags
()
&
(
SYNTHETIC
|
OVERRIDE_BRIDGE
))
!=
SYNTHETIC
;
}
};
/**
* @param method The symbol for which a bridge might have to be added
* @param impl The implementation of method
...
...
@@ -999,8 +1003,9 @@ public class TransTypes extends TreeTranslator {
ListBuffer
<
JCTree
>
bridges
=
new
ListBuffer
<
JCTree
>();
if
(
false
)
//see CR: 6996415
bridges
.
appendList
(
addOverrideBridgesIfNeeded
(
tree
,
c
));
if
((
tree
.
sym
.
flags
()
&
INTERFACE
)
==
0
)
addBridges
(
tree
.
pos
(),
tree
.
sym
,
bridges
);
if
(
allowInterfaceBridges
||
(
tree
.
sym
.
flags
()
&
INTERFACE
)
==
0
)
{
addBridges
(
tree
.
pos
(),
c
,
bridges
);
}
tree
.
defs
=
bridges
.
toList
().
prependList
(
tree
.
defs
);
}
tree
.
type
=
erasure
(
tree
.
type
);
...
...
src/share/classes/com/sun/tools/javac/tree/JCTree.java
浏览文件 @
7dd21645
...
...
@@ -641,10 +641,12 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
polyKind
=
PolyKind
.
POLY
;
}
/** target descriptor inferred for this functional expression. */
public
Type
descriptorType
;
/** list of target types inferred for this functional expression. */
public
List
<
TypeSymbol
>
targets
;
public
List
<
Type
>
targets
;
public
Type
getDescriptorType
(
Types
types
)
{
return
types
.
findDescriptorType
(
targets
.
head
);
}
}
/**
...
...
src/share/classes/com/sun/tools/javac/util/Names.java
浏览文件 @
7dd21645
...
...
@@ -174,8 +174,8 @@ public class Names {
//lambda-related
public
final
Name
lambda
;
public
final
Name
meta
F
actory
;
public
final
Name
altMeta
F
actory
;
public
final
Name
meta
f
actory
;
public
final
Name
altMeta
f
actory
;
public
final
Name
.
Table
table
;
...
...
@@ -310,8 +310,8 @@ public class Names {
//lambda-related
lambda
=
fromString
(
"lambda$"
);
meta
Factory
=
fromString
(
"metaF
actory"
);
altMeta
Factory
=
fromString
(
"altMetaF
actory"
);
meta
factory
=
fromString
(
"metaf
actory"
);
altMeta
factory
=
fromString
(
"altMetaf
actory"
);
}
protected
Name
.
Table
createTable
(
Options
options
)
{
...
...
test/tools/javac/generics/bridges/Bridge.java
0 → 100644
浏览文件 @
7dd21645
/*
* Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
java.lang.annotation.Repeatable
;
@Repeatable
(
Bridges
.
class
)
@interface
Bridge
{
String
value
();
}
test/tools/javac/generics/bridges/BridgeHarness.java
0 → 100644
浏览文件 @
7dd21645
/*
* Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8013789
* @summary Compiler should emit bridges in interfaces
* @library /tools/javac/lib
* @build JavacTestingAbstractProcessor BridgeHarness
* @run main BridgeHarness
*/
import
com.sun.source.util.JavacTask
;
import
com.sun.tools.classfile.AccessFlags
;
import
com.sun.tools.classfile.ClassFile
;
import
com.sun.tools.classfile.ConstantPool
;
import
com.sun.tools.classfile.ConstantPoolException
;
import
com.sun.tools.classfile.Method
;
import
com.sun.tools.javac.code.Symbol.ClassSymbol
;
import
com.sun.tools.javac.util.List
;
import
java.io.File
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Set
;
import
javax.annotation.processing.RoundEnvironment
;
import
javax.annotation.processing.SupportedAnnotationTypes
;
import
javax.lang.model.element.Element
;
import
javax.lang.model.element.TypeElement
;
import
javax.tools.JavaCompiler
;
import
javax.tools.JavaFileObject
;
import
javax.tools.StandardJavaFileManager
;
import
javax.tools.ToolProvider
;
import
static
javax
.
tools
.
StandardLocation
.*;
public
class
BridgeHarness
{
/** number of errors found (must be zero for the test to pass) */
static
int
nerrors
=
0
;
/** the (shared) Java compiler used for compiling the tests */
static
final
JavaCompiler
comp
=
ToolProvider
.
getSystemJavaCompiler
();
/** the (shared) file manager used by the compiler */
static
final
StandardJavaFileManager
fm
=
comp
.
getStandardFileManager
(
null
,
null
,
null
);
public
static
void
main
(
String
[]
args
)
throws
Exception
{
//set sourcepath
fm
.
setLocation
(
SOURCE_PATH
,
Arrays
.
asList
(
new
File
(
System
.
getProperty
(
"test.src"
),
"tests"
)));
//set output (-d)
fm
.
setLocation
(
javax
.
tools
.
StandardLocation
.
CLASS_OUTPUT
,
Arrays
.
asList
(
new
File
(
System
.
getProperty
(
"user.dir"
))));
for
(
JavaFileObject
jfo
:
fm
.
list
(
SOURCE_PATH
,
""
,
Collections
.
singleton
(
JavaFileObject
.
Kind
.
SOURCE
),
true
))
{
//for each source, compile and check against annotations
new
BridgeHarness
(
jfo
).
compileAndCheck
();
}
//if there were errors, fail
if
(
nerrors
>
0
)
{
throw
new
AssertionError
(
"Errors were found"
);
}
}
/* utility methods */
/**
* Remove an element from a list
*/
static
<
Z
>
List
<
Z
>
drop
(
List
<
Z
>
lz
,
Z
z
)
{
if
(
lz
.
head
==
z
)
{
return
drop
(
lz
.
tail
,
z
);
}
else
if
(
lz
.
isEmpty
())
{
return
lz
;
}
else
{
return
drop
(
lz
.
tail
,
z
).
prepend
(
lz
.
head
);
}
}
/**
* return a string representation of a bytecode method
*/
static
String
descriptor
(
Method
m
,
ConstantPool
cp
)
throws
ConstantPoolException
{
return
m
.
getName
(
cp
)
+
m
.
descriptor
.
getValue
(
cp
);
}
/* test harness */
/** Test file to be compiled */
JavaFileObject
jfo
;
/** Mapping between class name and list of bridges in class with that name */
Map
<
String
,
List
<
Bridge
>>
bridgesMap
=
new
HashMap
<
String
,
List
<
Bridge
>>();
protected
BridgeHarness
(
JavaFileObject
jfo
)
{
this
.
jfo
=
jfo
;
}
/**
* Compile a test using a custom annotation processor and check the generated
* bytecode against discovered annotations.
*/
protected
void
compileAndCheck
()
throws
Exception
{
JavacTask
ct
=
(
JavacTask
)
comp
.
getTask
(
null
,
fm
,
null
,
null
,
null
,
Arrays
.
asList
(
jfo
));
ct
.
setProcessors
(
Collections
.
singleton
(
new
BridgeFinder
()));
for
(
JavaFileObject
jfo
:
ct
.
generate
())
{
checkBridges
(
jfo
);
}
}
/**
* Check that every bridge in the generated classfile has a matching bridge
* annotation in the bridge map
*/
protected
void
checkBridges
(
JavaFileObject
jfo
)
{
try
{
ClassFile
cf
=
ClassFile
.
read
(
jfo
.
openInputStream
());
System
.
err
.
println
(
"checking: "
+
cf
.
getName
());
List
<
Bridge
>
bridgeList
=
bridgesMap
.
get
(
cf
.
getName
());
if
(
bridgeList
==
null
)
{
//no bridges - nothing to check;
bridgeList
=
List
.
nil
();
}
for
(
Method
m
:
cf
.
methods
)
{
if
(
m
.
access_flags
.
is
(
AccessFlags
.
ACC_SYNTHETIC
|
AccessFlags
.
ACC_BRIDGE
))
{
//this is a bridge - see if there's a match in the bridge list
Bridge
match
=
null
;
for
(
Bridge
b
:
bridgeList
)
{
if
(
b
.
value
().
equals
(
descriptor
(
m
,
cf
.
constant_pool
)))
{
match
=
b
;
break
;
}
}
if
(
match
==
null
)
{
error
(
"No annotation for bridge method: "
+
descriptor
(
m
,
cf
.
constant_pool
));
}
else
{
bridgeList
=
drop
(
bridgeList
,
match
);
}
}
}
if
(
bridgeList
.
nonEmpty
())
{
error
(
"Redundant bridge annotation found: "
+
bridgeList
.
head
.
value
());
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
throw
new
Error
(
"error reading "
+
jfo
.
toUri
()
+
": "
+
e
);
}
}
/**
* Log an error
*/
protected
void
error
(
String
msg
)
{
nerrors
++;
System
.
err
.
printf
(
"Error occurred while checking file: %s\nreason: %s\n"
,
jfo
.
getName
(),
msg
);
}
/**
* This annotation processor is used to populate the bridge map with the
* contents of the annotations that are found on the tests being compiled
*/
@SupportedAnnotationTypes
({
"Bridges"
,
"Bridge"
})
class
BridgeFinder
extends
JavacTestingAbstractProcessor
{
@Override
public
boolean
process
(
Set
<?
extends
TypeElement
>
annotations
,
RoundEnvironment
roundEnv
)
{
if
(
roundEnv
.
processingOver
())
return
true
;
TypeElement
bridgeAnno
=
elements
.
getTypeElement
(
"Bridge"
);
TypeElement
bridgesAnno
=
elements
.
getTypeElement
(
"Bridges"
);
//see if there are repeated annos
for
(
Element
elem:
roundEnv
.
getElementsAnnotatedWith
(
bridgesAnno
))
{
List
<
Bridge
>
bridgeList
=
List
.
nil
();
Bridges
bridges
=
elem
.
getAnnotation
(
Bridges
.
class
);
for
(
Bridge
bridge
:
bridges
.
value
())
{
bridgeList
=
bridgeList
.
prepend
(
bridge
);
}
bridgesMap
.
put
(((
ClassSymbol
)
elem
).
flatname
.
toString
(),
bridgeList
);
}
//see if there are non-repeated annos
for
(
Element
elem:
roundEnv
.
getElementsAnnotatedWith
(
bridgeAnno
))
{
Bridge
bridge
=
elem
.
getAnnotation
(
Bridge
.
class
);
bridgesMap
.
put
(((
ClassSymbol
)
elem
).
flatname
.
toString
(),
List
.
of
(
bridge
));
}
return
true
;
}
}
}
test/tools/javac/generics/bridges/Bridges.java
0 → 100644
浏览文件 @
7dd21645
/*
* Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
@interface
Bridges
{
Bridge
[]
value
();
}
test/tools/javac/generics/bridges/tests/TestBridgeWithDefault.java
0 → 100644
浏览文件 @
7dd21645
/*
* Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
class
TestBridgeWithDefault
{
interface
A
{
Object
m
(
int
x
);
}
@Bridge
(
"m(I)Ljava/lang/Object;"
)
interface
B
extends
A
{
String
m
(
int
x
);
default
Integer
m
(
long
x
)
{
return
null
;
}
}
}
test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical01.java
0 → 100644
浏览文件 @
7dd21645
/*
* Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
class
TestClassAndInterfaceBridgeIdentical01
{
interface
A
{
Object
m
();
}
interface
B
{
Number
m
();
}
@Bridge
(
"m()Ljava/lang/Object;"
)
@Bridge
(
"m()Ljava/lang/Number;"
)
interface
C
extends
A
,
B
{
Integer
m
();
}
@Bridge
(
"m()Ljava/lang/Object;"
)
@Bridge
(
"m()Ljava/lang/Number;"
)
static
abstract
class
D
implements
A
,
B
{
public
abstract
Integer
m
();
}
@Bridge
(
"m()Ljava/lang/Object;"
)
@Bridge
(
"m()Ljava/lang/Number;"
)
static
class
E
implements
A
,
B
{
public
Integer
m
()
{
return
1
;
}
}
}
test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical02.java
0 → 100644
浏览文件 @
7dd21645
/*
* Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
class
TestClassAndInterfaceBridgeIdentical02
{
interface
A
<
X
extends
Object
>
{
void
m
(
X
x
);
}
interface
B
<
X
extends
Number
>
{
void
m
(
X
x
);
}
@Bridge
(
"m(Ljava/lang/Object;)V"
)
@Bridge
(
"m(Ljava/lang/Number;)V"
)
interface
C
extends
A
<
Integer
>,
B
<
Integer
>
{
void
m
(
Integer
i
);
}
@Bridge
(
"m(Ljava/lang/Object;)V"
)
@Bridge
(
"m(Ljava/lang/Number;)V"
)
static
abstract
class
D
implements
A
<
Integer
>,
B
<
Integer
>
{
public
abstract
void
m
(
Integer
i
);
}
@Bridge
(
"m(Ljava/lang/Object;)V"
)
@Bridge
(
"m(Ljava/lang/Number;)V"
)
static
class
E
implements
A
<
Integer
>,
B
<
Integer
>
{
public
void
m
(
Integer
i
)
{
}
}
}
test/tools/javac/generics/bridges/tests/TestNoBridgeInSiblingsSuper.java
0 → 100644
浏览文件 @
7dd21645
/*
* Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
class
TestNoBridgeInSiblingSuper
{
interface
A
{
Object
m
();
}
interface
B
{
String
m
();
}
//no bridge here!
interface
C
extends
A
,
B
{
}
@Bridge
(
"m()Ljava/lang/Object;"
)
interface
D
extends
C
{
String
m
();
}
}
test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges01.java
0 → 100644
浏览文件 @
7dd21645
/*
* Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
class
TestNoDuplicateBridges01
{
interface
A1
{
Object
m
();
}
interface
A2
{
Object
m
();
}
@Bridge
(
"m()Ljava/lang/Object;"
)
interface
B
extends
A1
,
A2
{
B
m
();
}
}
test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges02.java
0 → 100644
浏览文件 @
7dd21645
/*
* Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
class
TestNoDuplicateBridges02
{
interface
A
<
T
>
{
A
<
T
>
get
();
}
@Bridge
(
"get()LTestNoDuplicateBridges02$A;"
)
interface
B
<
T
>
extends
A
<
T
>
{
B
<
T
>
get
();
}
@Bridge
(
"get()LTestNoDuplicateBridges02$A;"
)
@Bridge
(
"get()LTestNoDuplicateBridges02$B;"
)
interface
C
<
T
>
extends
A
<
T
>,
B
<
T
>
{
C
<
T
>
get
();
}
}
test/tools/javac/lambda/bridge/TestMetafactoryBridges.java
0 → 100644
浏览文件 @
7dd21645
/*
* Copyright (c) 2013, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8013789
* @summary Compiler should emit bridges in interfaces
*/
import
com.sun.source.util.JavacTask
;
import
com.sun.tools.javac.api.ClientCodeWrapper.DiagnosticSourceUnwrapper
;
import
com.sun.tools.javac.code.Symbol
;
import
com.sun.tools.javac.util.JCDiagnostic
;
import
java.io.File
;
import
java.io.PrintWriter
;
import
java.net.URI
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.EnumSet
;
import
java.util.List
;
import
java.util.Set
;
import
javax.tools.Diagnostic
;
import
javax.tools.Diagnostic.Kind
;
import
javax.tools.JavaCompiler
;
import
javax.tools.JavaFileObject
;
import
javax.tools.SimpleJavaFileObject
;
import
javax.tools.ToolProvider
;
public
class
TestMetafactoryBridges
{
static
int
checkCount
=
0
;
enum
ClasspathKind
{
NONE
(),
B7
(
7
,
ClassKind
.
B
),
A7
(
7
,
ClassKind
.
A
),
B8
(
8
,
ClassKind
.
B
),
A8
(
8
,
ClassKind
.
A
);
int
version
;
ClassKind
ck
;
ClasspathKind
()
{
this
(-
1
,
null
);
}
ClasspathKind
(
int
version
,
ClassKind
ck
)
{
this
.
version
=
version
;
this
.
ck
=
ck
;
}
}
enum
PreferPolicy
{
SOURCE
(
"-Xprefer:source"
),
NEWER
(
"-Xprefer:newer"
);
String
preferOpt
;
PreferPolicy
(
String
preferOpt
)
{
this
.
preferOpt
=
preferOpt
;
}
}
enum
SourcepathKind
{
NONE
,
A
(
ClassKind
.
A
),
B
(
ClassKind
.
B
),
C
(
ClassKind
.
C
),
AB
(
ClassKind
.
A
,
ClassKind
.
B
),
BC
(
ClassKind
.
B
,
ClassKind
.
C
),
AC
(
ClassKind
.
A
,
ClassKind
.
C
),
ABC
(
ClassKind
.
A
,
ClassKind
.
B
,
ClassKind
.
C
);
List
<
ClassKind
>
sources
;
SourcepathKind
(
ClassKind
...
sources
)
{
this
.
sources
=
Arrays
.
asList
(
sources
);
}
}
enum
SourceSet
{
ALL
()
{
@Override
List
<
List
<
ClassKind
>>
permutations
()
{
return
Arrays
.
asList
(
Arrays
.
asList
(
ClassKind
.
A
,
ClassKind
.
B
,
ClassKind
.
C
),
Arrays
.
asList
(
ClassKind
.
A
,
ClassKind
.
B
,
ClassKind
.
C
),
Arrays
.
asList
(
ClassKind
.
B
,
ClassKind
.
A
,
ClassKind
.
C
),
Arrays
.
asList
(
ClassKind
.
B
,
ClassKind
.
C
,
ClassKind
.
A
),
Arrays
.
asList
(
ClassKind
.
C
,
ClassKind
.
A
,
ClassKind
.
B
),
Arrays
.
asList
(
ClassKind
.
C
,
ClassKind
.
B
,
ClassKind
.
A
)
);
}
},
AC
()
{
@Override
List
<
List
<
ClassKind
>>
permutations
()
{
return
Arrays
.
asList
(
Arrays
.
asList
(
ClassKind
.
A
,
ClassKind
.
C
),
Arrays
.
asList
(
ClassKind
.
C
,
ClassKind
.
A
)
);
}
},
C
()
{
@Override
List
<
List
<
ClassKind
>>
permutations
()
{
return
Arrays
.
asList
(
Arrays
.
asList
(
ClassKind
.
C
));
}
};
abstract
List
<
List
<
ClassKind
>>
permutations
();
}
enum
ClassKind
{
A
(
"A"
,
"interface A { Object m(); }"
),
B
(
"B"
,
"interface B extends A { Integer m(); }"
,
A
),
C
(
"C"
,
"class C { B b = ()->42; }"
,
A
,
B
);
String
name
;
String
source
;
ClassKind
[]
deps
;
ClassKind
(
String
name
,
String
source
,
ClassKind
...
deps
)
{
this
.
name
=
name
;
this
.
source
=
source
;
this
.
deps
=
deps
;
}
}
public
static
void
main
(
String
...
args
)
throws
Exception
{
String
SCRATCH_DIR
=
System
.
getProperty
(
"user.dir"
);
//create default shared JavaCompiler - reused across multiple compilations
JavaCompiler
comp
=
ToolProvider
.
getSystemJavaCompiler
();
int
n
=
0
;
for
(
SourceSet
ss
:
SourceSet
.
values
())
{
for
(
List
<
ClassKind
>
sources
:
ss
.
permutations
())
{
for
(
SourcepathKind
spKind
:
SourcepathKind
.
values
())
{
for
(
ClasspathKind
cpKind
:
ClasspathKind
.
values
())
{
for
(
PreferPolicy
pp
:
PreferPolicy
.
values
())
{
Set
<
ClassKind
>
deps
=
EnumSet
.
noneOf
(
ClassKind
.
class
);
if
(
cpKind
.
ck
!=
null
)
{
deps
.
add
(
cpKind
.
ck
);
}
deps
.
addAll
(
sources
);
if
(
deps
.
size
()
<
3
)
continue
;
File
testDir
=
new
File
(
SCRATCH_DIR
,
"test"
+
n
);
testDir
.
mkdir
();
try
(
PrintWriter
debugWriter
=
new
PrintWriter
(
new
File
(
testDir
,
"debug.txt"
)))
{
new
TestMetafactoryBridges
(
testDir
,
sources
,
spKind
,
cpKind
,
pp
,
debugWriter
).
run
(
comp
);
n
++;
}
}
}
}
}
}
System
.
out
.
println
(
"Total check executed: "
+
checkCount
);
}
File
testDir
;
List
<
ClassKind
>
sources
;
SourcepathKind
spKind
;
ClasspathKind
cpKind
;
PreferPolicy
pp
;
PrintWriter
debugWriter
;
DiagnosticChecker
diagChecker
;
TestMetafactoryBridges
(
File
testDir
,
List
<
ClassKind
>
sources
,
SourcepathKind
spKind
,
ClasspathKind
cpKind
,
PreferPolicy
pp
,
PrintWriter
debugWriter
)
{
this
.
testDir
=
testDir
;
this
.
sources
=
sources
;
this
.
spKind
=
spKind
;
this
.
cpKind
=
cpKind
;
this
.
pp
=
pp
;
this
.
debugWriter
=
debugWriter
;
this
.
diagChecker
=
new
DiagnosticChecker
();
}
class
JavaSource
extends
SimpleJavaFileObject
{
final
String
source
;
public
JavaSource
(
ClassKind
ck
)
{
super
(
URI
.
create
(
String
.
format
(
"myfo:/%s.java"
,
ck
.
name
)),
JavaFileObject
.
Kind
.
SOURCE
);
this
.
source
=
ck
.
source
;
}
@Override
public
CharSequence
getCharContent
(
boolean
ignoreEncodingErrors
)
{
return
source
;
}
}
void
run
(
JavaCompiler
tool
)
throws
Exception
{
File
classesDir
=
new
File
(
testDir
,
"classes"
);
File
outDir
=
new
File
(
testDir
,
"out"
);
File
srcDir
=
new
File
(
testDir
,
"src"
);
classesDir
.
mkdir
();
outDir
.
mkdir
();
srcDir
.
mkdir
();
debugWriter
.
append
(
testDir
.
getName
()
+
"\n"
);
debugWriter
.
append
(
"sources = "
+
sources
+
"\n"
);
debugWriter
.
append
(
"spKind = "
+
spKind
+
"\n"
);
debugWriter
.
append
(
"cpKind = "
+
cpKind
+
"\n"
);
debugWriter
.
append
(
"preferPolicy = "
+
pp
.
preferOpt
+
"\n"
);
//step 1 - prepare sources (older!!)
debugWriter
.
append
(
"Preparing sources\n"
);
for
(
ClassKind
ck
:
spKind
.
sources
)
{
//skip sources explicitly provided on command line
if
(!
sources
.
contains
(
ck
))
{
debugWriter
.
append
(
"Copy "
+
ck
.
name
+
".java to"
+
srcDir
.
getAbsolutePath
()
+
"\n"
);
File
dest
=
new
File
(
srcDir
,
ck
.
name
+
".java"
);
PrintWriter
pw
=
new
PrintWriter
(
dest
);
pw
.
append
(
ck
.
source
);
pw
.
close
();
}
}
//step 2 - prepare classes
debugWriter
.
append
(
"Preparing classes\n"
);
if
(
cpKind
!=
ClasspathKind
.
NONE
)
{
List
<
JavaSource
>
sources
=
new
ArrayList
<>();
ClassKind
toRemove
=
null
;
sources
.
add
(
new
JavaSource
(
cpKind
.
ck
));
if
(
cpKind
.
ck
.
deps
.
length
!=
0
)
{
//at most only one dependency
toRemove
=
cpKind
.
ck
.
deps
[
0
];
sources
.
add
(
new
JavaSource
(
toRemove
));
}
JavacTask
ct
=
(
JavacTask
)
tool
.
getTask
(
debugWriter
,
null
,
null
,
Arrays
.
asList
(
"-d"
,
classesDir
.
getAbsolutePath
(),
"-source"
,
String
.
valueOf
(
cpKind
.
version
)),
null
,
sources
);
try
{
ct
.
generate
();
if
(
toRemove
!=
null
)
{
debugWriter
.
append
(
"Remove "
+
toRemove
.
name
+
".class from"
+
classesDir
.
getAbsolutePath
()
+
"\n"
);
File
fileToRemove
=
new
File
(
classesDir
,
toRemove
.
name
+
".class"
);
fileToRemove
.
delete
();
}
}
catch
(
Throwable
ex
)
{
throw
new
AssertionError
(
"Error thrown when generating side-classes"
);
}
}
//step 3 - compile
debugWriter
.
append
(
"Compiling test\n"
);
List
<
JavaSource
>
sourcefiles
=
new
ArrayList
<>();
for
(
ClassKind
ck
:
sources
)
{
sourcefiles
.
add
(
new
JavaSource
(
ck
));
}
JavacTask
ct
=
(
JavacTask
)
tool
.
getTask
(
debugWriter
,
null
,
diagChecker
,
Arrays
.
asList
(
"-XDdumpLambdaToMethodStats"
,
"-d"
,
outDir
.
getAbsolutePath
(),
"-sourcepath"
,
srcDir
.
getAbsolutePath
(),
"-classpath"
,
classesDir
.
getAbsolutePath
(),
pp
.
preferOpt
),
null
,
sourcefiles
);
try
{
ct
.
generate
();
}
catch
(
Throwable
ex
)
{
throw
new
AssertionError
(
"Error thrown when compiling test case"
);
}
check
();
}
void
check
()
{
checkCount
++;
if
(
diagChecker
.
errorFound
)
{
throw
new
AssertionError
(
"Unexpected compilation failure"
);
}
boolean
altMetafactory
=
cpKind
==
ClasspathKind
.
B7
&&
!
sources
.
contains
(
ClassKind
.
B
)
&&
(
pp
==
PreferPolicy
.
NEWER
||
!
spKind
.
sources
.
contains
(
ClassKind
.
B
));
if
(
altMetafactory
!=
diagChecker
.
altMetafactory
)
{
throw
new
AssertionError
(
"Bad metafactory detected - expected altMetafactory: "
+
altMetafactory
+
"\ntest: "
+
testDir
);
}
}
static
class
DiagnosticChecker
implements
javax
.
tools
.
DiagnosticListener
<
JavaFileObject
>
{
boolean
altMetafactory
=
false
;
boolean
errorFound
=
false
;
public
void
report
(
Diagnostic
<?
extends
JavaFileObject
>
diagnostic
)
{
if
(
diagnostic
.
getKind
()
==
Diagnostic
.
Kind
.
ERROR
)
{
errorFound
=
true
;
}
else
if
(
statProcessor
.
matches
(
diagnostic
))
{
statProcessor
.
process
(
diagnostic
);
}
}
abstract
class
DiagnosticProcessor
{
List
<
String
>
codes
;
Diagnostic
.
Kind
kind
;
public
DiagnosticProcessor
(
Kind
kind
,
String
...
codes
)
{
this
.
codes
=
Arrays
.
asList
(
codes
);
this
.
kind
=
kind
;
}
abstract
void
process
(
Diagnostic
<?
extends
JavaFileObject
>
diagnostic
);
boolean
matches
(
Diagnostic
<?
extends
JavaFileObject
>
diagnostic
)
{
return
(
codes
.
isEmpty
()
||
codes
.
contains
(
diagnostic
.
getCode
()))
&&
diagnostic
.
getKind
()
==
kind
;
}
JCDiagnostic
asJCDiagnostic
(
Diagnostic
<?
extends
JavaFileObject
>
diagnostic
)
{
if
(
diagnostic
instanceof
JCDiagnostic
)
{
return
(
JCDiagnostic
)
diagnostic
;
}
else
if
(
diagnostic
instanceof
DiagnosticSourceUnwrapper
)
{
return
((
DiagnosticSourceUnwrapper
)
diagnostic
).
d
;
}
else
{
throw
new
AssertionError
(
"Cannot convert diagnostic to JCDiagnostic: "
+
diagnostic
.
getClass
().
getName
());
}
}
}
DiagnosticProcessor
statProcessor
=
new
DiagnosticProcessor
(
Kind
.
NOTE
,
"compiler.note.lambda.stat"
,
"compiler.note.mref.stat"
,
"compiler.note.mref.stat.1"
)
{
@Override
void
process
(
Diagnostic
<?
extends
JavaFileObject
>
diagnostic
)
{
JCDiagnostic
diag
=
asJCDiagnostic
(
diagnostic
);
if
((
Boolean
)
diag
.
getArgs
()[
0
])
{
altMetafactory
=
true
;
}
}
};
}
}
test/tools/javac/lambda/lambdaExpression/LambdaTest6.java
浏览文件 @
7dd21645
...
...
@@ -105,7 +105,7 @@ public class LambdaTest6<T> {
Class
returnType
=
m
.
getReturnType
();
assertTrue
(
types
.
remove
(
returnType
.
getName
()));
}
assertTrue
(
types
.
isEmpty
());
assertTrue
(
types
.
size
()
==
1
);
//there's a bridge
}
...
...
test/tools/javac/lambda/methodReference/BridgeMethod.java
浏览文件 @
7dd21645
...
...
@@ -112,6 +112,6 @@ public class BridgeMethod {
Class
<?>
returnType
=
m
.
getReturnType
();
assertTrue
(
types
.
remove
(
returnType
.
getName
()));
}
assertTrue
(
types
.
isEmpty
());
assertTrue
(
types
.
size
()
==
1
);
//there's a bridge
}
}
test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java
浏览文件 @
7dd21645
...
...
@@ -395,6 +395,7 @@ public class DefaultMethodsTest extends TestHarness {
* TEST: C c = new C(); c.m() == 88;
* TEST: I i = new C(); i.m() == 88;
*/
@Test
(
enabled
=
false
)
public
void
testSelfFill
()
{
// This test ensures that a concrete method overrides a default method
// that matches at the language-level, but has a different method
...
...
@@ -484,6 +485,7 @@ public class DefaultMethodsTest extends TestHarness {
* TEST: J<String,String> j = new C(); j.m("A","B","C") == 88;
* TEST: K<String> k = new C(); k.m("A","B","C") == 88;
*/
@Test
(
enabled
=
false
)
public
void
testBridges
()
{
DefaultMethod
dm
=
new
DefaultMethod
(
"int"
,
stdMethodName
,
"return 99;"
,
new
MethodParameter
(
"T"
,
"t"
),
new
MethodParameter
(
"V"
,
"v"
),
...
...
@@ -672,6 +674,7 @@ public class DefaultMethodsTest extends TestHarness {
* class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger;
* TEST: S s = new S(); s.foo() == new Integer(99)
*/
@Test
(
enabled
=
false
)
public
void
testCovarBridge
()
{
Interface
I
=
new
Interface
(
"I"
,
new
DefaultMethod
(
"Integer"
,
"m"
,
"return new Integer(88);"
));
...
...
@@ -754,6 +757,7 @@ public class DefaultMethodsTest extends TestHarness {
* Test that a erased-signature-matching method does not implement
* non-language-level matching methods
*/
@Test
(
enabled
=
false
)
public
void
testNonConcreteFill
()
{
AbstractMethod
ipm
=
new
AbstractMethod
(
"int"
,
"m"
,
new
MethodParameter
(
"T"
,
"t"
),
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录