提交 c74daecb 编写于 作者: M mcimadamore

8005166: Add support for static interface methods

Summary: Support public static interface methods
Reviewed-by: jjg
上级 a18476a0
......@@ -280,7 +280,7 @@ public class Flags {
SYNCHRONIZED | FINAL | STRICTFP;
public static final long
ExtendedStandardFlags = (long)StandardFlags | DEFAULT,
InterfaceDefaultMethodMask = ABSTRACT | PUBLIC | STRICTFP | DEFAULT,
InterfaceMethodMask = ABSTRACT | STATIC | PUBLIC | STRICTFP | DEFAULT,
LocalVarFlags = FINAL | PARAMETER;
......
......@@ -206,6 +206,9 @@ public enum Source {
public boolean allowDefaultMethods() {
return compareTo(JDK1_8) >= 0;
}
public boolean allowStaticInterfaceMethods() {
return compareTo(JDK1_8) >= 0;
}
public boolean allowStrictMethodClashCheck() {
return compareTo(JDK1_8) >= 0;
}
......
......@@ -1233,7 +1233,8 @@ public abstract class Symbol implements Element {
case Flags.PRIVATE:
return false;
case Flags.PUBLIC:
return true;
return !this.owner.isInterface() ||
(flags_field & STATIC) == 0;
case Flags.PROTECTED:
return (origin.flags() & INTERFACE) == 0;
case 0:
......@@ -1247,6 +1248,18 @@ public abstract class Symbol implements Element {
}
}
@Override
public boolean isInheritedIn(Symbol clazz, Types types) {
switch ((int)(flags_field & Flags.AccessFlags)) {
case PUBLIC:
return !this.owner.isInterface() ||
clazz == owner ||
(flags_field & STATIC) == 0;
default:
return super.isInheritedIn(clazz, types);
}
}
/** The implementation of this (abstract) symbol in class origin;
* null if none exists. Synthetic methods are not considered
* as possible implementations.
......
......@@ -954,8 +954,7 @@ public class Attr extends JCTree.Visitor {
// Empty bodies are only allowed for
// abstract, native, or interface methods, or for methods
// in a retrofit signature class.
if (isDefaultMethod || ((owner.flags() & INTERFACE) == 0 &&
(tree.mods.flags & (ABSTRACT | NATIVE)) == 0) &&
if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0 &&
!relax)
log.error(tree.pos(), "missing.meth.body.or.decl.abstract");
if (tree.defaultValue != null) {
......@@ -3481,6 +3480,15 @@ public class Attr extends JCTree.Visitor {
env.info.defaultSuperCallSite = null;
}
if (sym.isStatic() && site.isInterface()) {
Assert.check(env.tree.hasTag(APPLY));
JCMethodInvocation app = (JCMethodInvocation)env.tree;
if (app.meth.hasTag(SELECT) &&
!TreeInfo.isStaticSelector(((JCFieldAccess)app.meth).selected, names)) {
log.error(env.tree.pos(), "illegal.static.intf.meth.call", site);
}
}
// Compute the identifier's instantiated type.
// For methods, we need to compute the instance type by
// Resolve.instantiate from the symbol's type as well as
......
......@@ -1058,9 +1058,12 @@ public class Check {
} else
mask = ConstructorFlags;
} else if ((sym.owner.flags_field & INTERFACE) != 0) {
if ((flags & DEFAULT) != 0) {
mask = InterfaceDefaultMethodMask;
implicit = PUBLIC | ABSTRACT;
if ((flags & (DEFAULT | STATIC)) != 0) {
mask = InterfaceMethodMask;
implicit = PUBLIC;
if ((flags & DEFAULT) != 0) {
implicit |= ABSTRACT;
}
} else {
mask = implicit = InterfaceMethodFlags;
}
......@@ -1129,6 +1132,10 @@ public class Check {
ABSTRACT,
PRIVATE | STATIC | DEFAULT))
&&
checkDisjoint(pos, flags,
STATIC,
DEFAULT)
&&
checkDisjoint(pos, flags,
ABSTRACT | INTERFACE,
FINAL | NATIVE | SYNCHRONIZED)
......
......@@ -124,6 +124,7 @@ public class JavacParser implements Parser {
this.allowLambda = source.allowLambda();
this.allowMethodReferences = source.allowMethodReferences();
this.allowDefaultMethods = source.allowDefaultMethods();
this.allowStaticInterfaceMethods = source.allowStaticInterfaceMethods();
this.allowIntersectionTypesInCast = source.allowIntersectionTypesInCast();
this.keepDocComments = keepDocComments;
docComments = newDocCommentTable(keepDocComments, fac);
......@@ -198,6 +199,10 @@ public class JavacParser implements Parser {
*/
boolean allowDefaultMethods;
/** Switch: should we allow static methods in interfaces?
*/
boolean allowStaticInterfaceMethods;
/** Switch: should we allow intersection types in cast?
*/
boolean allowIntersectionTypesInCast;
......@@ -3093,6 +3098,9 @@ public class JavacParser implements Parser {
List<JCTypeParameter> typarams,
boolean isInterface, boolean isVoid,
Comment dc) {
if (isInterface && (mods.flags & Flags.STATIC) != 0) {
checkStaticInterfaceMethods();
}
List<JCVariableDecl> params = formalParameters();
if (!isVoid) type = bracketsOpt(type);
List<JCExpression> thrown = List.nil();
......@@ -3494,6 +3502,12 @@ public class JavacParser implements Parser {
allowIntersectionTypesInCast = true;
}
}
void checkStaticInterfaceMethods() {
if (!allowStaticInterfaceMethods) {
log.error(token.pos, "static.intf.methods.not.supported.in.source", source.name);
allowStaticInterfaceMethods = true;
}
}
/*
* a functional source tree and end position mappings
......
......@@ -948,6 +948,11 @@ compiler.err.types.incompatible.abstract.default=\
compiler.err.default.overrides.object.member=\
default method {0} in {1} {2} overrides a member of java.lang.Object
# 0: type
compiler.err.illegal.static.intf.meth.call=\
illegal static interface method call\n\
the receiver expression should be replaced with the type qualifier ''{0}''
# 0: type, 1: message segment
compiler.err.illegal.default.super.call=\
bad type qualifier {0} in default super call\n\
......@@ -2213,6 +2218,11 @@ 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)
# 0: string
compiler.err.static.intf.methods.not.supported.in.source=\
static interface methods are not supported in -source {0}\n\
(use -source 8 or higher to enable static interface methods)
########################################
# Diagnostics for verbose resolution
# used by Resolve (debug only)
......
/*
* 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 8005166
* @summary Add support for static interface methods
* smoke test for static interface methods
* @compile -XDallowStaticInterfaceMethods Static01.java
*/
public class Static01 {
static int assertionCount = 0;
static void assertTrue(boolean cond) {
assertionCount++;
if (!cond)
throw new AssertionError();
}
interface I {
public static void test() {
assertTrue(true);
}
}
public static void main(String[] args) {
I.test();
assertTrue(assertionCount == 1);
}
}
/*
* 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 8005166
* @summary Add support for static interface methods
* smoke test for static interface methods
* @compile/fail/ref=Static02.out -XDrawDiagnostics -XDallowStaticInterfaceMethods Static02.java
*/
class Static02 {
interface I {
public static void test() { }
}
public static void main(String[] args) {
I.test(); //ok
I i = new I() {};
i.test(); //no!
}
}
Static02.java:40:15: compiler.err.illegal.static.intf.meth.call: Static02.I
1 error
/*
* 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 8005166
* @summary Add support for static interface methods
* Smoke test for static interface method hiding
*/
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 InterfaceMethodHidingTest {
static int checkCount = 0;
enum SignatureKind {
VOID_INTEGER("void m(Integer s)", "return;"),
STRING_INTEGER("String m(Integer s)", "return null;"),
VOID_STRING("void m(String s)", "return;"),
STRING_STRING("String m(String s)", "return null;");
String sigStr;
String retStr;
SignatureKind(String sigStr, String retStr) {
this.sigStr = sigStr;
this.retStr = retStr;
}
boolean overrideEquivalentWith(SignatureKind s2) {
switch (this) {
case VOID_INTEGER:
case STRING_INTEGER:
return s2 == VOID_INTEGER || s2 == STRING_INTEGER;
case VOID_STRING:
case STRING_STRING:
return s2 == VOID_STRING || s2 == STRING_STRING;
default:
throw new AssertionError("bad signature kind");
}
}
}
enum MethodKind {
VIRTUAL("", "#M #S;"),
STATIC("static", "#M #S { #BE; #R }"),
DEFAULT("default", "#M #S { #BE; #R }");
String modStr;
String methTemplate;
MethodKind(String modStr, String methTemplate) {
this.modStr = modStr;
this.methTemplate = methTemplate;
}
boolean inherithed() {
return this != STATIC;
}
static boolean overrides(MethodKind mk1, SignatureKind sk1, MethodKind mk2, SignatureKind sk2) {
return sk1 == sk2 &&
mk2.inherithed() &&
mk1 != STATIC;
}
String getBody(BodyExpr be, SignatureKind sk) {
return methTemplate.replaceAll("#BE", be.bodyExprStr)
.replaceAll("#R", sk.retStr)
.replaceAll("#M", modStr)
.replaceAll("#S", sk.sigStr);
}
}
enum BodyExpr {
NONE(""),
THIS("Object o = this");
String bodyExprStr;
BodyExpr(String bodyExprStr) {
this.bodyExprStr = bodyExprStr;
}
boolean allowed(MethodKind mk) {
return this == NONE ||
mk != MethodKind.STATIC;
}
}
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 (MethodKind mk1 : MethodKind.values()) {
for (SignatureKind sk1 : SignatureKind.values()) {
for (BodyExpr be1 : BodyExpr.values()) {
for (MethodKind mk2 : MethodKind.values()) {
for (SignatureKind sk2 : SignatureKind.values()) {
for (BodyExpr be2 : BodyExpr.values()) {
for (MethodKind mk3 : MethodKind.values()) {
for (SignatureKind sk3 : SignatureKind.values()) {
for (BodyExpr be3 : BodyExpr.values()) {
new InterfaceMethodHidingTest(mk1, mk2, mk3, sk1, sk2, sk3, be1, be2, be3).run(comp, fm);
}
}
}
}
}
}
}
}
}
System.out.println("Total check executed: " + checkCount);
}
MethodKind mk1, mk2, mk3;
SignatureKind sk1, sk2, sk3;
BodyExpr be1, be2, be3;
JavaSource source;
DiagnosticChecker diagChecker;
InterfaceMethodHidingTest(MethodKind mk1, MethodKind mk2, MethodKind mk3,
SignatureKind sk1, SignatureKind sk2, SignatureKind sk3, BodyExpr be1, BodyExpr be2, BodyExpr be3) {
this.mk1 = mk1;
this.mk2 = mk2;
this.mk3 = mk3;
this.sk1 = sk1;
this.sk2 = sk2;
this.sk3 = sk3;
this.be1 = be1;
this.be2 = be2;
this.be3 = be3;
this.source = new JavaSource();
this.diagChecker = new DiagnosticChecker();
}
class JavaSource extends SimpleJavaFileObject {
String template = "interface Sup {\n" +
" default void sup() { }\n" +
"}\n" +
"interface A extends Sup {\n" +
" #M1\n" +
"}\n" +
"interface B extends A, Sup {\n" +
" #M2\n" +
"}\n" +
"interface C extends B, Sup {\n" +
" #M3\n" +
"}\n";
String source;
public JavaSource() {
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
source = template.replaceAll("#M1", mk1.getBody(be1, sk1))
.replaceAll("#M2", mk2.getBody(be2, sk2))
.replaceAll("#M3", mk3.getBody(be3, sk3));
}
@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("-XDallowStaticInterfaceMethods"), null, Arrays.asList(source));
try {
ct.analyze();
} catch (Throwable ex) {
throw new AssertionError("Error thrown when analyzing the following source:\n" + source.getCharContent(true));
}
check();
}
void check() {
boolean errorExpected =
!be1.allowed(mk1) || !be2.allowed(mk2) || !be3.allowed(mk3);
if (mk1.inherithed()) {
errorExpected |=
sk2.overrideEquivalentWith(sk1) && !MethodKind.overrides(mk2, sk2, mk1, sk1) ||
sk3.overrideEquivalentWith(sk1) && !MethodKind.overrides(mk3, sk3, mk1, sk1);
}
if (mk2.inherithed()) {
errorExpected |=
sk3.overrideEquivalentWith(sk2) && !MethodKind.overrides(mk3, sk3, mk2, sk2);
}
checkCount++;
if (diagChecker.errorFound != errorExpected) {
throw new AssertionError("Problem when compiling source:\n" + source.getCharContent(true) +
"\nfound error: " + diagChecker.errorFound);
}
}
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;
}
}
}
}
/*
* 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 8005166
* @summary Add support for static interface methods
* Smoke test for static imports of static interface methods
* @compile -XDallowStaticInterfaceMethods StaticImport1.java
*/
import static pkg.A.*;
class StaticImport1 {
void test() {
m();
}
}
/*
* 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 8005166
* @summary Add support for static interface methods
* Smoke test for static imports of static interface methods
* @compile/fail/ref=StaticImport2.out -XDrawDiagnostics -XDallowStaticInterfaceMethods StaticImport2.java
*/
import static pkg.B.*;
class StaticImport2 {
void test() {
m();
}
}
StaticImport2.java:36:9: compiler.err.cant.resolve.location.args: kindname.method, m, , , (compiler.misc.location: kindname.class, StaticImport2, null)
1 error
/*
* 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 8005166
* @summary Add support for static interface methods
* Smoke test for static imports of static interface methods
* @compile/fail/ref=StaticImport3.out -XDrawDiagnostics -XDallowStaticInterfaceMethods StaticImport3.java
*/
import static pkg.C.*;
class StaticImport3 {
void test() {
m();
}
}
StaticImport3.java:36:9: compiler.err.cant.resolve.location.args: kindname.method, m, , , (compiler.misc.location: kindname.class, StaticImport3, null)
1 error
/*
* 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.
*/
package pkg;
public interface A {
static void m() { }
}
/*
* 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.
*/
package pkg;
public interface B extends A { }
/*
* 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.
*/
package pkg;
public class C implements A { }
......@@ -23,7 +23,7 @@
/*
* @test
* @bug 7192245 8005851
* @bug 7192245 8005851 8005166
* @summary Automatic test for checking set of allowed modifiers on interface methods
*/
......@@ -54,7 +54,7 @@ public class TestDefaultMethodsSyntax {
}
List<String> getOptions() {
return Arrays.asList("-source", versionString);
return Arrays.asList("-XDallowStaticInterfaceMethods", "-source", versionString);
}
}
......@@ -77,32 +77,6 @@ public class TestDefaultMethodsSyntax {
this.modStr = modStr;
}
boolean isAllowed(EnclosingKind ek, ModifierKind otherMod) {
if (this == otherMod) return false;
switch (this) {
case NONE:
return true;
case ABSTRACT:
return otherMod != PRIVATE;
case NATIVE:
return otherMod != ABSTRACT &&
otherMod != STRICTFP;
case FINAL:
case STATIC:
case SYNCHRONIZED:
case STRICTFP:
return otherMod != ABSTRACT;
case PUBLIC:
return true;
case PROTECTED:
return ek == EnclosingKind.ABSTRACT_CLASS;
case DEFAULT:
return otherMod != ABSTRACT;
default:
return true;
}
}
static boolean intersect(ModifierKind mk, ModifierKind... mks) {
for (ModifierKind mk2 : mks) {
if (mk == mk2) return true;
......@@ -113,7 +87,7 @@ public class TestDefaultMethodsSyntax {
static boolean compatible(MethodKind mk, ModifierKind mod1, ModifierKind mod2, EnclosingKind ek) {
if (intersect(ABSTRACT, mod1, mod2) || intersect(NATIVE, mod1, mod2)) {
return mk == MethodKind.NO_BODY;
} else if (intersect(DEFAULT, mod1, mod2)) {
} else if (intersect(DEFAULT, mod1, mod2) || intersect(STATIC, mod1, mod2)) {
return mk == MethodKind.BODY;
} else {
return ek == EnclosingKind.INTERFACE ?
......@@ -123,7 +97,6 @@ public class TestDefaultMethodsSyntax {
boolean compatible(EnclosingKind ek) {
switch (this) {
case STATIC:
case PRIVATE:
case PROTECTED:
return ek != EnclosingKind.INTERFACE;
......@@ -176,16 +149,16 @@ public class TestDefaultMethodsSyntax {
static Result[][] allowedModifierPairs = {
/* NONE PUBLIC PROTECTED PRIVATE ABSTRACT STATIC NATIVE SYNCHRONIZED FINAL STRICTFP DEFAULT */
/* NONE */ { T , T , C , C , T , C , C , C , C , C , I },
/* PUBLIC */ { T , F , F , F , T , C , C , C , C , C , I },
/* NONE */ { T , T , C , C , T , T , C , C , C , C , I },
/* PUBLIC */ { T , F , F , F , T , T , C , C , C , C , I },
/* PROTECTED */ { C , F , F , F , C , C , C , C , C , C , F },
/* PRIVATE */ { C , F , F , F , F , C , C , C , C , C , F },
/* ABSTRACT */ { T , T , C , F , F , F , F , F , F , F , F },
/* STATIC */ { C , C , C , C , F , F , C , C , C , C , F },
/* STATIC */ { T , T , C , C , F , F , C , C , C , T , F },
/* NATIVE */ { C , C , C , C , F , C , F , C , C , F , F },
/* SYNCHRONIZED */ { C , C , C , C , F , C , C , F , C , C , F },
/* FINAL */ { C , C , C , C , F , C , C , C , F , C , F },
/* STRICTFP */ { C , C , C , C , F , C , F , C , C , F , I },
/* STRICTFP */ { C , C , C , C , F , T , F , C , C , F , I },
/* DEFAULT */ { I , I , F , F , F , F , F , F , F , I , F }};
}
......@@ -291,6 +264,9 @@ public class TestDefaultMethodsSyntax {
errorExpected |= ModifierKind.intersect(ModifierKind.DEFAULT, modk1, modk2) &&
vk == VersionKind.PRE_LAMBDA;
errorExpected |= ModifierKind.intersect(ModifierKind.STATIC, modk1, modk2) &&
ek == EnclosingKind.INTERFACE && vk == VersionKind.PRE_LAMBDA;
checkCount++;
if (diagChecker.errorFound != errorExpected) {
throw new AssertionError("Problem when compiling source:\n" + source.getCharContent(true) +
......
/*
* 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.illegal.static.intf.meth.call
// options: -XDallowStaticInterfaceMethods
class IllegalStaticIntfMethCall {
interface A {
static void m() { }
}
void test(A a) {
a.m();
}
}
/*
* 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.static.intf.methods.not.supported.in.source
// options: -source 7 -Xlint:-options -XDallowStaticInterfaceMethods
interface StaticIntfMethodNotSupported {
static void m() { }
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册