提交 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 { ...@@ -280,7 +280,7 @@ public class Flags {
SYNCHRONIZED | FINAL | STRICTFP; SYNCHRONIZED | FINAL | STRICTFP;
public static final long public static final long
ExtendedStandardFlags = (long)StandardFlags | DEFAULT, ExtendedStandardFlags = (long)StandardFlags | DEFAULT,
InterfaceDefaultMethodMask = ABSTRACT | PUBLIC | STRICTFP | DEFAULT, InterfaceMethodMask = ABSTRACT | STATIC | PUBLIC | STRICTFP | DEFAULT,
LocalVarFlags = FINAL | PARAMETER; LocalVarFlags = FINAL | PARAMETER;
......
...@@ -206,6 +206,9 @@ public enum Source { ...@@ -206,6 +206,9 @@ public enum Source {
public boolean allowDefaultMethods() { public boolean allowDefaultMethods() {
return compareTo(JDK1_8) >= 0; return compareTo(JDK1_8) >= 0;
} }
public boolean allowStaticInterfaceMethods() {
return compareTo(JDK1_8) >= 0;
}
public boolean allowStrictMethodClashCheck() { public boolean allowStrictMethodClashCheck() {
return compareTo(JDK1_8) >= 0; return compareTo(JDK1_8) >= 0;
} }
......
...@@ -1233,7 +1233,8 @@ public abstract class Symbol implements Element { ...@@ -1233,7 +1233,8 @@ public abstract class Symbol implements Element {
case Flags.PRIVATE: case Flags.PRIVATE:
return false; return false;
case Flags.PUBLIC: case Flags.PUBLIC:
return true; return !this.owner.isInterface() ||
(flags_field & STATIC) == 0;
case Flags.PROTECTED: case Flags.PROTECTED:
return (origin.flags() & INTERFACE) == 0; return (origin.flags() & INTERFACE) == 0;
case 0: case 0:
...@@ -1247,6 +1248,18 @@ public abstract class Symbol implements Element { ...@@ -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; /** The implementation of this (abstract) symbol in class origin;
* null if none exists. Synthetic methods are not considered * null if none exists. Synthetic methods are not considered
* as possible implementations. * as possible implementations.
......
...@@ -954,8 +954,7 @@ public class Attr extends JCTree.Visitor { ...@@ -954,8 +954,7 @@ public class Attr extends JCTree.Visitor {
// Empty bodies are only allowed for // Empty bodies are only allowed for
// abstract, native, or interface methods, or for methods // abstract, native, or interface methods, or for methods
// in a retrofit signature class. // in a retrofit signature class.
if (isDefaultMethod || ((owner.flags() & INTERFACE) == 0 && if (isDefaultMethod || (tree.sym.flags() & (ABSTRACT | NATIVE)) == 0 &&
(tree.mods.flags & (ABSTRACT | NATIVE)) == 0) &&
!relax) !relax)
log.error(tree.pos(), "missing.meth.body.or.decl.abstract"); log.error(tree.pos(), "missing.meth.body.or.decl.abstract");
if (tree.defaultValue != null) { if (tree.defaultValue != null) {
...@@ -3481,6 +3480,15 @@ public class Attr extends JCTree.Visitor { ...@@ -3481,6 +3480,15 @@ public class Attr extends JCTree.Visitor {
env.info.defaultSuperCallSite = null; 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. // Compute the identifier's instantiated type.
// For methods, we need to compute the instance type by // For methods, we need to compute the instance type by
// Resolve.instantiate from the symbol's type as well as // Resolve.instantiate from the symbol's type as well as
......
...@@ -1058,9 +1058,12 @@ public class Check { ...@@ -1058,9 +1058,12 @@ public class Check {
} else } else
mask = ConstructorFlags; mask = ConstructorFlags;
} else if ((sym.owner.flags_field & INTERFACE) != 0) { } else if ((sym.owner.flags_field & INTERFACE) != 0) {
if ((flags & DEFAULT) != 0) { if ((flags & (DEFAULT | STATIC)) != 0) {
mask = InterfaceDefaultMethodMask; mask = InterfaceMethodMask;
implicit = PUBLIC | ABSTRACT; implicit = PUBLIC;
if ((flags & DEFAULT) != 0) {
implicit |= ABSTRACT;
}
} else { } else {
mask = implicit = InterfaceMethodFlags; mask = implicit = InterfaceMethodFlags;
} }
...@@ -1129,6 +1132,10 @@ public class Check { ...@@ -1129,6 +1132,10 @@ public class Check {
ABSTRACT, ABSTRACT,
PRIVATE | STATIC | DEFAULT)) PRIVATE | STATIC | DEFAULT))
&& &&
checkDisjoint(pos, flags,
STATIC,
DEFAULT)
&&
checkDisjoint(pos, flags, checkDisjoint(pos, flags,
ABSTRACT | INTERFACE, ABSTRACT | INTERFACE,
FINAL | NATIVE | SYNCHRONIZED) FINAL | NATIVE | SYNCHRONIZED)
......
...@@ -124,6 +124,7 @@ public class JavacParser implements Parser { ...@@ -124,6 +124,7 @@ public class JavacParser implements Parser {
this.allowLambda = source.allowLambda(); this.allowLambda = source.allowLambda();
this.allowMethodReferences = source.allowMethodReferences(); this.allowMethodReferences = source.allowMethodReferences();
this.allowDefaultMethods = source.allowDefaultMethods(); this.allowDefaultMethods = source.allowDefaultMethods();
this.allowStaticInterfaceMethods = source.allowStaticInterfaceMethods();
this.allowIntersectionTypesInCast = source.allowIntersectionTypesInCast(); this.allowIntersectionTypesInCast = source.allowIntersectionTypesInCast();
this.keepDocComments = keepDocComments; this.keepDocComments = keepDocComments;
docComments = newDocCommentTable(keepDocComments, fac); docComments = newDocCommentTable(keepDocComments, fac);
...@@ -198,6 +199,10 @@ public class JavacParser implements Parser { ...@@ -198,6 +199,10 @@ public class JavacParser implements Parser {
*/ */
boolean allowDefaultMethods; boolean allowDefaultMethods;
/** Switch: should we allow static methods in interfaces?
*/
boolean allowStaticInterfaceMethods;
/** Switch: should we allow intersection types in cast? /** Switch: should we allow intersection types in cast?
*/ */
boolean allowIntersectionTypesInCast; boolean allowIntersectionTypesInCast;
...@@ -3093,6 +3098,9 @@ public class JavacParser implements Parser { ...@@ -3093,6 +3098,9 @@ public class JavacParser implements Parser {
List<JCTypeParameter> typarams, List<JCTypeParameter> typarams,
boolean isInterface, boolean isVoid, boolean isInterface, boolean isVoid,
Comment dc) { Comment dc) {
if (isInterface && (mods.flags & Flags.STATIC) != 0) {
checkStaticInterfaceMethods();
}
List<JCVariableDecl> params = formalParameters(); List<JCVariableDecl> params = formalParameters();
if (!isVoid) type = bracketsOpt(type); if (!isVoid) type = bracketsOpt(type);
List<JCExpression> thrown = List.nil(); List<JCExpression> thrown = List.nil();
...@@ -3494,6 +3502,12 @@ public class JavacParser implements Parser { ...@@ -3494,6 +3502,12 @@ public class JavacParser implements Parser {
allowIntersectionTypesInCast = true; 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 * a functional source tree and end position mappings
......
...@@ -948,6 +948,11 @@ compiler.err.types.incompatible.abstract.default=\ ...@@ -948,6 +948,11 @@ compiler.err.types.incompatible.abstract.default=\
compiler.err.default.overrides.object.member=\ compiler.err.default.overrides.object.member=\
default method {0} in {1} {2} overrides a member of java.lang.Object 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 # 0: type, 1: message segment
compiler.err.illegal.default.super.call=\ compiler.err.illegal.default.super.call=\
bad type qualifier {0} in default super call\n\ bad type qualifier {0} in default super call\n\
...@@ -2213,6 +2218,11 @@ compiler.err.intersection.types.in.cast.not.supported.in.source=\ ...@@ -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\ intersection types in cast are not supported in -source {0}\n\
(use -source 8 or higher to enable default methods) (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 # Diagnostics for verbose resolution
# used by Resolve (debug only) # 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 @@ ...@@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 7192245 8005851 * @bug 7192245 8005851 8005166
* @summary Automatic test for checking set of allowed modifiers on interface methods * @summary Automatic test for checking set of allowed modifiers on interface methods
*/ */
...@@ -54,7 +54,7 @@ public class TestDefaultMethodsSyntax { ...@@ -54,7 +54,7 @@ public class TestDefaultMethodsSyntax {
} }
List<String> getOptions() { List<String> getOptions() {
return Arrays.asList("-source", versionString); return Arrays.asList("-XDallowStaticInterfaceMethods", "-source", versionString);
} }
} }
...@@ -77,32 +77,6 @@ public class TestDefaultMethodsSyntax { ...@@ -77,32 +77,6 @@ public class TestDefaultMethodsSyntax {
this.modStr = modStr; 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) { static boolean intersect(ModifierKind mk, ModifierKind... mks) {
for (ModifierKind mk2 : mks) { for (ModifierKind mk2 : mks) {
if (mk == mk2) return true; if (mk == mk2) return true;
...@@ -113,7 +87,7 @@ public class TestDefaultMethodsSyntax { ...@@ -113,7 +87,7 @@ public class TestDefaultMethodsSyntax {
static boolean compatible(MethodKind mk, ModifierKind mod1, ModifierKind mod2, EnclosingKind ek) { static boolean compatible(MethodKind mk, ModifierKind mod1, ModifierKind mod2, EnclosingKind ek) {
if (intersect(ABSTRACT, mod1, mod2) || intersect(NATIVE, mod1, mod2)) { if (intersect(ABSTRACT, mod1, mod2) || intersect(NATIVE, mod1, mod2)) {
return mk == MethodKind.NO_BODY; 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; return mk == MethodKind.BODY;
} else { } else {
return ek == EnclosingKind.INTERFACE ? return ek == EnclosingKind.INTERFACE ?
...@@ -123,7 +97,6 @@ public class TestDefaultMethodsSyntax { ...@@ -123,7 +97,6 @@ public class TestDefaultMethodsSyntax {
boolean compatible(EnclosingKind ek) { boolean compatible(EnclosingKind ek) {
switch (this) { switch (this) {
case STATIC:
case PRIVATE: case PRIVATE:
case PROTECTED: case PROTECTED:
return ek != EnclosingKind.INTERFACE; return ek != EnclosingKind.INTERFACE;
...@@ -176,16 +149,16 @@ public class TestDefaultMethodsSyntax { ...@@ -176,16 +149,16 @@ public class TestDefaultMethodsSyntax {
static Result[][] allowedModifierPairs = { static Result[][] allowedModifierPairs = {
/* NONE PUBLIC PROTECTED PRIVATE ABSTRACT STATIC NATIVE SYNCHRONIZED FINAL STRICTFP DEFAULT */ /* NONE PUBLIC PROTECTED PRIVATE ABSTRACT STATIC NATIVE SYNCHRONIZED FINAL STRICTFP DEFAULT */
/* NONE */ { T , T , C , C , 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 , C , 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 }, /* PROTECTED */ { C , F , F , F , C , C , C , C , C , C , F },
/* PRIVATE */ { C , F , F , F , F , 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 }, /* 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 }, /* NATIVE */ { C , C , C , C , F , C , F , C , C , F , F },
/* SYNCHRONIZED */ { C , C , C , C , F , C , C , F , C , C , 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 }, /* 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 }}; /* DEFAULT */ { I , I , F , F , F , F , F , F , F , I , F }};
} }
...@@ -291,6 +264,9 @@ public class TestDefaultMethodsSyntax { ...@@ -291,6 +264,9 @@ public class TestDefaultMethodsSyntax {
errorExpected |= ModifierKind.intersect(ModifierKind.DEFAULT, modk1, modk2) && errorExpected |= ModifierKind.intersect(ModifierKind.DEFAULT, modk1, modk2) &&
vk == VersionKind.PRE_LAMBDA; vk == VersionKind.PRE_LAMBDA;
errorExpected |= ModifierKind.intersect(ModifierKind.STATIC, modk1, modk2) &&
ek == EnclosingKind.INTERFACE && vk == VersionKind.PRE_LAMBDA;
checkCount++; checkCount++;
if (diagChecker.errorFound != errorExpected) { if (diagChecker.errorFound != errorExpected) {
throw new AssertionError("Problem when compiling source:\n" + source.getCharContent(true) + 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.
先完成此消息的编辑!
想要评论请 注册