Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_langtools
提交
104e71be
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看板
提交
104e71be
编写于
12月 10, 2012
作者:
L
lana
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
54e8daa7
f6f7f8f7
变更
70
隐藏空白更改
内联
并排
Showing
70 changed file
with
2844 addition
and
386 deletion
+2844
-386
src/share/classes/com/sun/source/tree/IntersectionTypeTree.java
...are/classes/com/sun/source/tree/IntersectionTypeTree.java
+39
-0
src/share/classes/com/sun/source/tree/Tree.java
src/share/classes/com/sun/source/tree/Tree.java
+5
-0
src/share/classes/com/sun/source/tree/TreeVisitor.java
src/share/classes/com/sun/source/tree/TreeVisitor.java
+1
-0
src/share/classes/com/sun/source/util/SimpleTreeVisitor.java
src/share/classes/com/sun/source/util/SimpleTreeVisitor.java
+4
-0
src/share/classes/com/sun/source/util/TreeScanner.java
src/share/classes/com/sun/source/util/TreeScanner.java
+4
-0
src/share/classes/com/sun/tools/classfile/Instruction.java
src/share/classes/com/sun/tools/classfile/Instruction.java
+13
-1
src/share/classes/com/sun/tools/classfile/Opcode.java
src/share/classes/com/sun/tools/classfile/Opcode.java
+13
-13
src/share/classes/com/sun/tools/javac/code/Source.java
src/share/classes/com/sun/tools/javac/code/Source.java
+3
-0
src/share/classes/com/sun/tools/javac/code/Type.java
src/share/classes/com/sun/tools/javac/code/Type.java
+43
-0
src/share/classes/com/sun/tools/javac/code/Types.java
src/share/classes/com/sun/tools/javac/code/Types.java
+111
-85
src/share/classes/com/sun/tools/javac/comp/Attr.java
src/share/classes/com/sun/tools/javac/comp/Attr.java
+135
-62
src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
...hare/classes/com/sun/tools/javac/comp/LambdaToMethod.java
+6
-15
src/share/classes/com/sun/tools/javac/comp/Lower.java
src/share/classes/com/sun/tools/javac/comp/Lower.java
+27
-9
src/share/classes/com/sun/tools/javac/comp/Resolve.java
src/share/classes/com/sun/tools/javac/comp/Resolve.java
+1
-2
src/share/classes/com/sun/tools/javac/comp/TransTypes.java
src/share/classes/com/sun/tools/javac/comp/TransTypes.java
+8
-0
src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
+3
-3
src/share/classes/com/sun/tools/javac/jvm/Gen.java
src/share/classes/com/sun/tools/javac/jvm/Gen.java
+69
-0
src/share/classes/com/sun/tools/javac/model/JavacTypes.java
src/share/classes/com/sun/tools/javac/model/JavacTypes.java
+1
-0
src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java
...are/classes/com/sun/tools/javac/parser/JavaTokenizer.java
+18
-9
src/share/classes/com/sun/tools/javac/parser/JavacParser.java
...share/classes/com/sun/tools/javac/parser/JavacParser.java
+199
-109
src/share/classes/com/sun/tools/javac/resources/compiler.properties
...classes/com/sun/tools/javac/resources/compiler.properties
+18
-2
src/share/classes/com/sun/tools/javac/tree/JCTree.java
src/share/classes/com/sun/tools/javac/tree/JCTree.java
+33
-2
src/share/classes/com/sun/tools/javac/tree/Pretty.java
src/share/classes/com/sun/tools/javac/tree/Pretty.java
+8
-0
src/share/classes/com/sun/tools/javac/tree/TreeCopier.java
src/share/classes/com/sun/tools/javac/tree/TreeCopier.java
+6
-0
src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
+19
-0
src/share/classes/com/sun/tools/javac/tree/TreeMaker.java
src/share/classes/com/sun/tools/javac/tree/TreeMaker.java
+6
-0
src/share/classes/com/sun/tools/javac/tree/TreeScanner.java
src/share/classes/com/sun/tools/javac/tree/TreeScanner.java
+4
-0
src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java
...hare/classes/com/sun/tools/javac/tree/TreeTranslator.java
+5
-0
src/share/classes/javax/lang/model/type/IntersectionType.java
...share/classes/javax/lang/model/type/IntersectionType.java
+47
-0
src/share/classes/javax/lang/model/type/TypeKind.java
src/share/classes/javax/lang/model/type/TypeKind.java
+8
-1
src/share/classes/javax/lang/model/type/TypeVisitor.java
src/share/classes/javax/lang/model/type/TypeVisitor.java
+10
-0
src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java
...e/classes/javax/lang/model/util/AbstractTypeVisitor6.java
+14
-0
src/share/classes/javax/lang/model/util/AbstractTypeVisitor8.java
...e/classes/javax/lang/model/util/AbstractTypeVisitor8.java
+9
-0
src/share/classes/javax/tools/JavaCompiler.java
src/share/classes/javax/tools/JavaCompiler.java
+3
-3
test/tools/javac/7144981/IgnoreIgnorableCharactersInInput.java
...tools/javac/7144981/IgnoreIgnorableCharactersInInput.java
+92
-0
test/tools/javac/7153958/CPoolRefClassContainingInlinedCts.java
...ools/javac/7153958/CPoolRefClassContainingInlinedCts.java
+134
-0
test/tools/javac/7153958/pkg/ClassToBeStaticallyImported.java
.../tools/javac/7153958/pkg/ClassToBeStaticallyImported.java
+29
-0
test/tools/javac/cast/intersection/IntersectionTypeCastTest.java
...ols/javac/cast/intersection/IntersectionTypeCastTest.java
+330
-0
test/tools/javac/cast/intersection/IntersectionTypeParserTest.java
...s/javac/cast/intersection/IntersectionTypeParserTest.java
+191
-0
test/tools/javac/cast/intersection/model/Check.java
test/tools/javac/cast/intersection/model/Check.java
+27
-0
test/tools/javac/cast/intersection/model/IntersectionTypeInfo.java
...s/javac/cast/intersection/model/IntersectionTypeInfo.java
+29
-0
test/tools/javac/cast/intersection/model/Member.java
test/tools/javac/cast/intersection/model/Member.java
+31
-0
test/tools/javac/cast/intersection/model/Model01.java
test/tools/javac/cast/intersection/model/Model01.java
+52
-0
test/tools/javac/cast/intersection/model/ModelChecker.java
test/tools/javac/cast/intersection/model/ModelChecker.java
+153
-0
test/tools/javac/defaultMethods/defaultMethodExecution/DefaultMethodRegressionTests.java
.../defaultMethodExecution/DefaultMethodRegressionTests.java
+1
-0
test/tools/javac/diags/examples/IntersectionTypesInCastNotSupported.java
...c/diags/examples/IntersectionTypesInCastNotSupported.java
+29
-0
test/tools/javac/diags/examples/InvalidGenericLambdaTarget.java
...ools/javac/diags/examples/InvalidGenericLambdaTarget.java
+2
-2
test/tools/javac/diags/examples/SecondaryBoundMustBeMarkerIntf.java
.../javac/diags/examples/SecondaryBoundMustBeMarkerIntf.java
+30
-0
test/tools/javac/diags/examples/StaticBoundMref.java
test/tools/javac/diags/examples/StaticBoundMref.java
+32
-0
test/tools/javac/diags/examples/StaticMrefWithTargs.java
test/tools/javac/diags/examples/StaticMrefWithTargs.java
+32
-0
test/tools/javac/lambda/FunctionalInterfaceConversionTest.java
...tools/javac/lambda/FunctionalInterfaceConversionTest.java
+59
-25
test/tools/javac/lambda/Intersection01.java
test/tools/javac/lambda/Intersection01.java
+42
-0
test/tools/javac/lambda/Intersection01.out
test/tools/javac/lambda/Intersection01.out
+3
-0
test/tools/javac/lambda/LambdaConv21.java
test/tools/javac/lambda/LambdaConv21.java
+1
-1
test/tools/javac/lambda/LambdaConv21.out
test/tools/javac/lambda/LambdaConv21.out
+1
-2
test/tools/javac/lambda/LambdaParserTest.java
test/tools/javac/lambda/LambdaParserTest.java
+12
-2
test/tools/javac/lambda/MethodReference30.java
test/tools/javac/lambda/MethodReference30.java
+1
-1
test/tools/javac/lambda/MethodReference55.java
test/tools/javac/lambda/MethodReference55.java
+45
-0
test/tools/javac/lambda/MethodReference55.out
test/tools/javac/lambda/MethodReference55.out
+3
-0
test/tools/javac/lambda/MethodReference56.java
test/tools/javac/lambda/MethodReference56.java
+45
-0
test/tools/javac/lambda/MethodReference56.out
test/tools/javac/lambda/MethodReference56.out
+3
-0
test/tools/javac/lambda/MethodReference57.java
test/tools/javac/lambda/MethodReference57.java
+41
-0
test/tools/javac/lambda/MethodReference58.java
test/tools/javac/lambda/MethodReference58.java
+46
-0
test/tools/javac/lambda/MethodReference58.out
test/tools/javac/lambda/MethodReference58.out
+2
-0
test/tools/javac/lambda/VoidCompatibility.out
test/tools/javac/lambda/VoidCompatibility.out
+2
-1
test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java
...javac/lambda/intersection/IntersectionTargetTypeTest.java
+294
-0
test/tools/javac/lambda/methodReference/MethodRef1.java
test/tools/javac/lambda/methodReference/MethodRef1.java
+0
-3
test/tools/javac/lambda/methodReference/SamConversion.java
test/tools/javac/lambda/methodReference/SamConversion.java
+0
-9
test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestKinds.java
...da/methodReferenceExecution/MethodReferenceTestKinds.java
+0
-24
test/tools/javap/T7190862.java
test/tools/javap/T7190862.java
+157
-0
未找到文件。
src/share/classes/com/sun/source/tree/IntersectionTypeTree.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package
com.sun.source.tree
;
import
java.util.List
;
/**
* A tree node for an intersection type in a cast expression.
*
* @author Maurizio Cimadamore
*
* @since 1.8
*/
public
interface
IntersectionTypeTree
extends
Tree
{
List
<?
extends
Tree
>
getBounds
();
}
src/share/classes/com/sun/source/tree/Tree.java
浏览文件 @
104e71be
...
...
@@ -246,6 +246,11 @@ public interface Tree {
*/
UNION_TYPE
(
UnionTypeTree
.
class
),
/**
* Used for instances of {@link IntersectionTypeTree}.
*/
INTERSECTION_TYPE
(
IntersectionTypeTree
.
class
),
/**
* Used for instances of {@link TypeCastTree}.
*/
...
...
src/share/classes/com/sun/source/tree/TreeVisitor.java
浏览文件 @
104e71be
...
...
@@ -98,6 +98,7 @@ public interface TreeVisitor<R,P> {
R
visitTry
(
TryTree
node
,
P
p
);
R
visitParameterizedType
(
ParameterizedTypeTree
node
,
P
p
);
R
visitUnionType
(
UnionTypeTree
node
,
P
p
);
R
visitIntersectionType
(
IntersectionTypeTree
node
,
P
p
);
R
visitArrayType
(
ArrayTypeTree
node
,
P
p
);
R
visitTypeCast
(
TypeCastTree
node
,
P
p
);
R
visitPrimitiveType
(
PrimitiveTypeTree
node
,
P
p
);
...
...
src/share/classes/com/sun/source/util/SimpleTreeVisitor.java
浏览文件 @
104e71be
...
...
@@ -240,6 +240,10 @@ public class SimpleTreeVisitor <R,P> implements TreeVisitor<R,P> {
return
defaultAction
(
node
,
p
);
}
public
R
visitIntersectionType
(
IntersectionTypeTree
node
,
P
p
)
{
return
defaultAction
(
node
,
p
);
}
public
R
visitTypeParameter
(
TypeParameterTree
node
,
P
p
)
{
return
defaultAction
(
node
,
p
);
}
...
...
src/share/classes/com/sun/source/util/TreeScanner.java
浏览文件 @
104e71be
...
...
@@ -371,6 +371,10 @@ public class TreeScanner<R,P> implements TreeVisitor<R,P> {
return
scan
(
node
.
getTypeAlternatives
(),
p
);
}
public
R
visitIntersectionType
(
IntersectionTypeTree
node
,
P
p
)
{
return
scan
(
node
.
getBounds
(),
p
);
}
public
R
visitTypeParameter
(
TypeParameterTree
node
,
P
p
)
{
R
r
=
scan
(
node
.
getBounds
(),
p
);
return
r
;
...
...
src/share/classes/com/sun/tools/classfile/Instruction.java
浏览文件 @
104e71be
...
...
@@ -71,11 +71,16 @@ public class Instruction {
SHORT
(
3
),
/** Wide opcode is not followed by any operands. */
WIDE_NO_OPERANDS
(
2
),
/** Wide opcode is followed by a 2-byte index into the local variables array. */
WIDE_LOCAL
(
4
),
/** Wide opcode is followed by a 2-byte index into the constant pool. */
WIDE_CPREF_W
(
4
),
/** Wide opcode is followed by a 2-byte index into the constant pool,
* and a signed short value. */
WIDE_CPREF_W_SHORT
(
6
),
/** Wide opcode is followed by a 2-byte reference to a local variable,
* and a signed short value. */
WIDE_LOCAL_SHORT
(
6
),
/** Opcode was not recognized. */
UNKNOWN
(
1
);
...
...
@@ -101,7 +106,7 @@ public class Instruction {
R
visitConstantPoolRef
(
Instruction
instr
,
int
index
,
P
p
);
/** See {@link Kind#CPREF_W_UBYTE}, {@link Kind#CPREF_W_UBYTE_ZERO}, {@link Kind#WIDE_CPREF_W_SHORT}. */
R
visitConstantPoolRefAndValue
(
Instruction
instr
,
int
index
,
int
value
,
P
p
);
/** See {@link Kind#LOCAL}. */
/** See {@link Kind#LOCAL}
, {@link Kind#WIDE_LOCAL}
. */
R
visitLocal
(
Instruction
instr
,
int
index
,
P
p
);
/** See {@link Kind#LOCAL_BYTE}. */
R
visitLocalAndValue
(
Instruction
instr
,
int
index
,
int
value
,
P
p
);
...
...
@@ -315,6 +320,9 @@ public class Instruction {
case
WIDE_NO_OPERANDS:
return
visitor
.
visitNoOperands
(
this
,
p
);
case
WIDE_LOCAL:
return
visitor
.
visitLocal
(
this
,
getUnsignedShort
(
2
),
p
);
case
WIDE_CPREF_W:
return
visitor
.
visitConstantPoolRef
(
this
,
getUnsignedShort
(
2
),
p
);
...
...
@@ -322,6 +330,10 @@ public class Instruction {
return
visitor
.
visitConstantPoolRefAndValue
(
this
,
getUnsignedShort
(
2
),
getUnsignedByte
(
4
),
p
);
case
WIDE_LOCAL_SHORT:
return
visitor
.
visitLocalAndValue
(
this
,
getUnsignedShort
(
2
),
getShort
(
4
),
p
);
case
UNKNOWN:
return
visitor
.
visitUnknown
(
this
,
p
);
...
...
src/share/classes/com/sun/tools/classfile/Opcode.java
浏览文件 @
104e71be
/*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009,
2012,
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
...
...
@@ -246,18 +246,18 @@ public enum Opcode {
// impdep 0xff: Picojava priv
// wide opcodes
ILOAD_W
(
0xc415
,
WIDE_
CPREF_W
),
LLOAD_W
(
0xc416
,
WIDE_
CPREF_W
),
FLOAD_W
(
0xc417
,
WIDE_
CPREF_W
),
DLOAD_W
(
0xc418
,
WIDE_
CPREF_W
),
ALOAD_W
(
0xc419
,
WIDE_
CPREF_W
),
ISTORE_W
(
0xc436
,
WIDE_
CPREF_W
),
LSTORE_W
(
0xc437
,
WIDE_
CPREF_W
),
FSTORE_W
(
0xc438
,
WIDE_
CPREF_W
),
DSTORE_W
(
0xc439
,
WIDE_
CPREF_W
),
ASTORE_W
(
0xc43a
,
WIDE_
CPREF_W
),
IINC_W
(
0xc484
,
WIDE_
CPREF_W
_SHORT
),
RET_W
(
0xc4a9
,
WIDE_
CPREF_W
),
ILOAD_W
(
0xc415
,
WIDE_
LOCAL
),
LLOAD_W
(
0xc416
,
WIDE_
LOCAL
),
FLOAD_W
(
0xc417
,
WIDE_
LOCAL
),
DLOAD_W
(
0xc418
,
WIDE_
LOCAL
),
ALOAD_W
(
0xc419
,
WIDE_
LOCAL
),
ISTORE_W
(
0xc436
,
WIDE_
LOCAL
),
LSTORE_W
(
0xc437
,
WIDE_
LOCAL
),
FSTORE_W
(
0xc438
,
WIDE_
LOCAL
),
DSTORE_W
(
0xc439
,
WIDE_
LOCAL
),
ASTORE_W
(
0xc43a
,
WIDE_
LOCAL
),
IINC_W
(
0xc484
,
WIDE_
LOCAL
_SHORT
),
RET_W
(
0xc4a9
,
WIDE_
LOCAL
),
// PicoJava nonpriv instructions
LOAD_UBYTE
(
PICOJAVA
,
0xfe00
),
...
...
src/share/classes/com/sun/tools/javac/code/Source.java
浏览文件 @
104e71be
...
...
@@ -215,6 +215,9 @@ public enum Source {
public
boolean
allowRepeatedAnnotations
()
{
return
compareTo
(
JDK1_8
)
>=
0
;
}
public
boolean
allowIntersectionTypesInCast
()
{
return
compareTo
(
JDK1_8
)
>=
0
;
}
public
static
SourceVersion
toSourceVersion
(
Source
source
)
{
switch
(
source
)
{
case
JDK1_2:
...
...
src/share/classes/com/sun/tools/javac/code/Type.java
浏览文件 @
104e71be
...
...
@@ -839,6 +839,49 @@ public class Type implements PrimitiveType {
}
}
// a clone of a ClassType that knows about the bounds of an intersection type.
public
static
class
IntersectionClassType
extends
ClassType
implements
IntersectionType
{
public
boolean
allInterfaces
;
public
enum
IntersectionKind
{
EXPLICIT
,
IMPLICT
;
}
public
IntersectionKind
intersectionKind
;
public
IntersectionClassType
(
List
<
Type
>
bounds
,
ClassSymbol
csym
,
boolean
allInterfaces
)
{
super
(
Type
.
noType
,
List
.<
Type
>
nil
(),
csym
);
this
.
allInterfaces
=
allInterfaces
;
Assert
.
check
((
csym
.
flags
()
&
COMPOUND
)
!=
0
);
supertype_field
=
bounds
.
head
;
interfaces_field
=
bounds
.
tail
;
Assert
.
check
(
supertype_field
.
tsym
.
completer
!=
null
||
!
supertype_field
.
isInterface
(),
supertype_field
);
}
public
java
.
util
.
List
<?
extends
TypeMirror
>
getBounds
()
{
return
Collections
.
unmodifiableList
(
getComponents
());
}
public
List
<
Type
>
getComponents
()
{
return
interfaces_field
.
prepend
(
supertype_field
);
}
@Override
public
TypeKind
getKind
()
{
return
TypeKind
.
INTERSECTION
;
}
@Override
public
<
R
,
P
>
R
accept
(
TypeVisitor
<
R
,
P
>
v
,
P
p
)
{
return
intersectionKind
==
IntersectionKind
.
EXPLICIT
?
v
.
visitIntersection
(
this
,
p
)
:
v
.
visitDeclared
(
this
,
p
);
}
}
public
static
class
ArrayType
extends
Type
implements
javax
.
lang
.
model
.
type
.
ArrayType
{
...
...
src/share/classes/com/sun/tools/javac/code/Types.java
浏览文件 @
104e71be
...
...
@@ -26,7 +26,13 @@
package
com.sun.tools.javac.code
;
import
java.lang.ref.SoftReference
;
import
java.util.*
;
import
java.util.Comparator
;
import
java.util.HashSet
;
import
java.util.HashMap
;
import
java.util.Locale
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.WeakHashMap
;
import
com.sun.tools.javac.code.Attribute.RetentionPolicy
;
import
com.sun.tools.javac.code.Lint.LintCategory
;
...
...
@@ -382,28 +388,6 @@ public class Types {
}
}
/**
* Scope filter used to skip methods that should be ignored during
* function interface conversion (such as methods overridden by
* j.l.Object)
*/
class
DescriptorFilter
implements
Filter
<
Symbol
>
{
TypeSymbol
origin
;
DescriptorFilter
(
TypeSymbol
origin
)
{
this
.
origin
=
origin
;
}
@Override
public
boolean
accepts
(
Symbol
sym
)
{
return
sym
.
kind
==
Kinds
.
MTH
&&
(
sym
.
flags
()
&
(
ABSTRACT
|
DEFAULT
))
==
ABSTRACT
&&
!
overridesObjectMethod
(
origin
,
sym
)
&&
(
interfaceCandidates
(
origin
.
type
,
(
MethodSymbol
)
sym
).
head
.
flags
()
&
DEFAULT
)
==
0
;
}
};
/**
* Compute the function descriptor associated with a given functional interface
*/
...
...
@@ -431,23 +415,8 @@ public class Types {
throw
failure
(
"not.a.functional.intf.1"
,
diags
.
fragment
(
"no.abstracts"
,
Kinds
.
kindName
(
origin
),
origin
));
}
else
if
(
abstracts
.
size
()
==
1
)
{
if
(
abstracts
.
first
().
type
.
tag
==
FORALL
)
{
throw
failure
(
"invalid.generic.desc.in.functional.intf"
,
abstracts
.
first
(),
Kinds
.
kindName
(
origin
),
origin
);
}
else
{
return
new
FunctionDescriptor
(
abstracts
.
first
());
}
return
new
FunctionDescriptor
(
abstracts
.
first
());
}
else
{
// size > 1
for
(
Symbol
msym
:
abstracts
)
{
if
(
msym
.
type
.
tag
==
FORALL
)
{
throw
failure
(
"invalid.generic.desc.in.functional.intf"
,
abstracts
.
first
(),
Kinds
.
kindName
(
origin
),
origin
);
}
}
FunctionDescriptor
descRes
=
mergeDescriptors
(
origin
,
abstracts
.
toList
());
if
(
descRes
==
null
)
{
//we can get here if the functional interface is ill-formed
...
...
@@ -586,6 +555,85 @@ public class Types {
}
// </editor-fold>
/**
* Scope filter used to skip methods that should be ignored (such as methods
* overridden by j.l.Object) during function interface conversion/marker interface checks
*/
class
DescriptorFilter
implements
Filter
<
Symbol
>
{
TypeSymbol
origin
;
DescriptorFilter
(
TypeSymbol
origin
)
{
this
.
origin
=
origin
;
}
@Override
public
boolean
accepts
(
Symbol
sym
)
{
return
sym
.
kind
==
Kinds
.
MTH
&&
(
sym
.
flags
()
&
(
ABSTRACT
|
DEFAULT
))
==
ABSTRACT
&&
!
overridesObjectMethod
(
origin
,
sym
)
&&
(
interfaceCandidates
(
origin
.
type
,
(
MethodSymbol
)
sym
).
head
.
flags
()
&
DEFAULT
)
==
0
;
}
};
// <editor-fold defaultstate="collapsed" desc="isMarker">
/**
* A cache that keeps track of marker interfaces
*/
class
MarkerCache
{
private
WeakHashMap
<
TypeSymbol
,
Entry
>
_map
=
new
WeakHashMap
<
TypeSymbol
,
Entry
>();
class
Entry
{
final
boolean
isMarkerIntf
;
final
int
prevMark
;
public
Entry
(
boolean
isMarkerIntf
,
int
prevMark
)
{
this
.
isMarkerIntf
=
isMarkerIntf
;
this
.
prevMark
=
prevMark
;
}
boolean
matches
(
int
mark
)
{
return
this
.
prevMark
==
mark
;
}
}
boolean
get
(
TypeSymbol
origin
)
throws
FunctionDescriptorLookupError
{
Entry
e
=
_map
.
get
(
origin
);
CompoundScope
members
=
membersClosure
(
origin
.
type
,
false
);
if
(
e
==
null
||
!
e
.
matches
(
members
.
getMark
()))
{
boolean
isMarkerIntf
=
isMarkerInterfaceInternal
(
origin
,
members
);
_map
.
put
(
origin
,
new
Entry
(
isMarkerIntf
,
members
.
getMark
()));
return
isMarkerIntf
;
}
else
{
return
e
.
isMarkerIntf
;
}
}
/**
* Is given symbol a marker interface
*/
public
boolean
isMarkerInterfaceInternal
(
TypeSymbol
origin
,
CompoundScope
membersCache
)
throws
FunctionDescriptorLookupError
{
return
!
origin
.
isInterface
()
?
false
:
!
membersCache
.
getElements
(
new
DescriptorFilter
(
origin
)).
iterator
().
hasNext
();
}
}
private
MarkerCache
markerCache
=
new
MarkerCache
();
/**
* Is given type a marker interface?
*/
public
boolean
isMarkerInterface
(
Type
site
)
{
return
markerCache
.
get
(
site
.
tsym
);
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="isSubtype">
/**
* Is t an unchecked subtype of s?
...
...
@@ -1964,45 +2012,28 @@ public class Types {
* @param supertype is objectType if all bounds are interfaces,
* null otherwise.
*/
public
Type
makeCompoundType
(
List
<
Type
>
bounds
,
Type
supertype
)
{
public
Type
makeCompoundType
(
List
<
Type
>
bounds
)
{
return
makeCompoundType
(
bounds
,
bounds
.
head
.
tsym
.
isInterface
());
}
public
Type
makeCompoundType
(
List
<
Type
>
bounds
,
boolean
allInterfaces
)
{
Assert
.
check
(
bounds
.
nonEmpty
());
Type
firstExplicitBound
=
bounds
.
head
;
if
(
allInterfaces
)
{
bounds
=
bounds
.
prepend
(
syms
.
objectType
);
}
ClassSymbol
bc
=
new
ClassSymbol
(
ABSTRACT
|
PUBLIC
|
SYNTHETIC
|
COMPOUND
|
ACYCLIC
,
Type
.
moreInfo
?
names
.
fromString
(
bounds
.
toString
())
:
names
.
empty
,
null
,
syms
.
noSymbol
);
if
(
bounds
.
head
.
tag
==
TYPEVAR
)
// error condition, recover
bc
.
erasure_field
=
syms
.
objectType
;
else
bc
.
erasure_field
=
erasure
(
bounds
.
head
);
bc
.
members_field
=
new
Scope
(
bc
);
ClassType
bt
=
(
ClassType
)
bc
.
type
;
bt
.
allparams_field
=
List
.
nil
();
if
(
supertype
!=
null
)
{
bt
.
supertype_field
=
supertype
;
bt
.
interfaces_field
=
bounds
;
}
else
{
bt
.
supertype_field
=
bounds
.
head
;
bt
.
interfaces_field
=
bounds
.
tail
;
}
Assert
.
check
(
bt
.
supertype_field
.
tsym
.
completer
!=
null
||
!
bt
.
supertype_field
.
isInterface
(),
bt
.
supertype_field
);
return
bt
;
}
/**
* Same as {@link #makeCompoundType(List,Type)}, except that the
* second parameter is computed directly. Note that this might
* cause a symbol completion. Hence, this version of
* makeCompoundType may not be called during a classfile read.
*/
public
Type
makeCompoundType
(
List
<
Type
>
bounds
)
{
Type
supertype
=
(
bounds
.
head
.
tsym
.
flags
()
&
INTERFACE
)
!=
0
?
supertype
(
bounds
.
head
)
:
null
;
return
makeCompoundType
(
bounds
,
supertype
);
bc
.
type
=
new
IntersectionClassType
(
bounds
,
bc
,
allInterfaces
);
bc
.
erasure_field
=
(
bounds
.
head
.
tag
==
TYPEVAR
)
?
syms
.
objectType
:
// error condition, recover
erasure
(
firstExplicitBound
);
bc
.
members_field
=
new
Scope
(
bc
);
return
bc
.
type
;
}
/**
...
...
@@ -2192,12 +2223,8 @@ public class Types {
* @param supertype is objectType if all bounds are interfaces,
* null otherwise.
*/
public
void
setBounds
(
TypeVar
t
,
List
<
Type
>
bounds
,
Type
supertype
)
{
if
(
bounds
.
tail
.
isEmpty
())
t
.
bound
=
bounds
.
head
;
else
t
.
bound
=
makeCompoundType
(
bounds
,
supertype
);
t
.
rank_field
=
-
1
;
public
void
setBounds
(
TypeVar
t
,
List
<
Type
>
bounds
)
{
setBounds
(
t
,
bounds
,
bounds
.
head
.
tsym
.
isInterface
());
}
/**
...
...
@@ -2209,10 +2236,10 @@ public class Types {
* Note that this check might cause a symbol completion. Hence, this version of
* setBounds may not be called during a classfile read.
*/
public
void
setBounds
(
TypeVar
t
,
List
<
Type
>
bounds
)
{
Type
supertype
=
(
bounds
.
head
.
tsym
.
flags
()
&
INTERFACE
)
!=
0
?
syms
.
objectType
:
null
;
setBounds
(
t
,
bounds
,
supertype
);
public
void
setBounds
(
TypeVar
t
,
List
<
Type
>
bounds
,
boolean
allInterfaces
)
{
t
.
bound
=
bounds
.
tail
.
isEmpty
()
?
bounds
.
head
:
makeCompoundType
(
bounds
,
allInterfaces
);
t
.
rank_field
=
-
1
;
}
// </editor-fold>
...
...
@@ -2222,7 +2249,7 @@ public class Types {
* Return list of bounds of the given type variable.
*/
public
List
<
Type
>
getBounds
(
TypeVar
t
)
{
if
(
t
.
bound
.
hasTag
(
NONE
))
if
(
t
.
bound
.
hasTag
(
NONE
))
return
List
.
nil
();
else
if
(
t
.
bound
.
isErroneous
()
||
!
t
.
bound
.
isCompound
())
return
List
.
of
(
t
.
bound
);
...
...
@@ -3321,8 +3348,7 @@ public class Types {
if
(
arraySuperType
==
null
)
{
// JLS 10.8: all arrays implement Cloneable and Serializable.
arraySuperType
=
makeCompoundType
(
List
.
of
(
syms
.
serializableType
,
syms
.
cloneableType
),
syms
.
objectType
);
syms
.
cloneableType
),
true
);
}
}
}
...
...
src/share/classes/com/sun/tools/javac/comp/Attr.java
浏览文件 @
104e71be
...
...
@@ -716,21 +716,8 @@ public class Attr extends JCTree.Visitor {
}
a
.
tsym
.
flags_field
&=
~
UNATTRIBUTED
;
}
for
(
JCTypeParameter
tvar
:
typarams
)
for
(
JCTypeParameter
tvar
:
typarams
)
{
chk
.
checkNonCyclic
(
tvar
.
pos
(),
(
TypeVar
)
tvar
.
type
);
attribStats
(
typarams
,
env
);
}
void
attribBounds
(
List
<
JCTypeParameter
>
typarams
)
{
for
(
JCTypeParameter
typaram
:
typarams
)
{
Type
bound
=
typaram
.
type
.
getUpperBound
();
if
(
bound
!=
null
&&
bound
.
tsym
instanceof
ClassSymbol
)
{
ClassSymbol
c
=
(
ClassSymbol
)
bound
.
tsym
;
if
((
c
.
flags_field
&
COMPOUND
)
!=
0
)
{
Assert
.
check
((
c
.
flags_field
&
UNATTRIBUTED
)
!=
0
,
c
);
attribClass
(
typaram
.
pos
(),
c
);
}
}
}
}
...
...
@@ -892,7 +879,12 @@ public class Attr extends JCTree.Visitor {
deferredLintHandler
.
flush
(
tree
.
pos
());
chk
.
checkDeprecatedAnnotation
(
tree
.
pos
(),
m
);
attribBounds
(
tree
.
typarams
);
// Create a new environment with local scope
// for attributing the method.
Env
<
AttrContext
>
localEnv
=
memberEnter
.
methodEnv
(
tree
,
env
);
localEnv
.
info
.
lint
=
lint
;
attribStats
(
tree
.
typarams
,
localEnv
);
// If we override any other methods, check that we do so properly.
// JLS ???
...
...
@@ -903,12 +895,6 @@ public class Attr extends JCTree.Visitor {
}
chk
.
checkOverride
(
tree
,
m
);
// Create a new environment with local scope
// for attributing the method.
Env
<
AttrContext
>
localEnv
=
memberEnter
.
methodEnv
(
tree
,
env
);
localEnv
.
info
.
lint
=
lint
;
if
(
isDefaultMethod
&&
types
.
overridesObjectMethod
(
m
.
enclClass
(),
m
))
{
log
.
error
(
tree
,
"default.overrides.object.member"
,
m
.
name
,
Kinds
.
kindName
(
m
.
location
()),
m
.
location
());
}
...
...
@@ -2196,7 +2182,7 @@ public class Attr extends JCTree.Visitor {
Type
target
;
Type
lambdaType
;
if
(
pt
()
!=
Type
.
recoveryType
)
{
target
=
infer
.
instantiateFunctionalInterface
(
that
,
pt
(
),
explicitParamTypes
,
resultInfo
.
checkContext
);
target
=
infer
.
instantiateFunctionalInterface
(
that
,
checkIntersectionTarget
(
that
,
resultInfo
),
explicitParamTypes
,
resultInfo
.
checkContext
);
lambdaType
=
types
.
findDescriptorType
(
target
);
chk
.
checkFunctionalInterface
(
that
,
target
);
}
else
{
...
...
@@ -2204,6 +2190,14 @@ public class Attr extends JCTree.Visitor {
lambdaType
=
fallbackDescriptorType
(
that
);
}
if
(
lambdaType
.
hasTag
(
FORALL
))
{
//lambda expression target desc cannot be a generic method
resultInfo
.
checkContext
.
report
(
that
,
diags
.
fragment
(
"invalid.generic.lambda.target"
,
lambdaType
,
kindName
(
target
.
tsym
),
target
.
tsym
));
result
=
that
.
type
=
types
.
createErrorType
(
pt
());
return
;
}
if
(!
TreeInfo
.
isExplicitLambda
(
that
))
{
//add param type info in the AST
List
<
Type
>
actuals
=
lambdaType
.
getParameterTypes
();
...
...
@@ -2244,9 +2238,13 @@ public class Attr extends JCTree.Visitor {
//with the target-type, it will be recovered anyway in Attr.checkId
needsRecovery
=
false
;
FunctionalReturnContext
funcContext
=
that
.
getBodyKind
()
==
JCLambda
.
BodyKind
.
EXPRESSION
?
new
ExpressionLambdaReturnContext
((
JCExpression
)
that
.
getBody
(),
resultInfo
.
checkContext
)
:
new
FunctionalReturnContext
(
resultInfo
.
checkContext
);
ResultInfo
bodyResultInfo
=
lambdaType
.
getReturnType
()
==
Type
.
recoveryType
?
recoveryInfo
:
new
ResultInfo
(
VAL
,
lambdaType
.
getReturnType
(),
new
LambdaReturnContext
(
resultInfo
.
checkContext
)
);
new
ResultInfo
(
VAL
,
lambdaType
.
getReturnType
(),
funcContext
);
localEnv
.
info
.
returnResult
=
bodyResultInfo
;
if
(
that
.
getBodyKind
()
==
JCLambda
.
BodyKind
.
EXPRESSION
)
{
...
...
@@ -2282,6 +2280,26 @@ public class Attr extends JCTree.Visitor {
}
}
}
private
Type
checkIntersectionTarget
(
DiagnosticPosition
pos
,
ResultInfo
resultInfo
)
{
Type
pt
=
resultInfo
.
pt
;
if
(
pt
!=
Type
.
recoveryType
&&
pt
.
isCompound
())
{
IntersectionClassType
ict
=
(
IntersectionClassType
)
pt
;
List
<
Type
>
bounds
=
ict
.
allInterfaces
?
ict
.
getComponents
().
tail
:
ict
.
getComponents
();
types
.
findDescriptorType
(
bounds
.
head
);
//propagate exception outwards!
for
(
Type
bound
:
bounds
.
tail
)
{
if
(!
types
.
isMarkerInterface
(
bound
))
{
resultInfo
.
checkContext
.
report
(
pos
,
diags
.
fragment
(
"secondary.bound.must.be.marker.intf"
,
bound
));
}
}
//for now (translation doesn't support intersection types)
return
bounds
.
head
;
}
else
{
return
pt
;
}
}
//where
private
Type
fallbackDescriptorType
(
JCExpression
tree
)
{
switch
(
tree
.
getTag
())
{
...
...
@@ -2327,8 +2345,9 @@ public class Attr extends JCTree.Visitor {
* type according to both the inherited context and the assignment
* context.
*/
class
LambdaReturnContext
extends
Check
.
NestedCheckContext
{
public
LambdaReturnContext
(
CheckContext
enclosingContext
)
{
class
FunctionalReturnContext
extends
Check
.
NestedCheckContext
{
FunctionalReturnContext
(
CheckContext
enclosingContext
)
{
super
(
enclosingContext
);
}
...
...
@@ -2344,6 +2363,23 @@ public class Attr extends JCTree.Visitor {
}
}
class
ExpressionLambdaReturnContext
extends
FunctionalReturnContext
{
JCExpression
expr
;
ExpressionLambdaReturnContext
(
JCExpression
expr
,
CheckContext
enclosingContext
)
{
super
(
enclosingContext
);
this
.
expr
=
expr
;
}
@Override
public
boolean
compatible
(
Type
found
,
Type
req
,
Warner
warn
)
{
//a void return is compatible with an expression statement lambda
return
TreeInfo
.
isExpressionStatement
(
expr
)
&&
req
.
hasTag
(
VOID
)
||
super
.
compatible
(
found
,
req
,
warn
);
}
}
/**
* Lambda compatibility. Check that given return types, thrown types, parameter types
* are compatible with the expected functional interface descriptor. This means that:
...
...
@@ -2428,7 +2464,7 @@ public class Attr extends JCTree.Visitor {
}
//attrib type-arguments
List
<
Type
>
typeargtypes
=
null
;
List
<
Type
>
typeargtypes
=
List
.
nil
()
;
if
(
that
.
typeargs
!=
null
)
{
typeargtypes
=
attribTypes
(
that
.
typeargs
,
localEnv
);
}
...
...
@@ -2436,7 +2472,7 @@ public class Attr extends JCTree.Visitor {
Type
target
;
Type
desc
;
if
(
pt
()
!=
Type
.
recoveryType
)
{
target
=
infer
.
instantiateFunctionalInterface
(
that
,
pt
(
),
null
,
resultInfo
.
checkContext
);
target
=
infer
.
instantiateFunctionalInterface
(
that
,
checkIntersectionTarget
(
that
,
resultInfo
),
null
,
resultInfo
.
checkContext
);
desc
=
types
.
findDescriptorType
(
target
);
chk
.
checkFunctionalInterface
(
that
,
target
);
}
else
{
...
...
@@ -2498,6 +2534,26 @@ public class Attr extends JCTree.Visitor {
}
}
if
(
resultInfo
.
checkContext
.
deferredAttrContext
().
mode
==
AttrMode
.
CHECK
)
{
if
(
refSym
.
isStatic
()
&&
TreeInfo
.
isStaticSelector
(
that
.
expr
,
names
)
&&
exprType
.
getTypeArguments
().
nonEmpty
())
{
//static ref with class type-args
log
.
error
(
that
.
expr
.
pos
(),
"invalid.mref"
,
Kinds
.
kindName
(
that
.
getMode
()),
diags
.
fragment
(
"static.mref.with.targs"
));
result
=
that
.
type
=
types
.
createErrorType
(
target
);
return
;
}
if
(
refSym
.
isStatic
()
&&
!
TreeInfo
.
isStaticSelector
(
that
.
expr
,
names
)
&&
!
lookupHelper
.
referenceKind
(
refSym
).
isUnbound
())
{
//no static bound mrefs
log
.
error
(
that
.
expr
.
pos
(),
"invalid.mref"
,
Kinds
.
kindName
(
that
.
getMode
()),
diags
.
fragment
(
"static.bound.mref"
));
result
=
that
.
type
=
types
.
createErrorType
(
target
);
return
;
}
}
if
(
desc
.
getReturnType
()
==
Type
.
recoveryType
)
{
// stop here
result
=
that
.
type
=
target
;
...
...
@@ -2560,7 +2616,7 @@ public class Attr extends JCTree.Visitor {
if
(!
returnType
.
hasTag
(
VOID
)
&&
!
resType
.
hasTag
(
VOID
))
{
if
(
resType
.
isErroneous
()
||
new
Lambda
ReturnContext
(
checkContext
).
compatible
(
resType
,
returnType
,
types
.
noWarnings
))
{
new
Functional
ReturnContext
(
checkContext
).
compatible
(
resType
,
returnType
,
types
.
noWarnings
))
{
incompatibleReturnType
=
null
;
}
}
...
...
@@ -3525,63 +3581,79 @@ public class Attr extends JCTree.Visitor {
tree
.
type
=
result
=
t
;
}
public
void
visitTypeParameter
(
JCTypeParameter
tree
)
{
TypeVar
a
=
(
TypeVar
)
tree
.
type
;
public
void
visitTypeIntersection
(
JCTypeIntersection
tree
)
{
attribTypes
(
tree
.
bounds
,
env
);
tree
.
type
=
result
=
checkIntersection
(
tree
,
tree
.
bounds
);
}
public
void
visitTypeParameter
(
JCTypeParameter
tree
)
{
TypeVar
typeVar
=
(
TypeVar
)
tree
.
type
;
if
(!
typeVar
.
bound
.
isErroneous
())
{
//fixup type-parameter bound computed in 'attribTypeVariables'
typeVar
.
bound
=
checkIntersection
(
tree
,
tree
.
bounds
);
}
}
Type
checkIntersection
(
JCTree
tree
,
List
<
JCExpression
>
bounds
)
{
Set
<
Type
>
boundSet
=
new
HashSet
<
Type
>();
if
(
a
.
bound
.
isErroneous
())
return
;
List
<
Type
>
bs
=
types
.
getBounds
(
a
);
if
(
tree
.
bounds
.
nonEmpty
())
{
if
(
bounds
.
nonEmpty
())
{
// accept class or interface or typevar as first bound.
Type
b
=
checkBase
(
bs
.
head
,
tree
.
bounds
.
head
,
env
,
false
,
false
,
false
);
boundSet
.
add
(
types
.
erasure
(
b
));
if
(
b
.
isErroneous
())
{
a
.
bound
=
b
;
bounds
.
head
.
type
=
checkBase
(
bounds
.
head
.
type
,
bounds
.
head
,
env
,
false
,
false
,
false
);
boundSet
.
add
(
types
.
erasure
(
b
ounds
.
head
.
type
));
if
(
b
ounds
.
head
.
type
.
isErroneous
())
{
return
bounds
.
head
.
type
;
}
else
if
(
b
.
hasTag
(
TYPEVAR
))
{
else
if
(
b
ounds
.
head
.
type
.
hasTag
(
TYPEVAR
))
{
// if first bound was a typevar, do not accept further bounds.
if
(
tree
.
bounds
.
tail
.
nonEmpty
())
{
log
.
error
(
tree
.
bounds
.
tail
.
head
.
pos
(),
if
(
bounds
.
tail
.
nonEmpty
())
{
log
.
error
(
bounds
.
tail
.
head
.
pos
(),
"type.var.may.not.be.followed.by.other.bounds"
);
tree
.
bounds
=
List
.
of
(
tree
.
bounds
.
head
);
a
.
bound
=
bs
.
head
;
return
bounds
.
head
.
type
;
}
}
else
{
// if first bound was a class or interface, accept only interfaces
// as further bounds.
for
(
JCExpression
bound
:
tree
.
bounds
.
tail
)
{
bs
=
bs
.
tail
;
Type
i
=
checkBase
(
bs
.
head
,
bound
,
env
,
false
,
true
,
false
);
if
(
i
.
isErroneous
())
a
.
bound
=
i
;
else
if
(
i
.
hasTag
(
CLASS
))
chk
.
checkNotRepeated
(
bound
.
pos
(),
types
.
erasure
(
i
),
boundSet
);
for
(
JCExpression
bound
:
bounds
.
tail
)
{
bound
.
type
=
checkBase
(
bound
.
type
,
bound
,
env
,
false
,
true
,
false
);
if
(
bound
.
type
.
isErroneous
())
{
bounds
=
List
.
of
(
bound
);
}
else
if
(
bound
.
type
.
hasTag
(
CLASS
))
{
chk
.
checkNotRepeated
(
bound
.
pos
(),
types
.
erasure
(
bound
.
type
),
boundSet
);
}
}
}
}
bs
=
types
.
getBounds
(
a
);
// in case of multiple bounds ...
if
(
bs
.
length
()
>
1
)
{
if
(
bounds
.
length
()
==
0
)
{
return
syms
.
objectType
;
}
else
if
(
bounds
.
length
()
==
1
)
{
return
bounds
.
head
.
type
;
}
else
{
Type
owntype
=
types
.
makeCompoundType
(
TreeInfo
.
types
(
bounds
));
if
(
tree
.
hasTag
(
TYPEINTERSECTION
))
{
((
IntersectionClassType
)
owntype
).
intersectionKind
=
IntersectionClassType
.
IntersectionKind
.
EXPLICIT
;
}
// ... the variable's bound is a class type flagged COMPOUND
// (see comment for TypeVar.bound).
// In this case, generate a class tree that represents the
// bound class, ...
JCExpression
extending
;
List
<
JCExpression
>
implementing
;
if
(
(
bs
.
head
.
tsym
.
flags
()
&
INTERFACE
)
==
0
)
{
extending
=
tree
.
bounds
.
head
;
implementing
=
tree
.
bounds
.
tail
;
if
(
!
bounds
.
head
.
type
.
isInterface
()
)
{
extending
=
bounds
.
head
;
implementing
=
bounds
.
tail
;
}
else
{
extending
=
null
;
implementing
=
tree
.
bounds
;
implementing
=
bounds
;
}
JCClassDecl
cd
=
make
.
at
(
tree
.
pos
).
ClassDef
(
JCClassDecl
cd
=
make
.
at
(
tree
).
ClassDef
(
make
.
Modifiers
(
PUBLIC
|
ABSTRACT
),
tree
.
name
,
List
.<
JCTypeParameter
>
nil
(),
names
.
empty
,
List
.<
JCTypeParameter
>
nil
(),
extending
,
implementing
,
List
.<
JCTree
>
nil
());
ClassSymbol
c
=
(
ClassSymbol
)
a
.
getUpperBound
()
.
tsym
;
ClassSymbol
c
=
(
ClassSymbol
)
owntype
.
tsym
;
Assert
.
check
((
c
.
flags
()
&
COMPOUND
)
!=
0
);
cd
.
sym
=
c
;
c
.
sourcefile
=
env
.
toplevel
.
sourcefile
;
...
...
@@ -3590,10 +3662,11 @@ public class Attr extends JCTree.Visitor {
c
.
flags_field
|=
UNATTRIBUTED
;
Env
<
AttrContext
>
cenv
=
enter
.
classEnv
(
cd
,
env
);
enter
.
typeEnvs
.
put
(
c
,
cenv
);
attribClass
(
c
);
return
owntype
;
}
}
public
void
visitWildcard
(
JCWildcard
tree
)
{
//- System.err.println("visitWildcard("+tree+");");//DEBUG
Type
type
=
(
tree
.
kind
.
kind
==
BoundKind
.
UNBOUND
)
...
...
@@ -3747,7 +3820,7 @@ public class Attr extends JCTree.Visitor {
chk
.
validateAnnotations
(
tree
.
mods
.
annotations
,
c
);
// Validate type parameters, supertype and interfaces.
attrib
Bounds
(
tree
.
typarams
);
attrib
Stats
(
tree
.
typarams
,
env
);
if
(!
c
.
isAnonymous
())
{
//already checked if anonymous
chk
.
validate
(
tree
.
typarams
,
env
);
...
...
src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
浏览文件 @
104e71be
...
...
@@ -288,21 +288,20 @@ public class LambdaToMethod extends TreeTranslator {
JCExpression
init
;
switch
(
tree
.
kind
)
{
case
IMPLICIT_INNER:
/** Inner
#
new */
case
SUPER:
/** super
#
instMethod */
case
IMPLICIT_INNER:
/** Inner
::
new */
case
SUPER:
/** super
::
instMethod */
init
=
makeThis
(
localContext
.
owner
.
owner
.
asType
(),
localContext
.
owner
);
break
;
case
BOUND:
/** Expr
#
instMethod */
case
BOUND:
/** Expr
::
instMethod */
init
=
tree
.
getQualifierExpression
();
break
;
case
STATIC_EVAL:
/** Expr # staticMethod */
case
UNBOUND:
/** Type # instMethod */
case
STATIC:
/** Type # staticMethod */
case
TOPLEVEL:
/** Top level # new */
case
UNBOUND:
/** Type :: instMethod */
case
STATIC:
/** Type :: staticMethod */
case
TOPLEVEL:
/** Top level :: new */
init
=
null
;
break
;
...
...
@@ -315,14 +314,6 @@ public class LambdaToMethod extends TreeTranslator {
//build a sam instance using an indy call to the meta-factory
result
=
makeMetaFactoryIndyCall
(
tree
,
tree
.
targetType
,
localContext
.
referenceKind
(),
refSym
,
indy_args
);
//if we had a static reference with non-static qualifier, add a let
//expression to force the evaluation of the qualifier expr
if
(
tree
.
hasKind
(
ReferenceKind
.
STATIC_EVAL
))
{
VarSymbol
rec
=
new
VarSymbol
(
0
,
names
.
fromString
(
"rec$"
),
tree
.
getQualifierExpression
().
type
,
localContext
.
owner
);
JCVariableDecl
recDef
=
make
.
VarDef
(
rec
,
tree
.
getQualifierExpression
());
result
=
make
.
LetExpr
(
recDef
,
result
).
setType
(
tree
.
type
);
}
}
/**
...
...
src/share/classes/com/sun/tools/javac/comp/Lower.java
浏览文件 @
104e71be
...
...
@@ -138,6 +138,10 @@ public class Lower extends TreeTranslator {
*/
Map
<
ClassSymbol
,
JCClassDecl
>
classdefs
;
/** A hash table mapping local classes to a list of pruned trees.
*/
public
Map
<
ClassSymbol
,
List
<
JCTree
>>
prunedTree
=
new
WeakHashMap
<
ClassSymbol
,
List
<
JCTree
>>();
/** A hash table mapping virtual accessed symbols in outer subclasses
* to the actually referred symbol in superclasses.
*/
...
...
@@ -1039,6 +1043,12 @@ public class Lower extends TreeTranslator {
}
}
private
void
addPrunedInfo
(
JCTree
tree
)
{
List
<
JCTree
>
infoList
=
prunedTree
.
get
(
currentClass
);
infoList
=
(
infoList
==
null
)
?
List
.
of
(
tree
)
:
infoList
.
prepend
(
tree
);
prunedTree
.
put
(
currentClass
,
infoList
);
}
/** Ensure that identifier is accessible, return tree accessing the identifier.
* @param sym The accessed symbol.
* @param tree The tree referring to the symbol.
...
...
@@ -1111,7 +1121,10 @@ public class Lower extends TreeTranslator {
// Constants are replaced by their constant value.
if
(
sym
.
kind
==
VAR
)
{
Object
cv
=
((
VarSymbol
)
sym
).
getConstValue
();
if
(
cv
!=
null
)
return
makeLit
(
sym
.
type
,
cv
);
if
(
cv
!=
null
)
{
addPrunedInfo
(
tree
);
return
makeLit
(
sym
.
type
,
cv
);
}
}
// Private variables and methods are replaced by calls
...
...
@@ -2746,12 +2759,15 @@ public class Lower extends TreeTranslator {
/** Visitor method for conditional expressions.
*/
@Override
public
void
visitConditional
(
JCConditional
tree
)
{
JCTree
cond
=
tree
.
cond
=
translate
(
tree
.
cond
,
syms
.
booleanType
);
if
(
cond
.
type
.
isTrue
())
{
result
=
convert
(
translate
(
tree
.
truepart
,
tree
.
type
),
tree
.
type
);
addPrunedInfo
(
cond
);
}
else
if
(
cond
.
type
.
isFalse
())
{
result
=
convert
(
translate
(
tree
.
falsepart
,
tree
.
type
),
tree
.
type
);
addPrunedInfo
(
cond
);
}
else
{
// Condition is not a compile-time constant.
tree
.
truepart
=
translate
(
tree
.
truepart
,
tree
.
type
);
...
...
@@ -2760,14 +2776,14 @@ public class Lower extends TreeTranslator {
}
}
//where
private
JCTree
convert
(
JCTree
tree
,
Type
pt
)
{
if
(
tree
.
type
==
pt
||
tree
.
type
.
hasTag
(
BOT
))
return
tree
;
JCTree
result
=
make_at
(
tree
.
pos
()).
TypeCast
(
make
.
Type
(
pt
),
(
JCExpression
)
tree
);
result
.
type
=
(
tree
.
type
.
constValue
()
!=
null
)
?
cfolder
.
coerce
(
tree
.
type
,
pt
)
:
pt
;
return
result
;
}
private
JCTree
convert
(
JCTree
tree
,
Type
pt
)
{
if
(
tree
.
type
==
pt
||
tree
.
type
.
hasTag
(
BOT
))
return
tree
;
JCTree
result
=
make_at
(
tree
.
pos
()).
TypeCast
(
make
.
Type
(
pt
),
(
JCExpression
)
tree
);
result
.
type
=
(
tree
.
type
.
constValue
()
!=
null
)
?
cfolder
.
coerce
(
tree
.
type
,
pt
)
:
pt
;
return
result
;
}
/** Visitor method for if statements.
*/
...
...
@@ -2775,12 +2791,14 @@ public class Lower extends TreeTranslator {
JCTree
cond
=
tree
.
cond
=
translate
(
tree
.
cond
,
syms
.
booleanType
);
if
(
cond
.
type
.
isTrue
())
{
result
=
translate
(
tree
.
thenpart
);
addPrunedInfo
(
cond
);
}
else
if
(
cond
.
type
.
isFalse
())
{
if
(
tree
.
elsepart
!=
null
)
{
result
=
translate
(
tree
.
elsepart
);
}
else
{
result
=
make
.
Skip
();
}
addPrunedInfo
(
cond
);
}
else
{
// Condition is not a compile-time constant.
tree
.
thenpart
=
translate
(
tree
.
thenpart
);
...
...
src/share/classes/com/sun/tools/javac/comp/Resolve.java
浏览文件 @
104e71be
...
...
@@ -2617,8 +2617,7 @@ public class Resolve {
@Override
ReferenceKind
referenceKind
(
Symbol
sym
)
{
if
(
sym
.
isStatic
())
{
return
TreeInfo
.
isStaticSelector
(
referenceTree
.
expr
,
names
)
?
ReferenceKind
.
STATIC
:
ReferenceKind
.
STATIC_EVAL
;
return
ReferenceKind
.
STATIC
;
}
else
{
Name
selName
=
TreeInfo
.
name
(
referenceTree
.
getQualifierExpression
());
return
selName
!=
null
&&
selName
==
names
.
_super
?
...
...
src/share/classes/com/sun/tools/javac/comp/TransTypes.java
浏览文件 @
104e71be
...
...
@@ -551,6 +551,7 @@ public class TransTypes extends TreeTranslator {
tree
.
body
=
translate
(
tree
.
body
,
null
);
//save non-erased target
tree
.
targetType
=
tree
.
type
;
Assert
.
check
(!
tree
.
targetType
.
isCompound
(),
"Intersection-type targets not supported yet!"
);
tree
.
type
=
erasure
(
tree
.
type
);
result
=
tree
;
}
...
...
@@ -786,6 +787,7 @@ public class TransTypes extends TreeTranslator {
tree
.
expr
=
translate
(
tree
.
expr
,
null
);
//save non-erased target
tree
.
targetType
=
tree
.
type
;
Assert
.
check
(!
tree
.
targetType
.
isCompound
(),
"Intersection-type targets not supported yet!"
);
tree
.
type
=
erasure
(
tree
.
type
);
result
=
tree
;
}
...
...
@@ -803,6 +805,12 @@ public class TransTypes extends TreeTranslator {
result
=
clazz
;
}
public
void
visitTypeIntersection
(
JCTypeIntersection
tree
)
{
tree
.
bounds
=
translate
(
tree
.
bounds
,
null
);
tree
.
type
=
erasure
(
tree
.
type
);
result
=
tree
;
}
/**************************************************************************
* utility methods
*************************************************************************/
...
...
src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
浏览文件 @
104e71be
...
...
@@ -846,17 +846,17 @@ public class ClassReader implements Completer {
tvar
=
(
TypeVar
)
findTypeVar
(
name
);
}
List
<
Type
>
bounds
=
List
.
nil
();
Type
st
=
null
;
boolean
allInterfaces
=
false
;
if
(
signature
[
sigp
]
==
':'
&&
signature
[
sigp
+
1
]
==
':'
)
{
sigp
++;
st
=
syms
.
objectTyp
e
;
allInterfaces
=
tru
e
;
}
while
(
signature
[
sigp
]
==
':'
)
{
sigp
++;
bounds
=
bounds
.
prepend
(
sigToType
());
}
if
(!
sigEnterPhase
)
{
types
.
setBounds
(
tvar
,
bounds
.
reverse
(),
st
);
types
.
setBounds
(
tvar
,
bounds
.
reverse
(),
allInterfaces
);
}
return
tvar
;
}
...
...
src/share/classes/com/sun/tools/javac/jvm/Gen.java
浏览文件 @
104e71be
...
...
@@ -71,6 +71,7 @@ public class Gen extends JCTree.Visitor {
private
final
Map
<
Type
,
Symbol
>
stringBufferAppend
;
private
Name
accessDollar
;
private
final
Types
types
;
private
final
Lower
lower
;
/** Switch: GJ mode?
*/
...
...
@@ -112,6 +113,7 @@ public class Gen extends JCTree.Visitor {
stringBufferAppend
=
new
HashMap
<
Type
,
Symbol
>();
accessDollar
=
names
.
fromString
(
"access"
+
target
.
syntheticNameChar
());
lower
=
Lower
.
instance
(
context
);
Options
options
=
Options
.
instance
(
context
);
lineDebugInfo
=
...
...
@@ -816,6 +818,62 @@ public class Gen extends JCTree.Visitor {
}
}
/** Visitor class for expressions which might be constant expressions.
* This class is a subset of TreeScanner. Intended to visit trees pruned by
* Lower as long as constant expressions looking for references to any
* ClassSymbol. Any such reference will be added to the constant pool so
* automated tools can detect class dependencies better.
*/
class
ClassReferenceVisitor
extends
JCTree
.
Visitor
{
@Override
public
void
visitTree
(
JCTree
tree
)
{}
@Override
public
void
visitBinary
(
JCBinary
tree
)
{
tree
.
lhs
.
accept
(
this
);
tree
.
rhs
.
accept
(
this
);
}
@Override
public
void
visitSelect
(
JCFieldAccess
tree
)
{
if
(
tree
.
selected
.
type
.
hasTag
(
CLASS
))
{
makeRef
(
tree
.
selected
.
pos
(),
tree
.
selected
.
type
);
}
}
@Override
public
void
visitIdent
(
JCIdent
tree
)
{
if
(
tree
.
sym
.
owner
instanceof
ClassSymbol
)
{
pool
.
put
(
tree
.
sym
.
owner
);
}
}
@Override
public
void
visitConditional
(
JCConditional
tree
)
{
tree
.
cond
.
accept
(
this
);
tree
.
truepart
.
accept
(
this
);
tree
.
falsepart
.
accept
(
this
);
}
@Override
public
void
visitUnary
(
JCUnary
tree
)
{
tree
.
arg
.
accept
(
this
);
}
@Override
public
void
visitParens
(
JCParens
tree
)
{
tree
.
expr
.
accept
(
this
);
}
@Override
public
void
visitTypeCast
(
JCTypeCast
tree
)
{
tree
.
expr
.
accept
(
this
);
}
}
private
ClassReferenceVisitor
classReferenceVisitor
=
new
ClassReferenceVisitor
();
/** Visitor method: generate code for an expression, catching and reporting
* any completion failures.
* @param tree The expression to be visited.
...
...
@@ -826,6 +884,7 @@ public class Gen extends JCTree.Visitor {
try
{
if
(
tree
.
type
.
constValue
()
!=
null
)
{
// Short circuit any expressions which are constants
tree
.
accept
(
classReferenceVisitor
);
checkStringConstant
(
tree
.
pos
(),
tree
.
type
.
constValue
());
result
=
items
.
makeImmediateItem
(
tree
.
type
,
tree
.
type
.
constValue
());
}
else
{
...
...
@@ -2205,6 +2264,15 @@ public class Gen extends JCTree.Visitor {
code
.
endScopes
(
limit
);
}
private
void
generateReferencesToPrunedTree
(
ClassSymbol
classSymbol
,
Pool
pool
)
{
List
<
JCTree
>
prunedInfo
=
lower
.
prunedTree
.
get
(
classSymbol
);
if
(
prunedInfo
!=
null
)
{
for
(
JCTree
prunedTree:
prunedInfo
)
{
prunedTree
.
accept
(
classReferenceVisitor
);
}
}
}
/* ************************************************************************
* main method
*************************************************************************/
...
...
@@ -2232,6 +2300,7 @@ public class Gen extends JCTree.Visitor {
cdef
.
defs
=
normalizeDefs
(
cdef
.
defs
,
c
);
c
.
pool
=
pool
;
pool
.
reset
();
generateReferencesToPrunedTree
(
c
,
pool
);
Env
<
GenContext
>
localEnv
=
new
Env
<
GenContext
>(
cdef
,
new
GenContext
());
localEnv
.
toplevel
=
env
.
toplevel
;
...
...
src/share/classes/com/sun/tools/javac/model/JavacTypes.java
浏览文件 @
104e71be
...
...
@@ -74,6 +74,7 @@ public class JavacTypes implements javax.lang.model.util.Types {
public
Element
asElement
(
TypeMirror
t
)
{
switch
(
t
.
getKind
())
{
case
DECLARED:
case
INTERSECTION:
case
ERROR:
case
TYPEVAR:
Type
type
=
cast
(
Type
.
class
,
t
);
...
...
src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java
浏览文件 @
104e71be
...
...
@@ -348,8 +348,8 @@ public class JavaTokenizer {
private
void
scanIdent
()
{
boolean
isJavaIdentifierPart
;
char
high
;
reader
.
putChar
(
true
);
do
{
reader
.
putChar
(
true
);
switch
(
reader
.
ch
)
{
case
'A'
:
case
'B'
:
case
'C'
:
case
'D'
:
case
'E'
:
case
'F'
:
case
'G'
:
case
'H'
:
case
'I'
:
case
'J'
:
...
...
@@ -366,6 +366,7 @@ public class JavaTokenizer {
case
'$'
:
case
'_'
:
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
break
;
case
'\u0000'
:
case
'\u0001'
:
case
'\u0002'
:
case
'\u0003'
:
case
'\u0004'
:
case
'\u0005'
:
case
'\u0006'
:
case
'\u0007'
:
case
'\u0008'
:
case
'\
u000E
'
:
case
'\
u000F
'
:
case
'\u0010'
:
...
...
@@ -373,26 +374,33 @@ public class JavaTokenizer {
case
'\u0015'
:
case
'\u0016'
:
case
'\u0017'
:
case
'\u0018'
:
case
'\u0019'
:
case
'\
u001B
'
:
case
'\
u007F
'
:
break
;
reader
.
scanChar
();
continue
;
case
'\
u001A
'
:
// EOI is also a legal identifier part
if
(
reader
.
bp
>=
reader
.
buflen
)
{
name
=
reader
.
name
();
tk
=
tokens
.
lookupKind
(
name
);
return
;
}
break
;
reader
.
scanChar
();
continue
;
default
:
if
(
reader
.
ch
<
'\u0080'
)
{
// all ASCII range chars already handled, above
isJavaIdentifierPart
=
false
;
}
else
{
high
=
reader
.
scanSurrogates
();
if
(
high
!=
0
)
{
reader
.
putChar
(
high
);
isJavaIdentifierPart
=
Character
.
isJavaIdentifierPart
(
Character
.
toCodePoint
(
high
,
reader
.
ch
));
if
(
Character
.
isIdentifierIgnorable
(
reader
.
ch
))
{
reader
.
scanChar
();
continue
;
}
else
{
isJavaIdentifierPart
=
Character
.
isJavaIdentifierPart
(
reader
.
ch
);
high
=
reader
.
scanSurrogates
();
if
(
high
!=
0
)
{
reader
.
putChar
(
high
);
isJavaIdentifierPart
=
Character
.
isJavaIdentifierPart
(
Character
.
toCodePoint
(
high
,
reader
.
ch
));
}
else
{
isJavaIdentifierPart
=
Character
.
isJavaIdentifierPart
(
reader
.
ch
);
}
}
}
if
(!
isJavaIdentifierPart
)
{
...
...
@@ -401,6 +409,7 @@ public class JavaTokenizer {
return
;
}
}
reader
.
putChar
(
true
);
}
while
(
true
);
}
...
...
src/share/classes/com/sun/tools/javac/parser/JavacParser.java
浏览文件 @
104e71be
...
...
@@ -124,6 +124,9 @@ public class JavacParser implements Parser {
this
.
allowLambda
=
source
.
allowLambda
();
this
.
allowMethodReferences
=
source
.
allowMethodReferences
();
this
.
allowDefaultMethods
=
source
.
allowDefaultMethods
();
this
.
allowIntersectionTypesInCast
=
source
.
allowIntersectionTypesInCast
()
&&
fac
.
options
.
isSet
(
"allowIntersectionTypes"
);
this
.
keepDocComments
=
keepDocComments
;
docComments
=
newDocCommentTable
(
keepDocComments
,
fac
);
this
.
keepLineMap
=
keepLineMap
;
...
...
@@ -197,6 +200,10 @@ public class JavacParser implements Parser {
*/
boolean
allowDefaultMethods
;
/** Switch: should we allow intersection types in cast?
*/
boolean
allowIntersectionTypesInCast
;
/** Switch: should we keep docComments?
*/
boolean
keepDocComments
;
...
...
@@ -239,22 +246,38 @@ public class JavacParser implements Parser {
}
protected
boolean
peekToken
(
TokenKind
tk
)
{
return
S
.
token
(
1
).
kind
==
tk
;
return
peekToken
(
0
,
tk
);
}
protected
boolean
peekToken
(
int
lookahead
,
TokenKind
tk
)
{
return
S
.
token
(
lookahead
+
1
).
kind
==
tk
;
}
protected
boolean
peekToken
(
TokenKind
tk1
,
TokenKind
tk2
)
{
return
S
.
token
(
1
).
kind
==
tk1
&&
S
.
token
(
2
).
kind
==
tk2
;
return
peekToken
(
0
,
tk1
,
tk2
);
}
protected
boolean
peekToken
(
int
lookahead
,
TokenKind
tk1
,
TokenKind
tk2
)
{
return
S
.
token
(
lookahead
+
1
).
kind
==
tk1
&&
S
.
token
(
lookahead
+
2
).
kind
==
tk2
;
}
protected
boolean
peekToken
(
TokenKind
tk1
,
TokenKind
tk2
,
TokenKind
tk3
)
{
return
S
.
token
(
1
).
kind
==
tk1
&&
S
.
token
(
2
).
kind
==
tk2
&&
S
.
token
(
3
).
kind
==
tk3
;
return
peekToken
(
0
,
tk1
,
tk2
,
tk3
);
}
protected
boolean
peekToken
(
int
lookahead
,
TokenKind
tk1
,
TokenKind
tk2
,
TokenKind
tk3
)
{
return
S
.
token
(
lookahead
+
1
).
kind
==
tk1
&&
S
.
token
(
lookahead
+
2
).
kind
==
tk2
&&
S
.
token
(
lookahead
+
3
).
kind
==
tk3
;
}
protected
boolean
peekToken
(
TokenKind
...
kinds
)
{
for
(
int
lookahead
=
0
;
lookahead
<
kinds
.
length
;
lookahead
++)
{
return
peekToken
(
0
,
kinds
);
}
protected
boolean
peekToken
(
int
lookahead
,
TokenKind
...
kinds
)
{
for
(;
lookahead
<
kinds
.
length
;
lookahead
++)
{
if
(
S
.
token
(
lookahead
+
1
).
kind
!=
kinds
[
lookahead
])
{
return
false
;
}
...
...
@@ -966,102 +989,40 @@ public class JavacParser implements Parser {
break
;
case
LPAREN:
if
(
typeArgs
==
null
&&
(
mode
&
EXPR
)
!=
0
)
{
if
(
peekToken
(
MONKEYS_AT
)
||
peekToken
(
FINAL
)
||
peekToken
(
RPAREN
)
||
peekToken
(
IDENTIFIER
,
COMMA
)
||
peekToken
(
IDENTIFIER
,
RPAREN
,
ARROW
))
{
//implicit n-ary lambda
t
=
lambdaExpressionOrStatement
(
true
,
peekToken
(
MONKEYS_AT
)
||
peekToken
(
FINAL
),
pos
);
break
;
}
else
{
nextToken
();
mode
=
EXPR
|
TYPE
|
NOPARAMS
;
t
=
term3
();
if
((
mode
&
TYPE
)
!=
0
&&
token
.
kind
==
LT
)
{
// Could be a cast to a parameterized type
JCTree
.
Tag
op
=
JCTree
.
Tag
.
LT
;
int
pos1
=
token
.
pos
;
nextToken
();
mode
&=
(
EXPR
|
TYPE
);
mode
|=
TYPEARG
;
JCExpression
t1
=
term3
();
if
((
mode
&
TYPE
)
!=
0
&&
(
token
.
kind
==
COMMA
||
token
.
kind
==
GT
))
{
mode
=
TYPE
;
ListBuffer
<
JCExpression
>
args
=
new
ListBuffer
<
JCExpression
>();
args
.
append
(
t1
);
while
(
token
.
kind
==
COMMA
)
{
nextToken
();
args
.
append
(
typeArgument
());
}
accept
(
GT
);
t
=
toP
(
F
.
at
(
pos1
).
TypeApply
(
t
,
args
.
toList
()));
checkGenerics
();
mode
=
EXPR
|
TYPE
;
//could be a lambda or a method ref or a cast to a type
t
=
term3Rest
(
t
,
typeArgs
);
if
(
token
.
kind
==
IDENTIFIER
||
token
.
kind
==
ELLIPSIS
)
{
//explicit lambda (w/ generic type)
mode
=
EXPR
;
JCModifiers
mods
=
F
.
at
(
token
.
pos
).
Modifiers
(
Flags
.
PARAMETER
);
if
(
token
.
kind
==
ELLIPSIS
)
{
mods
.
flags
=
Flags
.
VARARGS
;
t
=
to
(
F
.
at
(
token
.
pos
).
TypeArray
(
t
));
nextToken
();
}
t
=
lambdaExpressionOrStatement
(
variableDeclaratorId
(
mods
,
t
),
pos
);
break
;
}
}
else
if
((
mode
&
EXPR
)
!=
0
)
{
mode
=
EXPR
;
JCExpression
e
=
term2Rest
(
t1
,
TreeInfo
.
shiftPrec
);
t
=
F
.
at
(
pos1
).
Binary
(
op
,
t
,
e
);
t
=
termRest
(
term1Rest
(
term2Rest
(
t
,
TreeInfo
.
orPrec
)));
}
else
{
accept
(
GT
);
}
}
else
if
((
mode
&
TYPE
)
!=
0
&&
(
token
.
kind
==
IDENTIFIER
||
token
.
kind
==
ELLIPSIS
))
{
//explicit lambda (w/ non-generic type)
ParensResult
pres
=
analyzeParens
();
switch
(
pres
)
{
case
CAST:
accept
(
LPAREN
);
mode
=
TYPE
;
int
pos1
=
pos
;
List
<
JCExpression
>
targets
=
List
.
of
(
t
=
term3
());
while
(
token
.
kind
==
AMP
)
{
checkIntersectionTypesInCast
();
accept
(
AMP
);
targets
=
targets
.
prepend
(
term3
());
}
if
(
targets
.
length
()
>
1
)
{
t
=
toP
(
F
.
at
(
pos1
).
TypeIntersection
(
targets
.
reverse
()));
}
accept
(
RPAREN
);
mode
=
EXPR
;
JCExpression
t1
=
term3
();
return
F
.
at
(
pos
).
TypeCast
(
t
,
t1
);
case
IMPLICIT_LAMBDA:
case
EXPLICIT_LAMBDA:
t
=
lambdaExpressionOrStatement
(
true
,
pres
==
ParensResult
.
EXPLICIT_LAMBDA
,
pos
);
break
;
default
:
//PARENS
accept
(
LPAREN
);
mode
=
EXPR
;
JCModifiers
mods
=
F
.
at
(
token
.
pos
).
Modifiers
(
Flags
.
PARAMETER
);
if
(
token
.
kind
==
ELLIPSIS
)
{
mods
.
flags
=
Flags
.
VARARGS
;
t
=
to
(
F
.
at
(
token
.
pos
).
TypeArray
(
t
));
nextToken
();
}
t
=
lambdaExpressionOrStatement
(
variableDeclaratorId
(
mods
,
t
),
pos
);
t
=
termRest
(
term1Rest
(
term2Rest
(
term3
(),
TreeInfo
.
orPrec
)));
accept
(
RPAREN
);
t
=
toP
(
F
.
at
(
pos
).
Parens
(
t
));
break
;
}
else
{
t
=
termRest
(
term1Rest
(
term2Rest
(
t
,
TreeInfo
.
orPrec
)));
}
}
accept
(
RPAREN
);
lastmode
=
mode
;
mode
=
EXPR
;
if
((
lastmode
&
EXPR
)
==
0
)
{
JCExpression
t1
=
term3
();
return
F
.
at
(
pos
).
TypeCast
(
t
,
t1
);
}
else
if
((
lastmode
&
TYPE
)
!=
0
)
{
switch
(
token
.
kind
)
{
/*case PLUSPLUS: case SUBSUB: */
case
BANG:
case
TILDE:
case
LPAREN:
case
THIS:
case
SUPER:
case
INTLITERAL:
case
LONGLITERAL:
case
FLOATLITERAL:
case
DOUBLELITERAL:
case
CHARLITERAL:
case
STRINGLITERAL:
case
TRUE:
case
FALSE:
case
NULL:
case
NEW:
case
IDENTIFIER:
case
ASSERT:
case
ENUM:
case
BYTE:
case
SHORT:
case
CHAR:
case
INT:
case
LONG:
case
FLOAT:
case
DOUBLE:
case
BOOLEAN:
case
VOID:
JCExpression
t1
=
term3
();
return
F
.
at
(
pos
).
TypeCast
(
t
,
t1
);
}
}
}
else
{
return
illegal
();
}
t
=
toP
(
F
.
at
(
pos
).
Parens
(
t
));
break
;
case
THIS:
if
((
mode
&
EXPR
)
!=
0
)
{
...
...
@@ -1346,6 +1307,138 @@ public class JavacParser implements Parser {
}
}
/**
* If we see an identifier followed by a '<' it could be an unbound
* method reference or a binary expression. To disambiguate, look for a
* matching '>' and see if the subsequent terminal is either '.' or '#'.
*/
@SuppressWarnings
(
"fallthrough"
)
ParensResult
analyzeParens
()
{
int
depth
=
0
;
boolean
type
=
false
;
for
(
int
lookahead
=
0
;
;
lookahead
++)
{
TokenKind
tk
=
S
.
token
(
lookahead
).
kind
;
switch
(
tk
)
{
case
EXTENDS:
case
SUPER:
case
COMMA:
type
=
true
;
case
QUES:
case
DOT:
case
AMP:
//skip
break
;
case
BYTE:
case
SHORT:
case
INT:
case
LONG:
case
FLOAT:
case
DOUBLE:
case
BOOLEAN:
case
CHAR:
if
(
peekToken
(
lookahead
,
RPAREN
))
{
//Type, ')' -> cast
return
ParensResult
.
CAST
;
}
else
if
(
peekToken
(
lookahead
,
IDENTIFIER
))
{
//Type, 'Identifier -> explicit lambda
return
ParensResult
.
EXPLICIT_LAMBDA
;
}
break
;
case
LPAREN:
if
(
lookahead
!=
0
)
{
// '(' in a non-starting position -> parens
return
ParensResult
.
PARENS
;
}
else
if
(
peekToken
(
lookahead
,
RPAREN
))
{
// '(', ')' -> explicit lambda
return
ParensResult
.
EXPLICIT_LAMBDA
;
}
break
;
case
RPAREN:
// if we have seen something that looks like a type,
// then it's a cast expression
if
(
type
)
return
ParensResult
.
CAST
;
// otherwise, disambiguate cast vs. parenthesized expression
// based on subsequent token.
switch
(
S
.
token
(
lookahead
+
1
).
kind
)
{
/*case PLUSPLUS: case SUBSUB: */
case
BANG:
case
TILDE:
case
LPAREN:
case
THIS:
case
SUPER:
case
INTLITERAL:
case
LONGLITERAL:
case
FLOATLITERAL:
case
DOUBLELITERAL:
case
CHARLITERAL:
case
STRINGLITERAL:
case
TRUE:
case
FALSE:
case
NULL:
case
NEW:
case
IDENTIFIER:
case
ASSERT:
case
ENUM:
case
BYTE:
case
SHORT:
case
CHAR:
case
INT:
case
LONG:
case
FLOAT:
case
DOUBLE:
case
BOOLEAN:
case
VOID:
return
ParensResult
.
CAST
;
default
:
return
ParensResult
.
PARENS
;
}
case
IDENTIFIER:
if
(
peekToken
(
lookahead
,
IDENTIFIER
))
{
// Identifier, Identifier -> explicit lambda
return
ParensResult
.
EXPLICIT_LAMBDA
;
}
else
if
(
peekToken
(
lookahead
,
RPAREN
,
ARROW
))
{
// Identifier, ')' '->' -> implicit lambda
return
ParensResult
.
IMPLICIT_LAMBDA
;
}
break
;
case
FINAL:
case
ELLIPSIS:
case
MONKEYS_AT:
//those can only appear in explicit lambdas
return
ParensResult
.
EXPLICIT_LAMBDA
;
case
LBRACKET:
if
(
peekToken
(
lookahead
,
RBRACKET
,
IDENTIFIER
))
{
// '[', ']', Identifier -> explicit lambda
return
ParensResult
.
EXPLICIT_LAMBDA
;
}
else
if
(
peekToken
(
lookahead
,
RBRACKET
,
RPAREN
)
||
peekToken
(
lookahead
,
RBRACKET
,
AMP
))
{
// '[', ']', ')' -> cast
// '[', ']', '&' -> cast (intersection type)
return
ParensResult
.
CAST
;
}
else
if
(
peekToken
(
lookahead
,
RBRACKET
))
{
//consume the ']' and skip
type
=
true
;
lookahead
++;
break
;
}
else
{
return
ParensResult
.
PARENS
;
}
case
LT:
depth
++;
break
;
case
GTGTGT:
depth
--;
case
GTGT:
depth
--;
case
GT:
depth
--;
if
(
depth
==
0
)
{
if
(
peekToken
(
lookahead
,
RPAREN
)
||
peekToken
(
lookahead
,
AMP
))
{
// '>', ')' -> cast
// '>', '&' -> cast
return
ParensResult
.
CAST
;
}
else
if
(
peekToken
(
lookahead
,
IDENTIFIER
,
COMMA
)
||
peekToken
(
lookahead
,
IDENTIFIER
,
RPAREN
,
ARROW
)
||
peekToken
(
lookahead
,
ELLIPSIS
))
{
// '>', Identifier, ',' -> explicit lambda
// '>', Identifier, ')', '->' -> explicit lambda
// '>', '...' -> explicit lambda
return
ParensResult
.
EXPLICIT_LAMBDA
;
}
//it looks a type, but could still be (i) a cast to generic type,
//(ii) an unbound method reference or (iii) an explicit lambda
type
=
true
;
break
;
}
else
if
(
depth
<
0
)
{
//unbalanced '<', '>' - not a generic type
return
ParensResult
.
PARENS
;
}
break
;
default
:
//this includes EOF
return
ParensResult
.
PARENS
;
}
}
}
enum
ParensResult
{
CAST
,
EXPLICIT_LAMBDA
,
IMPLICIT_LAMBDA
,
PARENS
;
}
JCExpression
lambdaExpressionOrStatement
(
JCVariableDecl
firstParam
,
int
pos
)
{
ListBuffer
<
JCVariableDecl
>
params
=
new
ListBuffer
<
JCVariableDecl
>();
params
.
append
(
firstParam
);
...
...
@@ -3171,21 +3264,12 @@ public class JavacParser implements Parser {
/** Check that given tree is a legal expression statement.
*/
protected
JCExpression
checkExprStat
(
JCExpression
t
)
{
switch
(
t
.
getTag
())
{
case
PREINC:
case
PREDEC:
case
POSTINC:
case
POSTDEC:
case
ASSIGN:
case
BITOR_ASG:
case
BITXOR_ASG:
case
BITAND_ASG:
case
SL_ASG:
case
SR_ASG:
case
USR_ASG:
case
PLUS_ASG:
case
MINUS_ASG:
case
MUL_ASG:
case
DIV_ASG:
case
MOD_ASG:
case
APPLY:
case
NEWCLASS:
case
ERRONEOUS:
return
t
;
default
:
if
(!
TreeInfo
.
isExpressionStatement
(
t
))
{
JCExpression
ret
=
F
.
at
(
t
.
pos
).
Erroneous
(
List
.<
JCTree
>
of
(
t
));
error
(
ret
,
"not.stmt"
);
return
ret
;
}
else
{
return
t
;
}
}
...
...
@@ -3395,6 +3479,12 @@ public class JavacParser implements Parser {
allowDefaultMethods
=
true
;
}
}
void
checkIntersectionTypesInCast
()
{
if
(!
allowIntersectionTypesInCast
)
{
log
.
error
(
token
.
pos
,
"intersection.types.in.cast.not.supported.in.source"
,
source
.
name
);
allowIntersectionTypesInCast
=
true
;
}
}
/*
* a functional source tree and end position mappings
...
...
src/share/classes/com/sun/tools/javac/resources/compiler.properties
浏览文件 @
104e71be
...
...
@@ -187,8 +187,9 @@ compiler.misc.not.a.functional.intf.1=\
{0}
# 0: symbol, 1: symbol kind, 2: symbol
compiler.misc.invalid.generic.desc.in.functional.intf
=
\
invalid functional descriptor: method {0} in {1} {2} is generic
compiler.misc.invalid.generic.lambda.target
=
\
invalid functional descriptor for lambda expression
\n\
method {0} in {1} {2} is generic
# 0: symbol kind, 1: symbol
compiler.misc.incompatible.descs.in.functional.intf
=
\
...
...
@@ -206,6 +207,10 @@ compiler.misc.descriptor.throws=\
compiler.misc.no.suitable.functional.intf.inst
=
\
cannot infer functional interface descriptor for {0}
# 0: type
compiler.misc.secondary.bound.must.be.marker.intf
=
\
secondary bound {0} must be a marker interface
# 0: symbol kind, 1: message segment
compiler.err.invalid.mref
=
\
invalid {0} reference; {1}
...
...
@@ -214,6 +219,12 @@ compiler.err.invalid.mref=\
compiler.misc.invalid.mref
=
\
invalid {0} reference; {1}
compiler.misc.static.mref.with.targs
=
\
parameterized qualifier on static method reference
compiler.misc.static.bound.mref
=
\
static bound method reference
# 0: symbol
compiler.err.cant.assign.val.to.final.var
=
\
cannot assign a value to final variable {0}
...
...
@@ -2196,6 +2207,11 @@ compiler.err.default.methods.not.supported.in.source=\
default methods are not supported in -source {0}
\n\
(use -source 8 or higher to enable default methods)
# 0: string
compiler.err.intersection.types.in.cast.not.supported.in.source
=
\
intersection types in cast are not supported in -source {0}
\n\
(use -source 8 or higher to enable default methods)
########################################
# Diagnostics for verbose resolution
# used by Resolve (debug only)
...
...
src/share/classes/com/sun/tools/javac/tree/JCTree.java
浏览文件 @
104e71be
...
...
@@ -254,6 +254,10 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
*/
TYPEUNION
,
/** Intersection types, of type TypeIntersection
*/
TYPEINTERSECTION
,
/** Formal type parameters, of type TypeParameter.
*/
TYPEPARAMETER
,
...
...
@@ -1829,8 +1833,6 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
STATIC
(
ReferenceMode
.
INVOKE
,
false
),
/** Expr # instMethod */
BOUND
(
ReferenceMode
.
INVOKE
,
false
),
/** Expr # staticMethod */
STATIC_EVAL
(
ReferenceMode
.
INVOKE
,
false
),
/** Inner # new */
IMPLICIT_INNER
(
ReferenceMode
.
NEW
,
false
),
/** Toplevel # new */
...
...
@@ -2063,6 +2065,34 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
}
}
/**
* An intersection type, T1 & T2 & ... Tn (used in cast expressions)
*/
public
static
class
JCTypeIntersection
extends
JCExpression
implements
IntersectionTypeTree
{
public
List
<
JCExpression
>
bounds
;
protected
JCTypeIntersection
(
List
<
JCExpression
>
bounds
)
{
this
.
bounds
=
bounds
;
}
@Override
public
void
accept
(
Visitor
v
)
{
v
.
visitTypeIntersection
(
this
);
}
public
Kind
getKind
()
{
return
Kind
.
INTERSECTION_TYPE
;
}
public
List
<
JCExpression
>
getBounds
()
{
return
bounds
;
}
@Override
public
<
R
,
D
>
R
accept
(
TreeVisitor
<
R
,
D
>
v
,
D
d
)
{
return
v
.
visitIntersectionType
(
this
,
d
);
}
@Override
public
Tag
getTag
()
{
return
TYPEINTERSECTION
;
}
}
/**
* A formal class parameter.
*/
...
...
@@ -2385,6 +2415,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
public
void
visitTypeArray
(
JCArrayTypeTree
that
)
{
visitTree
(
that
);
}
public
void
visitTypeApply
(
JCTypeApply
that
)
{
visitTree
(
that
);
}
public
void
visitTypeUnion
(
JCTypeUnion
that
)
{
visitTree
(
that
);
}
public
void
visitTypeIntersection
(
JCTypeIntersection
that
)
{
visitTree
(
that
);
}
public
void
visitTypeParameter
(
JCTypeParameter
that
)
{
visitTree
(
that
);
}
public
void
visitWildcard
(
JCWildcard
that
)
{
visitTree
(
that
);
}
public
void
visitTypeBoundKind
(
TypeBoundKind
that
)
{
visitTree
(
that
);
}
...
...
src/share/classes/com/sun/tools/javac/tree/Pretty.java
浏览文件 @
104e71be
...
...
@@ -1249,6 +1249,14 @@ public class Pretty extends JCTree.Visitor {
}
}
public
void
visitTypeIntersection
(
JCTypeIntersection
tree
)
{
try
{
printExprs
(
tree
.
bounds
,
" & "
);
}
catch
(
IOException
e
)
{
throw
new
UncheckedIOException
(
e
);
}
}
public
void
visitTypeParameter
(
JCTypeParameter
tree
)
{
try
{
print
(
tree
.
name
);
...
...
src/share/classes/com/sun/tools/javac/tree/TreeCopier.java
浏览文件 @
104e71be
...
...
@@ -358,6 +358,12 @@ public class TreeCopier<P> implements TreeVisitor<JCTree,P> {
return
M
.
at
(
t
.
pos
).
TypeUnion
(
components
);
}
public
JCTree
visitIntersectionType
(
IntersectionTypeTree
node
,
P
p
)
{
JCTypeIntersection
t
=
(
JCTypeIntersection
)
node
;
List
<
JCExpression
>
bounds
=
copy
(
t
.
bounds
,
p
);
return
M
.
at
(
t
.
pos
).
TypeIntersection
(
bounds
);
}
public
JCTree
visitArrayType
(
ArrayTypeTree
node
,
P
p
)
{
JCArrayTypeTree
t
=
(
JCArrayTypeTree
)
node
;
JCExpression
elemtype
=
copy
(
t
.
elemtype
,
p
);
...
...
src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
浏览文件 @
104e71be
...
...
@@ -267,6 +267,25 @@ public class TreeInfo {
return
lambda
.
params
.
isEmpty
()
||
lambda
.
params
.
head
.
vartype
!=
null
;
}
/** Return true if the tree corresponds to an expression statement */
public
static
boolean
isExpressionStatement
(
JCExpression
tree
)
{
switch
(
tree
.
getTag
())
{
case
PREINC:
case
PREDEC:
case
POSTINC:
case
POSTDEC:
case
ASSIGN:
case
BITOR_ASG:
case
BITXOR_ASG:
case
BITAND_ASG:
case
SL_ASG:
case
SR_ASG:
case
USR_ASG:
case
PLUS_ASG:
case
MINUS_ASG:
case
MUL_ASG:
case
DIV_ASG:
case
MOD_ASG:
case
APPLY:
case
NEWCLASS:
case
ERRONEOUS:
return
true
;
default
:
return
false
;
}
}
/**
* Return true if the AST corresponds to a static select of the kind A.B
*/
...
...
src/share/classes/com/sun/tools/javac/tree/TreeMaker.java
浏览文件 @
104e71be
...
...
@@ -456,6 +456,12 @@ public class TreeMaker implements JCTree.Factory {
return
tree
;
}
public
JCTypeIntersection
TypeIntersection
(
List
<
JCExpression
>
components
)
{
JCTypeIntersection
tree
=
new
JCTypeIntersection
(
components
);
tree
.
pos
=
pos
;
return
tree
;
}
public
JCTypeParameter
TypeParameter
(
Name
name
,
List
<
JCExpression
>
bounds
)
{
JCTypeParameter
tree
=
new
JCTypeParameter
(
name
,
bounds
);
tree
.
pos
=
pos
;
...
...
src/share/classes/com/sun/tools/javac/tree/TreeScanner.java
浏览文件 @
104e71be
...
...
@@ -286,6 +286,10 @@ public class TreeScanner extends Visitor {
scan
(
tree
.
alternatives
);
}
public
void
visitTypeIntersection
(
JCTypeIntersection
tree
)
{
scan
(
tree
.
bounds
);
}
public
void
visitTypeParameter
(
JCTypeParameter
tree
)
{
scan
(
tree
.
bounds
);
}
...
...
src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java
浏览文件 @
104e71be
...
...
@@ -379,6 +379,11 @@ public class TreeTranslator extends JCTree.Visitor {
result
=
tree
;
}
public
void
visitTypeIntersection
(
JCTypeIntersection
tree
)
{
tree
.
bounds
=
translate
(
tree
.
bounds
);
result
=
tree
;
}
public
void
visitTypeParameter
(
JCTypeParameter
tree
)
{
tree
.
bounds
=
translate
(
tree
.
bounds
);
result
=
tree
;
...
...
src/share/classes/javax/lang/model/type/IntersectionType.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package
javax.lang.model.type
;
import
java.util.List
;
/**
* Represents an intersection type.
*
* As of the {@link javax.lang.model.SourceVersion#RELEASE_8
* RELEASE_8} source version, intersection types can appear as the target type
* of a cast expression.
*
* @since 1.8
*/
public
interface
IntersectionType
extends
TypeMirror
{
/**
* Return the bounds comprising this intersection type.
*
* @return the bounds of this intersection types.
*/
List
<?
extends
TypeMirror
>
getBounds
();
}
src/share/classes/javax/lang/model/type/TypeKind.java
浏览文件 @
104e71be
...
...
@@ -144,7 +144,14 @@ public enum TypeKind {
*
* @since 1.7
*/
UNION
;
UNION
,
/**
* An intersection type.
*
* @since 1.8
*/
INTERSECTION
;
/**
* Returns {@code true} if this kind corresponds to a primitive
...
...
src/share/classes/javax/lang/model/type/TypeVisitor.java
浏览文件 @
104e71be
...
...
@@ -172,4 +172,14 @@ public interface TypeVisitor<R, P> {
* @since 1.7
*/
R
visitUnion
(
UnionType
t
,
P
p
);
/**
* Visits an intersection type.
*
* @param t the type to visit
* @param p a visitor-specified parameter
* @return a visitor-specified result
* @since 1.8
*/
R
visitIntersection
(
IntersectionType
t
,
P
p
);
}
src/share/classes/javax/lang/model/util/AbstractTypeVisitor6.java
浏览文件 @
104e71be
...
...
@@ -110,6 +110,20 @@ public abstract class AbstractTypeVisitor6<R, P> implements TypeVisitor<R, P> {
return
visitUnknown
(
t
,
p
);
}
/**
* Visits an {@code IntersectionType} element by calling {@code
* visitUnknown}.
* @param t {@inheritDoc}
* @param p {@inheritDoc}
* @return the result of {@code visitUnknown}
*
* @since 1.8
*/
public
R
visitIntersection
(
IntersectionType
t
,
P
p
)
{
return
visitUnknown
(
t
,
p
);
}
/**
* {@inheritDoc}
*
...
...
src/share/classes/javax/lang/model/util/AbstractTypeVisitor8.java
浏览文件 @
104e71be
...
...
@@ -66,4 +66,13 @@ public abstract class AbstractTypeVisitor8<R, P> extends AbstractTypeVisitor7<R,
protected
AbstractTypeVisitor8
()
{
super
();
}
/**
* Visits an {@code IntersectionType} in a manner defined by a subclass.
*
* @param t {@inheritDoc}
* @param p {@inheritDoc}
* @return the result of the visit as defined by a subclass
*/
public
abstract
R
visitIntersection
(
IntersectionType
t
,
P
p
);
}
src/share/classes/javax/tools/JavaCompiler.java
浏览文件 @
104e71be
...
...
@@ -108,8 +108,8 @@ import javax.annotation.processing.Processor;
* example a recommended coding pattern:
*
* <pre>
* File
s
[] files1 = ... ; // input for first compilation task
* File
s
[] files2 = ... ; // input for second compilation task
* File[] files1 = ... ; // input for first compilation task
* File[] files2 = ... ; // input for second compilation task
*
* JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
* StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
...
...
@@ -165,7 +165,7 @@ import javax.annotation.processing.Processor;
* JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
* StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, null, null);
* JavaFileManager fileManager = new ForwardingJavaFileManager(stdFileManager) {
* public void flush() {
* public void flush()
throws IOException
{
* logger.entering(StandardJavaFileManager.class.getName(), "flush");
* super.flush();
* logger.exiting(StandardJavaFileManager.class.getName(), "flush");
...
...
test/tools/javac/7144981/IgnoreIgnorableCharactersInInput.java
0 → 100644
浏览文件 @
104e71be
/*
* @test /nodynamiccopyright/
* @bug 7144981
* @summary javac should ignore ignorable characters in input
* @run main IgnoreIgnorableCharactersInInput
*/
import
com.sun.source.util.JavacTask
;
import
java.io.File
;
import
java.net.URI
;
import
java.util.Arrays
;
import
java.util.Set
;
import
java.util.TreeSet
;
import
javax.tools.JavaCompiler
;
import
javax.tools.JavaFileObject
;
import
javax.tools.SimpleJavaFileObject
;
import
javax.tools.ToolProvider
;
public
class
IgnoreIgnorableCharactersInInput
{
public
static
void
main
(
String
...
args
)
throws
Exception
{
new
IgnoreIgnorableCharactersInInput
().
run
();
}
void
run
()
throws
Exception
{
JavaCompiler
comp
=
ToolProvider
.
getSystemJavaCompiler
();
File
classesDir
=
new
File
(
System
.
getProperty
(
"user.dir"
),
"classes"
);
classesDir
.
mkdirs
();
JavaSource
[]
sources
=
new
JavaSource
[]{
new
JavaSource
(
"TestOneIgnorableChar"
,
"AA\\u0000BB"
),
new
JavaSource
(
"TestMultipleIgnorableChar"
,
"AA\\u0000\\u0000\\u0000BB"
)};
JavacTask
ct
=
(
JavacTask
)
comp
.
getTask
(
null
,
null
,
null
,
Arrays
.
asList
(
"-d"
,
classesDir
.
getPath
()),
null
,
Arrays
.
asList
(
sources
));
try
{
if
(!
ct
.
call
())
{
throw
new
AssertionError
(
"Error thrown when compiling test cases"
);
}
}
catch
(
Throwable
ex
)
{
throw
new
AssertionError
(
"Error thrown when compiling test cases"
);
}
check
(
classesDir
,
"TestOneIgnorableChar.class"
,
"TestOneIgnorableChar$AABB.class"
,
"TestMultipleIgnorableChar.class"
,
"TestMultipleIgnorableChar$AABB.class"
);
if
(
errors
>
0
)
throw
new
AssertionError
(
"There are some errors in the test check the error output"
);
}
/**
* Check that a directory contains the expected files.
*/
void
check
(
File
dir
,
String
...
paths
)
{
Set
<
String
>
found
=
new
TreeSet
<
String
>(
Arrays
.
asList
(
dir
.
list
()));
Set
<
String
>
expect
=
new
TreeSet
<
String
>(
Arrays
.
asList
(
paths
));
if
(
found
.
equals
(
expect
))
return
;
for
(
String
f:
found
)
{
if
(!
expect
.
contains
(
f
))
error
(
"Unexpected file found: "
+
f
);
}
for
(
String
e:
expect
)
{
if
(!
found
.
contains
(
e
))
error
(
"Expected file not found: "
+
e
);
}
}
int
errors
;
void
error
(
String
msg
)
{
System
.
err
.
println
(
msg
);
errors
++;
}
class
JavaSource
extends
SimpleJavaFileObject
{
String
internalSource
=
"public class #O {public class #I {} }"
;
public
JavaSource
(
String
outerClassName
,
String
innerClassName
)
{
super
(
URI
.
create
(
outerClassName
+
".java"
),
JavaFileObject
.
Kind
.
SOURCE
);
internalSource
=
internalSource
.
replace
(
"#O"
,
outerClassName
).
replace
(
"#I"
,
innerClassName
);
}
@Override
public
CharSequence
getCharContent
(
boolean
ignoreEncodingErrors
)
{
return
internalSource
;
}
}
}
test/tools/javac/7153958/CPoolRefClassContainingInlinedCts.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 7153958
* @summary add constant pool reference to class containing inlined constants
* @compile pkg/ClassToBeStaticallyImported.java
* @run main CPoolRefClassContainingInlinedCts
*/
import
com.sun.tools.classfile.ClassFile
;
import
com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info
;
import
com.sun.tools.classfile.ConstantPool.CPInfo
;
import
com.sun.tools.classfile.ConstantPoolException
;
import
java.io.File
;
import
java.io.IOException
;
import
static
pkg
.
ClassToBeStaticallyImported
.
staticField
;
public
class
CPoolRefClassContainingInlinedCts
{
public
static
void
main
(
String
args
[])
throws
Exception
{
new
CPoolRefClassContainingInlinedCts
().
run
();
}
void
run
()
throws
Exception
{
checkReferences
();
}
int
numberOfReferencedClassesToBeChecked
=
0
;
void
checkClassName
(
String
className
)
{
switch
(
className
)
{
case
"SimpleAssignClass"
:
case
"BinaryExpClass"
:
case
"UnaryExpClass"
:
case
"CastClass"
:
case
"ParensClass"
:
case
"CondClass"
:
case
"IfClass"
:
case
"pkg/ClassToBeStaticallyImported"
:
numberOfReferencedClassesToBeChecked
++;
}
}
void
checkReferences
()
throws
IOException
,
ConstantPoolException
{
File
testClasses
=
new
File
(
System
.
getProperty
(
"test.classes"
));
File
file
=
new
File
(
testClasses
,
CPoolRefClassContainingInlinedCts
.
class
.
getName
()
+
".class"
);
ClassFile
classFile
=
ClassFile
.
read
(
file
);
int
i
=
1
;
CPInfo
cpInfo
;
while
(
i
<
classFile
.
constant_pool
.
size
())
{
cpInfo
=
classFile
.
constant_pool
.
get
(
i
);
if
(
cpInfo
instanceof
CONSTANT_Class_info
)
{
checkClassName
(((
CONSTANT_Class_info
)
cpInfo
).
getName
());
}
i
+=
cpInfo
.
size
();
}
if
(
numberOfReferencedClassesToBeChecked
!=
8
)
{
throw
new
AssertionError
(
"Class reference missing in the constant pool"
);
}
}
private
int
assign
=
SimpleAssignClass
.
x
;
private
int
binary
=
BinaryExpClass
.
x
+
1
;
private
int
unary
=
-
UnaryExpClass
.
x
;
private
int
cast
=
(
int
)
CastClass
.
x
;
private
int
parens
=
(
ParensClass
.
x
);
private
int
cond
=
(
CondClass
.
x
==
1
)
?
1
:
2
;
private
static
int
ifConstant
;
private
static
int
importStatic
;
static
{
if
(
IfClass
.
x
==
1
)
{
ifConstant
=
1
;
}
else
{
ifConstant
=
2
;
}
}
static
{
if
(
staticField
==
1
)
{
importStatic
=
1
;
}
else
{
importStatic
=
2
;
}
}
}
class
SimpleAssignClass
{
public
static
final
int
x
=
1
;
}
class
BinaryExpClass
{
public
static
final
int
x
=
1
;
}
class
UnaryExpClass
{
public
static
final
int
x
=
1
;
}
class
CastClass
{
public
static
final
int
x
=
1
;
}
class
ParensClass
{
public
static
final
int
x
=
1
;
}
class
CondClass
{
public
static
final
int
x
=
1
;
}
class
IfClass
{
public
static
final
int
x
=
1
;
}
test/tools/javac/7153958/pkg/ClassToBeStaticallyImported.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package
pkg
;
public
class
ClassToBeStaticallyImported
{
public
static
final
int
staticField
=
1
;
}
test/tools/javac/cast/intersection/IntersectionTypeCastTest.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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 8002099
* @summary Add support for intersection types in cast expression
*/
import
com.sun.source.util.JavacTask
;
import
com.sun.tools.javac.util.List
;
import
com.sun.tools.javac.util.ListBuffer
;
import
java.net.URI
;
import
java.util.Arrays
;
import
javax.tools.Diagnostic
;
import
javax.tools.JavaCompiler
;
import
javax.tools.JavaFileObject
;
import
javax.tools.SimpleJavaFileObject
;
import
javax.tools.StandardJavaFileManager
;
import
javax.tools.ToolProvider
;
public
class
IntersectionTypeCastTest
{
static
int
checkCount
=
0
;
interface
Type
{
boolean
subtypeOf
(
Type
that
);
String
asString
();
boolean
isClass
();
boolean
isInterface
();
}
enum
InterfaceKind
implements
Type
{
A
(
"interface A { }\n"
,
"A"
,
null
),
B
(
"interface B { }\n"
,
"B"
,
null
),
C
(
"interface C extends A { }\n"
,
"C"
,
A
);
String
declStr
;
String
typeStr
;
InterfaceKind
superInterface
;
InterfaceKind
(
String
declStr
,
String
typeStr
,
InterfaceKind
superInterface
)
{
this
.
declStr
=
declStr
;
this
.
typeStr
=
typeStr
;
this
.
superInterface
=
superInterface
;
}
@Override
public
boolean
subtypeOf
(
Type
that
)
{
return
this
==
that
||
superInterface
==
that
||
that
==
ClassKind
.
OBJECT
;
}
@Override
public
String
asString
()
{
return
typeStr
;
}
@Override
public
boolean
isClass
()
{
return
false
;
}
@Override
public
boolean
isInterface
()
{
return
true
;
}
}
enum
ClassKind
implements
Type
{
OBJECT
(
null
,
"Object"
),
CA
(
"#M class CA implements A { }\n"
,
"CA"
,
InterfaceKind
.
A
),
CB
(
"#M class CB implements B { }\n"
,
"CB"
,
InterfaceKind
.
B
),
CAB
(
"#M class CAB implements A, B { }\n"
,
"CAB"
,
InterfaceKind
.
A
,
InterfaceKind
.
B
),
CC
(
"#M class CC implements C { }\n"
,
"CC"
,
InterfaceKind
.
C
,
InterfaceKind
.
A
),
CCA
(
"#M class CCA implements C, A { }\n"
,
"CCA"
,
InterfaceKind
.
C
,
InterfaceKind
.
A
),
CCB
(
"#M class CCB implements C, B { }\n"
,
"CCB"
,
InterfaceKind
.
C
,
InterfaceKind
.
A
,
InterfaceKind
.
B
),
CCAB
(
"#M class CCAB implements C, A, B { }\n"
,
"CCAB"
,
InterfaceKind
.
C
,
InterfaceKind
.
A
,
InterfaceKind
.
B
);
String
declTemplate
;
String
typeStr
;
List
<
InterfaceKind
>
superInterfaces
;
ClassKind
(
String
declTemplate
,
String
typeStr
,
InterfaceKind
...
superInterfaces
)
{
this
.
declTemplate
=
declTemplate
;
this
.
typeStr
=
typeStr
;
this
.
superInterfaces
=
List
.
from
(
superInterfaces
);
}
String
getDecl
(
ModifierKind
mod
)
{
return
declTemplate
!=
null
?
declTemplate
.
replaceAll
(
"#M"
,
mod
.
modStr
)
:
""
;
}
@Override
public
boolean
subtypeOf
(
Type
that
)
{
return
this
==
that
||
superInterfaces
.
contains
(
that
)
||
that
==
OBJECT
;
}
@Override
public
String
asString
()
{
return
typeStr
;
}
@Override
public
boolean
isClass
()
{
return
true
;
}
@Override
public
boolean
isInterface
()
{
return
false
;
}
}
enum
ModifierKind
{
NONE
(
""
),
FINAL
(
"final"
);
String
modStr
;
ModifierKind
(
String
modStr
)
{
this
.
modStr
=
modStr
;
}
}
enum
CastKind
{
CLASS
(
"(#C)"
,
0
),
INTERFACE
(
"(#I0)"
,
1
),
INTERSECTION2
(
"(#C & #I0)"
,
1
),
INTERSECTION3
(
"(#C & #I0 & #I1)"
,
2
);
//INTERSECTION4("(#C & #I0 & #I1 & #I2)", 3);
String
castTemplate
;
int
interfaceBounds
;
CastKind
(
String
castTemplate
,
int
interfaceBounds
)
{
this
.
castTemplate
=
castTemplate
;
this
.
interfaceBounds
=
interfaceBounds
;
}
}
static
class
CastInfo
{
CastKind
kind
;
Type
[]
types
;
CastInfo
(
CastKind
kind
,
Type
...
types
)
{
this
.
kind
=
kind
;
this
.
types
=
types
;
}
String
getCast
()
{
String
temp
=
kind
.
castTemplate
.
replaceAll
(
"#C"
,
types
[
0
].
asString
());
for
(
int
i
=
0
;
i
<
kind
.
interfaceBounds
;
i
++)
{
temp
=
temp
.
replace
(
String
.
format
(
"#I%d"
,
i
),
types
[
i
+
1
].
asString
());
}
return
temp
;
}
boolean
hasDuplicateTypes
()
{
for
(
int
i
=
0
;
i
<
types
.
length
;
i
++)
{
for
(
int
j
=
0
;
j
<
types
.
length
;
j
++)
{
if
(
i
!=
j
&&
types
[
i
]
==
types
[
j
])
{
return
true
;
}
}
}
return
false
;
}
boolean
compatibleWith
(
ModifierKind
mod
,
CastInfo
that
)
{
for
(
Type
t1
:
types
)
{
for
(
Type
t2
:
that
.
types
)
{
boolean
compat
=
t1
.
subtypeOf
(
t2
)
||
t2
.
subtypeOf
(
t1
)
||
(
t1
.
isInterface
()
&&
t2
.
isInterface
())
||
//side-cast (1)
(
mod
==
ModifierKind
.
NONE
&&
(
t1
.
isInterface
()
!=
t2
.
isInterface
()));
//side-cast (2)
if
(!
compat
)
return
false
;
}
}
return
true
;
}
}
public
static
void
main
(
String
...
args
)
throws
Exception
{
//create default shared JavaCompiler - reused across multiple compilations
JavaCompiler
comp
=
ToolProvider
.
getSystemJavaCompiler
();
StandardJavaFileManager
fm
=
comp
.
getStandardFileManager
(
null
,
null
,
null
);
for
(
ModifierKind
mod
:
ModifierKind
.
values
())
{
for
(
CastInfo
cast1
:
allCastInfo
())
{
for
(
CastInfo
cast2
:
allCastInfo
())
{
new
IntersectionTypeCastTest
(
mod
,
cast1
,
cast2
).
run
(
comp
,
fm
);
}
}
}
System
.
out
.
println
(
"Total check executed: "
+
checkCount
);
}
static
List
<
CastInfo
>
allCastInfo
()
{
ListBuffer
<
CastInfo
>
buf
=
ListBuffer
.
lb
();
for
(
CastKind
kind
:
CastKind
.
values
())
{
for
(
ClassKind
clazz
:
ClassKind
.
values
())
{
if
(
kind
==
CastKind
.
INTERFACE
&&
clazz
!=
ClassKind
.
OBJECT
)
{
continue
;
}
else
if
(
kind
.
interfaceBounds
==
0
)
{
buf
.
append
(
new
CastInfo
(
kind
,
clazz
));
continue
;
}
else
{
for
(
InterfaceKind
intf1
:
InterfaceKind
.
values
())
{
if
(
kind
.
interfaceBounds
==
1
)
{
buf
.
append
(
new
CastInfo
(
kind
,
clazz
,
intf1
));
continue
;
}
else
{
for
(
InterfaceKind
intf2
:
InterfaceKind
.
values
())
{
if
(
kind
.
interfaceBounds
==
2
)
{
buf
.
append
(
new
CastInfo
(
kind
,
clazz
,
intf1
,
intf2
));
continue
;
}
else
{
for
(
InterfaceKind
intf3
:
InterfaceKind
.
values
())
{
buf
.
append
(
new
CastInfo
(
kind
,
clazz
,
intf1
,
intf2
,
intf3
));
continue
;
}
}
}
}
}
}
}
}
return
buf
.
toList
();
}
ModifierKind
mod
;
CastInfo
cast1
,
cast2
;
JavaSource
source
;
DiagnosticChecker
diagChecker
;
IntersectionTypeCastTest
(
ModifierKind
mod
,
CastInfo
cast1
,
CastInfo
cast2
)
{
this
.
mod
=
mod
;
this
.
cast1
=
cast1
;
this
.
cast2
=
cast2
;
this
.
source
=
new
JavaSource
();
this
.
diagChecker
=
new
DiagnosticChecker
();
}
class
JavaSource
extends
SimpleJavaFileObject
{
String
bodyTemplate
=
"class Test {\n"
+
" void test() {\n"
+
" Object o = #C1#C2null;\n"
+
" } }"
;
String
source
=
""
;
public
JavaSource
()
{
super
(
URI
.
create
(
"myfo:/Test.java"
),
JavaFileObject
.
Kind
.
SOURCE
);
for
(
ClassKind
ck
:
ClassKind
.
values
())
{
source
+=
ck
.
getDecl
(
mod
);
}
for
(
InterfaceKind
ik
:
InterfaceKind
.
values
())
{
source
+=
ik
.
declStr
;
}
source
+=
bodyTemplate
.
replaceAll
(
"#C1"
,
cast1
.
getCast
()).
replaceAll
(
"#C2"
,
cast2
.
getCast
());
}
@Override
public
CharSequence
getCharContent
(
boolean
ignoreEncodingErrors
)
{
return
source
;
}
}
void
run
(
JavaCompiler
tool
,
StandardJavaFileManager
fm
)
throws
Exception
{
JavacTask
ct
=
(
JavacTask
)
tool
.
getTask
(
null
,
fm
,
diagChecker
,
Arrays
.
asList
(
"-XDallowIntersectionTypes"
),
null
,
Arrays
.
asList
(
source
));
try
{
ct
.
analyze
();
}
catch
(
Throwable
ex
)
{
throw
new
AssertionError
(
"Error thrown when compiling the following code:\n"
+
source
.
getCharContent
(
true
));
}
check
();
}
void
check
()
{
checkCount
++;
boolean
errorExpected
=
cast1
.
hasDuplicateTypes
()
||
cast2
.
hasDuplicateTypes
();
errorExpected
|=
!
cast2
.
compatibleWith
(
mod
,
cast1
);
if
(
errorExpected
!=
diagChecker
.
errorFound
)
{
throw
new
Error
(
"invalid diagnostics for source:\n"
+
source
.
getCharContent
(
true
)
+
"\nFound error: "
+
diagChecker
.
errorFound
+
"\nExpected error: "
+
errorExpected
);
}
}
static
class
DiagnosticChecker
implements
javax
.
tools
.
DiagnosticListener
<
JavaFileObject
>
{
boolean
errorFound
;
public
void
report
(
Diagnostic
<?
extends
JavaFileObject
>
diagnostic
)
{
if
(
diagnostic
.
getKind
()
==
Diagnostic
.
Kind
.
ERROR
)
{
errorFound
=
true
;
}
}
}
}
test/tools/javac/cast/intersection/IntersectionTypeParserTest.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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 8002099
* @summary Add support for intersection types in cast expression
*/
import
com.sun.source.util.JavacTask
;
import
java.net.URI
;
import
java.util.Arrays
;
import
javax.tools.Diagnostic
;
import
javax.tools.JavaCompiler
;
import
javax.tools.JavaFileObject
;
import
javax.tools.SimpleJavaFileObject
;
import
javax.tools.StandardJavaFileManager
;
import
javax.tools.ToolProvider
;
public
class
IntersectionTypeParserTest
{
static
int
checkCount
=
0
;
enum
TypeKind
{
SIMPLE
(
"A"
),
GENERIC
(
"A<X>"
),
WILDCARD
(
"A<? super X, ? extends Y>"
);
String
typeStr
;
TypeKind
(
String
typeStr
)
{
this
.
typeStr
=
typeStr
;
}
}
enum
ArrayKind
{
NONE
(
""
),
SINGLE
(
"[]"
),
DOUBLE
(
"[][]"
);
String
arrStr
;
ArrayKind
(
String
arrStr
)
{
this
.
arrStr
=
arrStr
;
}
}
static
class
Type
{
TypeKind
tk
;
ArrayKind
ak
;
Type
(
TypeKind
tk
,
ArrayKind
ak
)
{
this
.
tk
=
tk
;
this
.
ak
=
ak
;
}
String
asString
()
{
return
tk
.
typeStr
+
ak
.
arrStr
;
}
}
enum
CastKind
{
ONE
(
"(#T0)"
,
1
),
TWO
(
"(#T0 & T1)"
,
2
),
THREE
(
"(#T0 & #T1 & #T2)"
,
3
);
String
castTemplate
;
int
nBounds
;
CastKind
(
String
castTemplate
,
int
nBounds
)
{
this
.
castTemplate
=
castTemplate
;
this
.
nBounds
=
nBounds
;
}
String
asString
(
Type
...
types
)
{
String
res
=
castTemplate
;
for
(
int
i
=
0
;
i
<
nBounds
;
i
++)
{
res
=
res
.
replaceAll
(
String
.
format
(
"#T%d"
,
i
),
types
[
i
].
asString
());
}
return
res
;
}
}
public
static
void
main
(
String
...
args
)
throws
Exception
{
//create default shared JavaCompiler - reused across multiple compilations
JavaCompiler
comp
=
ToolProvider
.
getSystemJavaCompiler
();
StandardJavaFileManager
fm
=
comp
.
getStandardFileManager
(
null
,
null
,
null
);
for
(
CastKind
ck
:
CastKind
.
values
())
{
for
(
TypeKind
t1
:
TypeKind
.
values
())
{
for
(
ArrayKind
ak1
:
ArrayKind
.
values
())
{
Type
typ1
=
new
Type
(
t1
,
ak1
);
if
(
ck
.
nBounds
==
1
)
{
new
IntersectionTypeParserTest
(
ck
,
typ1
).
run
(
comp
,
fm
);
continue
;
}
for
(
TypeKind
t2
:
TypeKind
.
values
())
{
for
(
ArrayKind
ak2
:
ArrayKind
.
values
())
{
Type
typ2
=
new
Type
(
t2
,
ak2
);
if
(
ck
.
nBounds
==
2
)
{
new
IntersectionTypeParserTest
(
ck
,
typ1
,
typ2
).
run
(
comp
,
fm
);
continue
;
}
for
(
TypeKind
t3
:
TypeKind
.
values
())
{
for
(
ArrayKind
ak3
:
ArrayKind
.
values
())
{
Type
typ3
=
new
Type
(
t3
,
ak3
);
new
IntersectionTypeParserTest
(
ck
,
typ1
,
typ2
,
typ3
).
run
(
comp
,
fm
);
}
}
}
}
}
}
}
System
.
out
.
println
(
"Total check executed: "
+
checkCount
);
}
CastKind
ck
;
Type
[]
types
;
JavaSource
source
;
DiagnosticChecker
diagChecker
;
IntersectionTypeParserTest
(
CastKind
ck
,
Type
...
types
)
{
this
.
ck
=
ck
;
this
.
types
=
types
;
this
.
source
=
new
JavaSource
();
this
.
diagChecker
=
new
DiagnosticChecker
();
}
class
JavaSource
extends
SimpleJavaFileObject
{
String
bodyTemplate
=
"class Test {\n"
+
" void test() {\n"
+
" Object o = #Cnull;\n"
+
" } }"
;
String
source
=
""
;
public
JavaSource
()
{
super
(
URI
.
create
(
"myfo:/Test.java"
),
JavaFileObject
.
Kind
.
SOURCE
);
source
+=
bodyTemplate
.
replaceAll
(
"#C"
,
ck
.
asString
(
types
));
}
@Override
public
CharSequence
getCharContent
(
boolean
ignoreEncodingErrors
)
{
return
source
;
}
}
void
run
(
JavaCompiler
tool
,
StandardJavaFileManager
fm
)
throws
Exception
{
checkCount
++;
JavacTask
ct
=
(
JavacTask
)
tool
.
getTask
(
null
,
fm
,
diagChecker
,
Arrays
.
asList
(
"-XDallowIntersectionTypes"
),
null
,
Arrays
.
asList
(
source
));
ct
.
parse
();
if
(
diagChecker
.
errorFound
)
{
throw
new
Error
(
"Unexpected parser error for source:\n"
+
source
.
getCharContent
(
true
));
}
}
static
class
DiagnosticChecker
implements
javax
.
tools
.
DiagnosticListener
<
JavaFileObject
>
{
boolean
errorFound
;
public
void
report
(
Diagnostic
<?
extends
JavaFileObject
>
diagnostic
)
{
if
(
diagnostic
.
getKind
()
==
Diagnostic
.
Kind
.
ERROR
)
{
errorFound
=
true
;
}
}
}
}
test/tools/javac/cast/intersection/model/Check.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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.
*/
/**
* Annotation used by ModelChecker to mark the class whose model is to be checked
*/
@interface
Check
{}
test/tools/javac/cast/intersection/model/IntersectionTypeInfo.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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.
*/
/**
* Used by ModelChecker to validate the modeling information of a union type.
*/
@interface
IntersectionTypeInfo
{
String
[]
value
();
}
test/tools/javac/cast/intersection/model/Member.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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
javax.lang.model.element.ElementKind
;
/**
* Annotation used by ModelChecker to mark a member that is to be checked
*/
@interface
Member
{
ElementKind
value
();
}
test/tools/javac/cast/intersection/model/Model01.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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 8002099
* @summary Add support for intersection types in cast expression
* @library ../../../lib
* @build JavacTestingAbstractProcessor ModelChecker
* @compile -XDallowIntersectionTypes -processor ModelChecker Model01.java
*/
import
javax.lang.model.element.ElementKind
;
@Check
class
Test
{
interface
A
{
@Member
(
ElementKind
.
METHOD
)
public
void
m1
();
}
interface
B
{
@Member
(
ElementKind
.
METHOD
)
public
void
m2
();
}
void
test
(){
@IntersectionTypeInfo
({
"java.lang.Object"
,
"Test.A"
,
"Test.B"
})
Object
o
=
(
A
&
B
)
null
;
}
}
test/tools/javac/cast/intersection/model/ModelChecker.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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
com.sun.source.tree.ExpressionTree
;
import
com.sun.source.tree.Tree
;
import
com.sun.source.tree.TypeCastTree
;
import
com.sun.source.tree.VariableTree
;
import
com.sun.source.util.TreePathScanner
;
import
com.sun.source.util.Trees
;
import
com.sun.source.util.TreePath
;
import
com.sun.tools.javac.tree.JCTree.JCExpression
;
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.lang.model.type.TypeMirror
;
import
javax.lang.model.type.TypeKind
;
import
javax.lang.model.type.IntersectionType
;
import
javax.lang.model.type.UnknownTypeException
;
import
javax.lang.model.util.SimpleTypeVisitor6
;
import
javax.lang.model.util.SimpleTypeVisitor7
;
@SupportedAnnotationTypes
(
"Check"
)
public
class
ModelChecker
extends
JavacTestingAbstractProcessor
{
@Override
public
boolean
process
(
Set
<?
extends
TypeElement
>
annotations
,
RoundEnvironment
roundEnv
)
{
if
(
roundEnv
.
processingOver
())
return
true
;
Trees
trees
=
Trees
.
instance
(
processingEnv
);
TypeElement
testAnno
=
elements
.
getTypeElement
(
"Check"
);
for
(
Element
elem:
roundEnv
.
getElementsAnnotatedWith
(
testAnno
))
{
TreePath
p
=
trees
.
getPath
(
elem
);
new
IntersectionCastTester
(
trees
).
scan
(
p
,
null
);
}
return
true
;
}
class
IntersectionCastTester
extends
TreePathScanner
<
Void
,
Void
>
{
Trees
trees
;
public
IntersectionCastTester
(
Trees
trees
)
{
super
();
this
.
trees
=
trees
;
}
@Override
public
Void
visitVariable
(
VariableTree
node
,
Void
p
)
{
TreePath
varPath
=
new
TreePath
(
getCurrentPath
(),
node
);
Element
v
=
trees
.
getElement
(
varPath
);
IntersectionTypeInfo
it
=
v
.
getAnnotation
(
IntersectionTypeInfo
.
class
);
assertTrue
(
it
!=
null
,
"IntersectionType annotation must be present"
);
ExpressionTree
varInit
=
node
.
getInitializer
();
assertTrue
(
varInit
!=
null
&&
varInit
.
getKind
()
==
Tree
.
Kind
.
TYPE_CAST
,
"variable must have be initialized to an expression containing an intersection type cast"
);
TypeMirror
t
=
((
JCExpression
)((
TypeCastTree
)
varInit
).
getType
()).
type
;
validateIntersectionTypeInfo
(
t
,
it
);
for
(
Element
e2
:
types
.
asElement
(
t
).
getEnclosedElements
())
{
assertTrue
(
false
,
"an intersection type has no declared members"
);
}
for
(
Element
e2
:
elements
.
getAllMembers
((
TypeElement
)
types
.
asElement
(
t
)))
{
Member
m
=
e2
.
getAnnotation
(
Member
.
class
);
if
(
m
!=
null
)
{
assertTrue
(
e2
.
getKind
()
==
m
.
value
(),
"Expected "
+
m
.
value
()
+
" - found "
+
e2
.
getKind
());
}
}
assertTrue
(
assertionCount
==
10
,
"Expected 10 assertions - found "
+
assertionCount
);
return
super
.
visitVariable
(
node
,
p
);
}
}
private
void
validateIntersectionTypeInfo
(
TypeMirror
expectedIntersectionType
,
IntersectionTypeInfo
it
)
{
assertTrue
(
expectedIntersectionType
.
getKind
()
==
TypeKind
.
INTERSECTION
,
"INTERSECTION kind expected"
);
try
{
new
SimpleTypeVisitor6
<
Void
,
Void
>(){}.
visit
(
expectedIntersectionType
);
throw
new
RuntimeException
(
"Expected UnknownTypeException not thrown."
);
}
catch
(
UnknownTypeException
ute
)
{
;
// Expected
}
try
{
new
SimpleTypeVisitor7
<
Void
,
Void
>(){}.
visit
(
expectedIntersectionType
);
throw
new
RuntimeException
(
"Expected UnknownTypeException not thrown."
);
}
catch
(
UnknownTypeException
ute
)
{
;
// Expected
}
IntersectionType
intersectionType
=
new
SimpleTypeVisitor
<
IntersectionType
,
Void
>(){
@Override
protected
IntersectionType
defaultAction
(
TypeMirror
e
,
Void
p
)
{
return
null
;}
@Override
public
IntersectionType
visitIntersection
(
IntersectionType
t
,
Void
p
)
{
return
t
;}
}.
visit
(
expectedIntersectionType
);
assertTrue
(
intersectionType
!=
null
,
"Must get a non-null intersection type."
);
assertTrue
(
it
.
value
().
length
==
intersectionType
.
getBounds
().
size
(),
"Cardinalities do not match"
);
String
[]
typeNames
=
it
.
value
();
for
(
int
i
=
0
;
i
<
typeNames
.
length
;
i
++)
{
TypeMirror
typeFromAnnotation
=
nameToType
(
typeNames
[
i
]);
assertTrue
(
types
.
isSameType
(
typeFromAnnotation
,
intersectionType
.
getBounds
().
get
(
i
)),
"Types were not equal."
);
}
}
private
TypeMirror
nameToType
(
String
name
)
{
return
elements
.
getTypeElement
(
name
).
asType
();
}
private
static
void
assertTrue
(
boolean
cond
,
String
msg
)
{
assertionCount
++;
if
(!
cond
)
throw
new
AssertionError
(
msg
);
}
static
int
assertionCount
=
0
;
}
test/tools/javac/defaultMethodExecution/DefaultMethodRegressionTests.java
→
test/tools/javac/defaultMethod
s/defaultMethod
Execution/DefaultMethodRegressionTests.java
浏览文件 @
104e71be
...
...
@@ -25,6 +25,7 @@
/**
* @test
* @ignore 8004360
* @bug 8003639
* @summary convert lambda testng tests to jtreg and add them
* @run testng DefaultMethodRegressionTests
...
...
test/tools/javac/diags/examples/IntersectionTypesInCastNotSupported.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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.
*/
// key: compiler.err.intersection.types.in.cast.not.supported.in.source
// options: -source 7 -Xlint:-options
interface
IntersectionTypesInCastNotSupported
{
Object
o
=
(
A
&
B
)
null
;
}
test/tools/javac/diags/examples/InvalidGeneric
DescInFunctionalInterface
.java
→
test/tools/javac/diags/examples/InvalidGeneric
LambdaTarget
.java
浏览文件 @
104e71be
...
...
@@ -22,9 +22,9 @@
*/
// key: compiler.err.prob.found.req
// key: compiler.misc.invalid.generic.
desc.in.functional.intf
// key: compiler.misc.invalid.generic.
lambda.target
class
InvalidGeneric
DescInFunctionalIntf
{
class
InvalidGeneric
LambdaTarget
{
interface
SAM
{
<
Z
>
void
m
();
...
...
test/tools/javac/diags/examples/SecondaryBoundMustBeMarkerIntf.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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.
*/
// key: compiler.err.prob.found.req
// key: compiler.misc.secondary.bound.must.be.marker.intf
// options: -XDallowIntersectionTypes
class
SecondaryBoundMustBeMarkerInterface
{
Runnable
r
=
(
Runnable
&
Comparable
<?>)()->{};
}
test/tools/javac/diags/examples/StaticBoundMref.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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.
*/
// key: compiler.err.invalid.mref
// key: compiler.misc.static.bound.mref
class
StaticBoundMref
{
Runnable
r
=
new
StaticBoundMref
()::
m
;
static
void
m
()
{
}
}
test/tools/javac/diags/examples/StaticMrefWithTargs.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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.
*/
// key: compiler.err.invalid.mref
// key: compiler.misc.static.mref.with.targs
class
StaticMrefWithTargs
<
X
>
{
Runnable
r
=
StaticMrefWithTargs
<
String
>::
m
;
static
void
m
()
{
}
}
test/tools/javac/lambda/
Lambda
ConversionTest.java
→
test/tools/javac/lambda/
FunctionalInterface
ConversionTest.java
浏览文件 @
104e71be
/*
* Copyright (c) 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 201
2
, 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
...
...
@@ -23,11 +23,11 @@
/**
* @test
* @bug 8003280
* @bug 8003280
8004102
* @summary Add lambda tests
* perform several automated checks in lambda conversion, esp. around accessibility
* @author Maurizio Cimadamore
* @run main
Lambda
ConversionTest
* @run main
FunctionalInterface
ConversionTest
*/
import
com.sun.source.util.JavacTask
;
...
...
@@ -37,9 +37,10 @@ import javax.tools.Diagnostic;
import
javax.tools.JavaCompiler
;
import
javax.tools.JavaFileObject
;
import
javax.tools.SimpleJavaFileObject
;
import
javax.tools.StandardJavaFileManager
;
import
javax.tools.ToolProvider
;
public
class
Lambda
ConversionTest
{
public
class
FunctionalInterface
ConversionTest
{
enum
PackageKind
{
NO_PKG
(
""
),
...
...
@@ -108,10 +109,21 @@ public class LambdaConversionTest {
}
}
enum
ExprKind
{
LAMBDA
(
"x -> null"
),
MREF
(
"this::m"
);
String
exprStr
;
private
ExprKind
(
String
exprStr
)
{
this
.
exprStr
=
exprStr
;
}
}
enum
MethodKind
{
NONE
(
""
),
NON_GENERIC
(
"public #R m(#ARG s) throws #T;"
),
GENERIC
(
"public <X> #R m(#ARG s) throws #T;"
);
NON_GENERIC
(
"public
abstract
#R m(#ARG s) throws #T;"
),
GENERIC
(
"public
abstract
<X> #R m(#ARG s) throws #T;"
);
String
methodTemplate
;
...
...
@@ -127,15 +139,21 @@ public class LambdaConversionTest {
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
final
JavaCompiler
comp
=
ToolProvider
.
getSystemJavaCompiler
();
StandardJavaFileManager
fm
=
comp
.
getStandardFileManager
(
null
,
null
,
null
);
for
(
PackageKind
samPkg
:
PackageKind
.
values
())
{
for
(
ModifierKind
modKind
:
ModifierKind
.
values
())
{
for
(
SamKind
samKind
:
SamKind
.
values
())
{
for
(
MethodKind
meth
:
MethodKind
.
values
())
{
for
(
TypeKind
retType
:
TypeKind
.
values
())
{
for
(
TypeKind
argType
:
TypeKind
.
values
())
{
for
(
TypeKind
thrownType
:
TypeKind
.
values
())
{
new
LambdaConversionTest
(
samPkg
,
modKind
,
samKind
,
meth
,
retType
,
argType
,
thrownType
).
test
();
for
(
MethodKind
samMeth
:
MethodKind
.
values
())
{
for
(
MethodKind
clientMeth
:
MethodKind
.
values
())
{
for
(
TypeKind
retType
:
TypeKind
.
values
())
{
for
(
TypeKind
argType
:
TypeKind
.
values
())
{
for
(
TypeKind
thrownType
:
TypeKind
.
values
())
{
for
(
ExprKind
exprKind
:
ExprKind
.
values
())
{
new
FunctionalInterfaceConversionTest
(
samPkg
,
modKind
,
samKind
,
samMeth
,
clientMeth
,
retType
,
argType
,
thrownType
,
exprKind
).
test
(
comp
,
fm
);
}
}
}
}
}
...
...
@@ -148,15 +166,18 @@ public class LambdaConversionTest {
PackageKind
samPkg
;
ModifierKind
modKind
;
SamKind
samKind
;
MethodKind
meth
;
MethodKind
samMeth
;
MethodKind
clientMeth
;
TypeKind
retType
;
TypeKind
argType
;
TypeKind
thrownType
;
ExprKind
exprKind
;
DiagnosticChecker
dc
;
SourceFile
samSourceFile
=
new
SourceFile
(
"Sam.java"
,
"#P \n #C"
)
{
public
String
toString
()
{
return
template
.
replaceAll
(
"#P"
,
samPkg
.
getPkgDecl
()).
replaceAll
(
"#C"
,
samKind
.
getSam
(
m
eth
.
getMethod
(
retType
,
argType
,
thrownType
)));
replaceAll
(
"#C"
,
samKind
.
getSam
(
samM
eth
.
getMethod
(
retType
,
argType
,
thrownType
)));
}
};
...
...
@@ -169,27 +190,33 @@ public class LambdaConversionTest {
};
SourceFile
clientSourceFile
=
new
SourceFile
(
"Client.java"
,
"#I\n class Client { Sam s = x -> null; }"
)
{
"#I\n abstract class Client { \n"
+
" Sam s = #E;\n"
+
" #M \n }"
)
{
public
String
toString
()
{
return
template
.
replaceAll
(
"#I"
,
samPkg
.
getImportStat
());
return
template
.
replaceAll
(
"#I"
,
samPkg
.
getImportStat
())
.
replaceAll
(
"#E"
,
exprKind
.
exprStr
)
.
replaceAll
(
"#M"
,
clientMeth
.
getMethod
(
retType
,
argType
,
thrownType
));
}
};
LambdaConversionTest
(
PackageKind
samPkg
,
ModifierKind
modKind
,
SamKind
samKind
,
MethodKind
meth
,
TypeKind
retType
,
TypeKind
argType
,
TypeKind
thrownType
)
{
FunctionalInterfaceConversionTest
(
PackageKind
samPkg
,
ModifierKind
modKind
,
SamKind
samKind
,
MethodKind
samMeth
,
MethodKind
clientMeth
,
TypeKind
retType
,
TypeKind
argType
,
TypeKind
thrownType
,
ExprKind
exprKind
)
{
this
.
samPkg
=
samPkg
;
this
.
modKind
=
modKind
;
this
.
samKind
=
samKind
;
this
.
meth
=
meth
;
this
.
samMeth
=
samMeth
;
this
.
clientMeth
=
clientMeth
;
this
.
retType
=
retType
;
this
.
argType
=
argType
;
this
.
thrownType
=
thrownType
;
this
.
exprKind
=
exprKind
;
this
.
dc
=
new
DiagnosticChecker
();
}
void
test
()
throws
Exception
{
final
JavaCompiler
tool
=
ToolProvider
.
getSystemJavaCompiler
();
DiagnosticChecker
dc
=
new
DiagnosticChecker
();
JavacTask
ct
=
(
JavacTask
)
tool
.
getTask
(
null
,
null
,
dc
,
void
test
(
JavaCompiler
comp
,
StandardJavaFileManager
fm
)
throws
Exception
{
JavacTask
ct
=
(
JavacTask
)
comp
.
getTask
(
null
,
fm
,
dc
,
null
,
null
,
Arrays
.
asList
(
samSourceFile
,
pkgClassSourceFile
,
clientSourceFile
));
ct
.
analyze
();
if
(
dc
.
errorFound
==
checkSamConversion
())
{
...
...
@@ -201,8 +228,15 @@ public class LambdaConversionTest {
if
(
samKind
!=
SamKind
.
INTERFACE
)
{
//sam type must be an interface
return
false
;
}
else
if
(
meth
!=
MethodKind
.
NON_GENERIC
)
{
//target method must be non-generic
}
else
if
(
samMeth
==
MethodKind
.
NONE
)
{
//interface must have at least a method
return
false
;
}
else
if
(
exprKind
==
ExprKind
.
LAMBDA
&&
samMeth
!=
MethodKind
.
NON_GENERIC
)
{
//target method for lambda must be non-generic
return
false
;
}
else
if
(
exprKind
==
ExprKind
.
MREF
&&
clientMeth
==
MethodKind
.
NONE
)
{
return
false
;
}
else
if
(
samPkg
!=
PackageKind
.
NO_PKG
&&
modKind
!=
ModifierKind
.
PUBLIC
&&
...
...
test/tools/javac/lambda/Intersection01.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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 8002099
* @summary Add support for intersection types in cast expression
* @compile/fail/ref=Intersection01.out -XDallowIntersectionTypes -XDrawDiagnostics Intersection01.java
*/
class
Intersection01
{
interface
SAM
{
void
m
();
}
Object
o1
=
(
java
.
io
.
Serializable
&
SAM
)()->{};
Object
o2
=
(
SAM
&
java
.
io
.
Serializable
)()->{};
Object
o3
=
(
java
.
io
.
Serializable
&
SAM
)
Intersection01:
:
m
;
Object
o4
=
(
SAM
&
java
.
io
.
Serializable
)
Intersection01:
:
m
;
static
void
m
()
{
}
}
test/tools/javac/lambda/Intersection01.out
0 → 100644
浏览文件 @
104e71be
Intersection01.java:36:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
Intersection01.java:38:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
2 errors
test/tools/javac/lambda/LambdaConv21.java
浏览文件 @
104e71be
...
...
@@ -23,7 +23,7 @@ class LambdaConv21 {
static
void
testExpressionLambda
()
{
SAM_void
s1
=
()->
m_void
();
//ok
SAM_java_lang_Void
s2
=
()->
m_void
();
//no - incompatible target
SAM_void
s3
=
()->
m_java_lang_Void
();
//
no - incompatible target
SAM_void
s3
=
()->
m_java_lang_Void
();
//
ok - expression statement lambda is compatible with void
SAM_java_lang_Void
s4
=
()->
m_java_lang_Void
();
//ok
}
...
...
test/tools/javac/lambda/LambdaConv21.out
浏览文件 @
104e71be
LambdaConv21.java:25:43: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: void, java.lang.Void))
LambdaConv21.java:26:43: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Void, void))
LambdaConv21.java:32:33: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.missing.ret.val: java.lang.Void))
LambdaConv21.java:33:53: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.unexpected.ret.val))
LambdaConv21.java:36:33: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.missing.ret.val: java.lang.Void))
5
errors
4
errors
test/tools/javac/lambda/LambdaParserTest.java
浏览文件 @
104e71be
...
...
@@ -90,9 +90,14 @@ public class LambdaParserTest {
enum
LambdaParameterKind
{
IMPLICIT
(
""
),
EXPLIICT_SIMPLE
(
"A"
),
EXPLIICT_SIMPLE_ARR1
(
"A[]"
),
EXPLIICT_SIMPLE_ARR2
(
"A[][]"
),
EXPLICIT_VARARGS
(
"A..."
),
EXPLICIT_GENERIC1
(
"A<X>"
),
EXPLICIT_GENERIC3
(
"A<? extends X, ? super Y>"
);
EXPLICIT_GENERIC2
(
"A<? extends X, ? super Y>"
),
EXPLICIT_GENERIC2_VARARGS
(
"A<? extends X, ? super Y>..."
),
EXPLICIT_GENERIC2_ARR1
(
"A<? extends X, ? super Y>[]"
),
EXPLICIT_GENERIC2_ARR2
(
"A<? extends X, ? super Y>[][]"
);
String
parameterType
;
...
...
@@ -103,6 +108,11 @@ public class LambdaParserTest {
boolean
explicit
()
{
return
this
!=
IMPLICIT
;
}
boolean
isVarargs
()
{
return
this
==
EXPLICIT_VARARGS
||
this
==
EXPLICIT_GENERIC2_VARARGS
;
}
}
enum
ModifierKind
{
...
...
@@ -253,7 +263,7 @@ public class LambdaParserTest {
if
(
lk
.
arity
()
==
2
&&
(
pk1
.
explicit
()
!=
pk2
.
explicit
()
||
pk1
==
LambdaParameterKind
.
EXPLICIT_VARARGS
))
{
pk1
.
isVarargs
()
))
{
errorExpected
=
true
;
}
...
...
test/tools/javac/lambda/MethodReference30.java
浏览文件 @
104e71be
...
...
@@ -46,7 +46,7 @@ public class MethodReference30 {
assertTrue
(
true
);
}
static
void
m
()
{
}
void
m
()
{
}
public
static
void
main
(
String
[]
args
)
{
SAM
s
=
new
MethodReference30
()::
m
;
...
...
test/tools/javac/lambda/MethodReference55.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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 8004101
* @summary Add checks for method reference well-formedness
* @compile/fail/ref=MethodReference55.out -XDrawDiagnostics MethodReference55.java
*/
class
MethodReference55
<
X
>
{
interface
V
{
void
m
(
Object
o
);
}
V
v
=
new
MethodReference55
<
String
>()::
m
;
void
test
()
{
g
(
new
MethodReference55
<
String
>()::
m
);
}
void
g
(
V
v
)
{
}
static
void
m
(
Object
o
)
{
};
}
test/tools/javac/lambda/MethodReference55.out
0 → 100644
浏览文件 @
104e71be
MethodReference55.java:36:11: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.bound.mref)
MethodReference55.java:39:11: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.bound.mref)
2 errors
test/tools/javac/lambda/MethodReference56.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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 8004101
* @summary Add checks for method reference well-formedness
* @compile/fail/ref=MethodReference56.out -XDrawDiagnostics MethodReference56.java
*/
class
MethodReference56
<
X
>
{
interface
V
{
void
m
(
Object
o
);
}
V
v
=
MethodReference56
<
String
>::
m
;
void
test
()
{
g
(
MethodReference56
<
String
>::
m
);
}
void
g
(
V
v
)
{
}
static
void
m
(
Object
o
)
{
};
}
test/tools/javac/lambda/MethodReference56.out
0 → 100644
浏览文件 @
104e71be
MethodReference56.java:36:28: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.mref.with.targs)
MethodReference56.java:39:28: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.mref.with.targs)
2 errors
test/tools/javac/lambda/MethodReference57.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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 8004102
* @summary Add support for generic functional descriptors
* @compile MethodReference57.java
*/
class
MethodReference57
{
interface
F
{
<
X
>
void
m
();
}
void
test
()
{
F
f
=
this
::
g
;
//ok
}
void
g
()
{
}
}
test/tools/javac/lambda/MethodReference58.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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 8004102
* @summary Add support for generic functional descriptors
* @compile/fail/ref=MethodReference58.out -XDrawDiagnostics MethodReference58.java
*/
class
MethodReference58
{
interface
F_Object
{
<
X
>
void
m
(
X
x
);
}
interface
F_Integer
{
<
X
extends
Integer
>
void
m
(
X
x
);
}
void
test
()
{
F_Object
f1
=
this
::
g
;
//incompatible bounds
F_Integer
f2
=
this
::
g
;
//ok
}
<
Z
extends
Number
>
void
g
(
Z
z
)
{
}
}
test/tools/javac/lambda/MethodReference58.out
0 → 100644
浏览文件 @
104e71be
MethodReference58.java:41:23: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, g, Z, X, kindname.class, MethodReference58, (compiler.misc.inferred.do.not.conform.to.upper.bounds: X, java.lang.Number)))
1 error
test/tools/javac/lambda/VoidCompatibility.out
浏览文件 @
104e71be
VoidCompatibility.java:17:9: compiler.err.ref.ambiguous: schedule, kindname.method, schedule(VoidCompatibility.Runnable), VoidCompatibility, kindname.method, schedule(VoidCompatibility.Thunk<?>), VoidCompatibility
VoidCompatibility.java:23:9: compiler.err.ref.ambiguous: schedule, kindname.method, schedule(VoidCompatibility.Runnable), VoidCompatibility, kindname.method, schedule(VoidCompatibility.Thunk<?>), VoidCompatibility
1 error
2 errors
test/tools/javac/lambda/intersection/IntersectionTargetTypeTest.java
0 → 100644
浏览文件 @
104e71be
/*
* Copyright (c) 2012, 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 8002099
* @summary Add support for intersection types in cast expression
*/
import
com.sun.source.util.JavacTask
;
import
com.sun.tools.javac.util.List
;
import
com.sun.tools.javac.util.ListBuffer
;
import
java.net.URI
;
import
java.util.Arrays
;
import
javax.tools.Diagnostic
;
import
javax.tools.JavaCompiler
;
import
javax.tools.JavaFileObject
;
import
javax.tools.SimpleJavaFileObject
;
import
javax.tools.StandardJavaFileManager
;
import
javax.tools.ToolProvider
;
public
class
IntersectionTargetTypeTest
{
static
int
checkCount
=
0
;
enum
BoundKind
{
INTF
,
CLASS
,
SAM
,
ZAM
;
}
enum
MethodKind
{
NONE
,
ABSTRACT
,
DEFAULT
;
}
enum
TypeKind
{
A
(
"interface A { }\n"
,
"A"
,
BoundKind
.
ZAM
),
B
(
"interface B { default void m() { } }\n"
,
"B"
,
BoundKind
.
ZAM
),
C
(
"interface C { void m(); }\n"
,
"C"
,
BoundKind
.
SAM
),
D
(
"interface D extends B { }\n"
,
"D"
,
BoundKind
.
ZAM
),
E
(
"interface E extends C { }\n"
,
"E"
,
BoundKind
.
SAM
),
F
(
"interface F extends C { void g(); }\n"
,
"F"
,
BoundKind
.
INTF
),
G
(
"interface G extends B { void g(); }\n"
,
"G"
,
BoundKind
.
SAM
),
H
(
"interface H extends A { void g(); }\n"
,
"H"
,
BoundKind
.
SAM
),
OBJECT
(
""
,
"Object"
,
BoundKind
.
CLASS
),
STRING
(
""
,
"String"
,
BoundKind
.
CLASS
);
String
declStr
;
String
typeStr
;
BoundKind
boundKind
;
private
TypeKind
(
String
declStr
,
String
typeStr
,
BoundKind
boundKind
)
{
this
.
declStr
=
declStr
;
this
.
typeStr
=
typeStr
;
this
.
boundKind
=
boundKind
;
}
boolean
compatibleSupertype
(
TypeKind
tk
)
{
if
(
tk
==
this
)
return
true
;
switch
(
tk
)
{
case
B:
return
this
!=
C
&&
this
!=
E
&&
this
!=
F
;
case
C:
return
this
!=
B
&&
this
!=
C
&&
this
!=
D
&&
this
!=
G
;
case
D:
return
compatibleSupertype
(
B
);
case
E:
case
F:
return
compatibleSupertype
(
C
);
case
G:
return
compatibleSupertype
(
B
);
case
H:
return
compatibleSupertype
(
A
);
default
:
return
true
;
}
}
}
enum
CastKind
{
ONE_ARY
(
"(#B0)"
,
1
),
TWO_ARY
(
"(#B0 & #B1)"
,
2
),
THREE_ARY
(
"(#B0 & #B1 & #B2)"
,
3
);
String
castTemplate
;
int
nbounds
;
CastKind
(
String
castTemplate
,
int
nbounds
)
{
this
.
castTemplate
=
castTemplate
;
this
.
nbounds
=
nbounds
;
}
}
enum
ExpressionKind
{
LAMBDA
(
"()->{}"
,
true
),
MREF
(
"this::m"
,
true
),
//COND_LAMBDA("(true ? ()->{} : ()->{})", true), re-enable if spec allows this
//COND_MREF("(true ? this::m : this::m)", true),
STANDALONE
(
"null"
,
false
);
String
exprString
;
boolean
isFunctional
;
private
ExpressionKind
(
String
exprString
,
boolean
isFunctional
)
{
this
.
exprString
=
exprString
;
this
.
isFunctional
=
isFunctional
;
}
}
static
class
CastInfo
{
CastKind
kind
;
TypeKind
[]
types
;
CastInfo
(
CastKind
kind
,
TypeKind
...
types
)
{
this
.
kind
=
kind
;
this
.
types
=
types
;
}
String
getCast
()
{
String
temp
=
kind
.
castTemplate
;
for
(
int
i
=
0
;
i
<
kind
.
nbounds
;
i
++)
{
temp
=
temp
.
replace
(
String
.
format
(
"#B%d"
,
i
),
types
[
i
].
typeStr
);
}
return
temp
;
}
boolean
wellFormed
()
{
//check for duplicate types
for
(
int
i
=
0
;
i
<
types
.
length
;
i
++)
{
for
(
int
j
=
0
;
j
<
types
.
length
;
j
++)
{
if
(
i
!=
j
&&
types
[
i
]
==
types
[
j
])
{
return
false
;
}
}
}
//check that classes only appear as first bound
boolean
classOk
=
true
;
for
(
int
i
=
0
;
i
<
types
.
length
;
i
++)
{
if
(
types
[
i
].
boundKind
==
BoundKind
.
CLASS
&&
!
classOk
)
{
return
false
;
}
classOk
=
false
;
}
//check that supertypes are mutually compatible
for
(
int
i
=
0
;
i
<
types
.
length
;
i
++)
{
for
(
int
j
=
0
;
j
<
types
.
length
;
j
++)
{
if
(!
types
[
i
].
compatibleSupertype
(
types
[
j
])
&&
i
!=
j
)
{
return
false
;
}
}
}
return
true
;
}
}
public
static
void
main
(
String
...
args
)
throws
Exception
{
//create default shared JavaCompiler - reused across multiple compilations
JavaCompiler
comp
=
ToolProvider
.
getSystemJavaCompiler
();
StandardJavaFileManager
fm
=
comp
.
getStandardFileManager
(
null
,
null
,
null
);
for
(
CastInfo
cInfo
:
allCastInfo
())
{
for
(
ExpressionKind
ek
:
ExpressionKind
.
values
())
{
new
IntersectionTargetTypeTest
(
cInfo
,
ek
).
run
(
comp
,
fm
);
}
}
System
.
out
.
println
(
"Total check executed: "
+
checkCount
);
}
static
List
<
CastInfo
>
allCastInfo
()
{
ListBuffer
<
CastInfo
>
buf
=
ListBuffer
.
lb
();
for
(
CastKind
kind
:
CastKind
.
values
())
{
for
(
TypeKind
b1
:
TypeKind
.
values
())
{
if
(
kind
.
nbounds
==
1
)
{
buf
.
append
(
new
CastInfo
(
kind
,
b1
));
continue
;
}
else
{
for
(
TypeKind
b2
:
TypeKind
.
values
())
{
if
(
kind
.
nbounds
==
2
)
{
buf
.
append
(
new
CastInfo
(
kind
,
b1
,
b2
));
continue
;
}
else
{
for
(
TypeKind
b3
:
TypeKind
.
values
())
{
buf
.
append
(
new
CastInfo
(
kind
,
b1
,
b2
,
b3
));
}
}
}
}
}
}
return
buf
.
toList
();
}
CastInfo
cInfo
;
ExpressionKind
ek
;
JavaSource
source
;
DiagnosticChecker
diagChecker
;
IntersectionTargetTypeTest
(
CastInfo
cInfo
,
ExpressionKind
ek
)
{
this
.
cInfo
=
cInfo
;
this
.
ek
=
ek
;
this
.
source
=
new
JavaSource
();
this
.
diagChecker
=
new
DiagnosticChecker
();
}
class
JavaSource
extends
SimpleJavaFileObject
{
String
bodyTemplate
=
"class Test {\n"
+
" void m() { }\n"
+
" void test() {\n"
+
" Object o = #C#E;\n"
+
" } }"
;
String
source
=
""
;
public
JavaSource
()
{
super
(
URI
.
create
(
"myfo:/Test.java"
),
JavaFileObject
.
Kind
.
SOURCE
);
for
(
TypeKind
tk
:
TypeKind
.
values
())
{
source
+=
tk
.
declStr
;
}
source
+=
bodyTemplate
.
replaceAll
(
"#C"
,
cInfo
.
getCast
()).
replaceAll
(
"#E"
,
ek
.
exprString
);
}
@Override
public
CharSequence
getCharContent
(
boolean
ignoreEncodingErrors
)
{
return
source
;
}
}
void
run
(
JavaCompiler
tool
,
StandardJavaFileManager
fm
)
throws
Exception
{
JavacTask
ct
=
(
JavacTask
)
tool
.
getTask
(
null
,
fm
,
diagChecker
,
Arrays
.
asList
(
"-XDallowIntersectionTypes"
),
null
,
Arrays
.
asList
(
source
));
try
{
ct
.
analyze
();
}
catch
(
Throwable
ex
)
{
throw
new
AssertionError
(
"Error thrown when compiling the following code:\n"
+
source
.
getCharContent
(
true
));
}
check
();
}
void
check
()
{
checkCount
++;
boolean
errorExpected
=
!
cInfo
.
wellFormed
();
if
(
ek
.
isFunctional
)
{
//first bound must be a SAM
errorExpected
|=
cInfo
.
types
[
0
].
boundKind
!=
BoundKind
.
SAM
;
if
(
cInfo
.
types
.
length
>
1
)
{
//additional bounds must be ZAMs
for
(
int
i
=
1
;
i
<
cInfo
.
types
.
length
;
i
++)
{
errorExpected
|=
cInfo
.
types
[
i
].
boundKind
!=
BoundKind
.
ZAM
;
}
}
}
if
(
errorExpected
!=
diagChecker
.
errorFound
)
{
throw
new
Error
(
"invalid diagnostics for source:\n"
+
source
.
getCharContent
(
true
)
+
"\nFound error: "
+
diagChecker
.
errorFound
+
"\nExpected error: "
+
errorExpected
);
}
}
static
class
DiagnosticChecker
implements
javax
.
tools
.
DiagnosticListener
<
JavaFileObject
>
{
boolean
errorFound
;
public
void
report
(
Diagnostic
<?
extends
JavaFileObject
>
diagnostic
)
{
if
(
diagnostic
.
getKind
()
==
Diagnostic
.
Kind
.
ERROR
)
{
errorFound
=
true
;
}
}
}
}
test/tools/javac/lambda/methodReference/MethodRef1.java
浏览文件 @
104e71be
...
...
@@ -70,9 +70,6 @@ public class MethodRef1 {
b
=
MethodRef1:
:
foo
;
//static reference to foo(int)
b
.
m
(
1
);
b
=
new
MethodRef1
()::
foo
;
//instance reference to static methods, supported for now
b
.
m
(
1
);
b
=
MethodRef1:
:
bar
;
//static reference to bar(int)
b
.
m
(
2
);
...
...
test/tools/javac/lambda/methodReference/SamConversion.java
浏览文件 @
104e71be
...
...
@@ -133,15 +133,6 @@ public class SamConversion {
}
catch
(
Exception
e
)
{
assertTrue
(
false
);
}
bar
=
new
A
()::
method6
;
try
{
bar
.
m
(
1
);
assertTrue
(
false
);
}
catch
(
MyException
e
)
{
}
catch
(
Exception
e
)
{
assertTrue
(
false
);
}
}
/**
...
...
test/tools/javac/lambda/methodReferenceExecution/MethodReferenceTestKinds.java
浏览文件 @
104e71be
...
...
@@ -119,20 +119,6 @@ public class MethodReferenceTestKinds extends MethodReferenceTestKindsSup {
assertEquals
(
var
.
get
(
inst
(
"arg"
)),
"SM:1-MethodReferenceTestKinds(arg)"
);
}
public
void
testMRStaticEval
()
{
MethodReferenceTestKinds
evalCheck
;
S0
var
=
(
evalCheck
=
inst
(
"discard"
))::
staticMethod0
;
assertEquals
(
evalCheck
.
toString
(),
"MethodReferenceTestKinds(discard)"
);
assertEquals
(
var
.
get
(),
"SM:0"
);
}
public
void
testMRStaticEvalArg
()
{
MethodReferenceTestKinds
evalCheck
;
S1
var
=
(
evalCheck
=
inst
(
"discard"
))::
staticMethod1
;
assertEquals
(
evalCheck
.
toString
(),
"MethodReferenceTestKinds(discard)"
);
assertEquals
(
var
.
get
(
inst
(
"arg"
)),
"SM:1-MethodReferenceTestKinds(arg)"
);
}
public
void
testMRTopLevel
()
{
SN0
var
=
MethodReferenceTestKindsBase:
:
new
;
assertEquals
(
var
.
make
().
toString
(),
"MethodReferenceTestKindsBase(blank)"
);
...
...
@@ -142,17 +128,7 @@ public class MethodReferenceTestKinds extends MethodReferenceTestKindsSup {
SN1
var
=
MethodReferenceTestKindsBase:
:
new
;
assertEquals
(
var
.
make
(
"name"
).
toString
(),
"MethodReferenceTestKindsBase(name)"
);
}
/* unbound inner case not supported anymore (dropped by EG)
public void testMRUnboundInner() {
SXN0 var = MethodReferenceTestKinds.In::new;
assertEquals(var.make(inst("out")).toString(), "In(blank)");
}
public void testMRUnboundInnerArg() {
SXN1 var = MethodReferenceTestKinds.In::new;
assertEquals(var.make(inst("out"), "name").toString(), "In(name)");
}
*/
public
void
testMRImplicitInner
()
{
SN0
var
=
MethodReferenceTestKinds
.
In
::
new
;
assertEquals
(
var
.
make
().
toString
(),
"In(blank)"
);
...
...
test/tools/javap/T7190862.java
0 → 100644
浏览文件 @
104e71be
/*
* @test /nodynamiccopyright/
* @bug 7190862 7109747
* @summary javap shows an incorrect type for operands if the 'wide' prefix is used
*/
import
com.sun.source.util.JavacTask
;
import
com.sun.tools.javap.JavapFileManager
;
import
com.sun.tools.javap.JavapTask
;
import
java.io.PrintWriter
;
import
java.io.StringWriter
;
import
java.net.URI
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.Locale
;
import
javax.tools.Diagnostic
;
import
javax.tools.DiagnosticCollector
;
import
javax.tools.JavaCompiler
;
import
javax.tools.JavaFileManager
;
import
javax.tools.JavaFileObject
;
import
javax.tools.SimpleJavaFileObject
;
import
javax.tools.ToolProvider
;
public
class
T7190862
{
enum
TypeWideInstructionMap
{
INT
(
"int"
,
new
String
[]{
"istore_w"
,
"iload_w"
}),
LONG
(
"long"
,
new
String
[]{
"lstore_w"
,
"lload_w"
}),
FLOAT
(
"float"
,
new
String
[]{
"fstore_w"
,
"fload_w"
}),
DOUBLE
(
"double"
,
new
String
[]{
"dstore_w"
,
"dload_w"
}),
OBJECT
(
"Object"
,
new
String
[]{
"astore_w"
,
"aload_w"
});
String
type
;
String
[]
instructions
;
TypeWideInstructionMap
(
String
type
,
String
[]
instructions
)
{
this
.
type
=
type
;
this
.
instructions
=
instructions
;
}
}
JavaSource
source
;
public
static
void
main
(
String
[]
args
)
{
JavaCompiler
comp
=
ToolProvider
.
getSystemJavaCompiler
();
new
T7190862
().
run
(
comp
);
}
private
void
run
(
JavaCompiler
comp
)
{
String
code
;
for
(
TypeWideInstructionMap
typeInstructionMap:
TypeWideInstructionMap
.
values
())
{
if
(
typeInstructionMap
!=
TypeWideInstructionMap
.
OBJECT
)
{
code
=
createWideLocalSource
(
typeInstructionMap
.
type
,
300
);
}
else
{
code
=
createWideLocalSourceForObject
(
300
);
}
source
=
new
JavaSource
(
code
);
compile
(
comp
);
check
(
typeInstructionMap
.
instructions
);
}
//an extra test for the iinc instruction
code
=
createIincSource
();
source
=
new
JavaSource
(
code
);
compile
(
comp
);
check
(
new
String
[]{
"iinc_w"
});
}
private
void
compile
(
JavaCompiler
comp
)
{
JavacTask
ct
=
(
JavacTask
)
comp
.
getTask
(
null
,
null
,
null
,
null
,
null
,
Arrays
.
asList
(
source
));
try
{
if
(!
ct
.
call
())
{
throw
new
AssertionError
(
"Error thrown when compiling the following source:\n"
+
source
.
getCharContent
(
true
));
}
}
catch
(
Throwable
ex
)
{
throw
new
AssertionError
(
"Error thrown when compiling the following source:\n"
+
source
.
getCharContent
(
true
));
}
}
private
void
check
(
String
[]
instructions
)
{
String
out
=
javap
(
Arrays
.
asList
(
"-c"
),
Arrays
.
asList
(
"Test.class"
));
for
(
String
line:
out
.
split
(
System
.
getProperty
(
"line.separator"
)))
{
line
=
line
.
trim
();
for
(
String
instruction:
instructions
)
{
if
(
line
.
contains
(
instruction
)
&&
line
.
contains
(
"#"
))
{
throw
new
Error
(
"incorrect type for operands for instruction "
+
instruction
);
}
}
}
}
private
String
javap
(
List
<
String
>
args
,
List
<
String
>
classes
)
{
DiagnosticCollector
<
JavaFileObject
>
dc
=
new
DiagnosticCollector
<
JavaFileObject
>();
StringWriter
sw
=
new
StringWriter
();
PrintWriter
pw
=
new
PrintWriter
(
sw
);
JavaFileManager
fm
=
JavapFileManager
.
create
(
dc
,
pw
);
JavapTask
t
=
new
JavapTask
(
pw
,
fm
,
dc
,
args
,
classes
);
boolean
ok
=
t
.
run
();
if
(!
ok
)
throw
new
Error
(
"javap failed unexpectedly"
);
List
<
Diagnostic
<?
extends
JavaFileObject
>>
diags
=
dc
.
getDiagnostics
();
for
(
Diagnostic
<?
extends
JavaFileObject
>
d:
diags
)
{
if
(
d
.
getKind
()
==
Diagnostic
.
Kind
.
ERROR
)
throw
new
Error
(
d
.
getMessage
(
Locale
.
ENGLISH
));
}
return
sw
.
toString
();
}
private
String
createWideLocalSource
(
String
type
,
int
numberOfVars
)
{
String
result
=
" "
+
type
+
" x0 = 0;\n"
;
for
(
int
i
=
1
;
i
<
numberOfVars
;
i
++)
{
result
+=
" "
+
type
+
" x"
+
i
+
" = x"
+
(
i
-
1
)
+
" + 1;\n"
;
}
return
result
;
}
private
String
createWideLocalSourceForObject
(
int
numberOfVars
)
{
String
result
=
" Object x0 = new Object();\n"
;
for
(
int
i
=
1
;
i
<
numberOfVars
;
i
++)
{
result
+=
" Object x"
+
i
+
" = x0;\n"
;
}
return
result
;
}
private
String
createIincSource
()
{
return
" int i = 0;\n"
+
" i += 1;\n"
+
" i += 51;\n"
+
" i += 101;\n"
+
" i += 151;\n"
;
}
class
JavaSource
extends
SimpleJavaFileObject
{
String
template
=
"class Test {\n"
+
" public static void main(String[] args)\n"
+
" {\n"
+
" #C"
+
" }\n"
+
"}"
;
String
source
;
public
JavaSource
(
String
code
)
{
super
(
URI
.
create
(
"Test.java"
),
JavaFileObject
.
Kind
.
SOURCE
);
source
=
template
.
replaceAll
(
"#C"
,
code
);
}
@Override
public
CharSequence
getCharContent
(
boolean
ignoreEncodingErrors
)
{
return
source
;
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录