8005166: Add support for static interface methods
authormcimadamore
Mon, 21 Jan 2013 20:19:53 +0000
changeset 15377 515846bb6637
parent 15376 32b49791817d
child 15378 a80880d406ee
8005166: Add support for static interface methods Summary: Support public static interface methods Reviewed-by: jjg
langtools/src/share/classes/com/sun/tools/javac/code/Flags.java
langtools/src/share/classes/com/sun/tools/javac/code/Source.java
langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java
langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
langtools/test/tools/javac/defaultMethods/static/Static01.java
langtools/test/tools/javac/defaultMethods/static/Static02.java
langtools/test/tools/javac/defaultMethods/static/Static02.out
langtools/test/tools/javac/defaultMethods/static/hiding/InterfaceMethodHidingTest.java
langtools/test/tools/javac/defaultMethods/static/import/StaticImport1.java
langtools/test/tools/javac/defaultMethods/static/import/StaticImport2.java
langtools/test/tools/javac/defaultMethods/static/import/StaticImport2.out
langtools/test/tools/javac/defaultMethods/static/import/StaticImport3.java
langtools/test/tools/javac/defaultMethods/static/import/StaticImport3.out
langtools/test/tools/javac/defaultMethods/static/import/pkg/A.java
langtools/test/tools/javac/defaultMethods/static/import/pkg/B.java
langtools/test/tools/javac/defaultMethods/static/import/pkg/C.java
langtools/test/tools/javac/defaultMethods/syntax/TestDefaultMethodsSyntax.java
langtools/test/tools/javac/diags/examples/IllegalStaticIntfMethCall.java
langtools/test/tools/javac/diags/examples/StaticIntfMethodNotSupported.java
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java	Mon Jan 21 20:15:16 2013 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java	Mon Jan 21 20:19:53 2013 +0000
@@ -280,7 +280,7 @@
                                 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;
 
 
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java	Mon Jan 21 20:15:16 2013 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java	Mon Jan 21 20:19:53 2013 +0000
@@ -206,6 +206,9 @@
     public boolean allowDefaultMethods() {
         return compareTo(JDK1_8) >= 0;
     }
+    public boolean allowStaticInterfaceMethods() {
+        return compareTo(JDK1_8) >= 0;
+    }
     public boolean allowStrictMethodClashCheck() {
         return compareTo(JDK1_8) >= 0;
     }
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Mon Jan 21 20:15:16 2013 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java	Mon Jan 21 20:19:53 2013 +0000
@@ -1233,7 +1233,8 @@
             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 @@
             }
         }
 
+        @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.
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Jan 21 20:15:16 2013 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Jan 21 20:19:53 2013 +0000
@@ -954,8 +954,7 @@
                 // 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 @@
             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
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Jan 21 20:15:16 2013 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Mon Jan 21 20:19:53 2013 +0000
@@ -1058,9 +1058,12 @@
                 } 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;
                 }
@@ -1130,6 +1133,10 @@
                                 PRIVATE | STATIC | DEFAULT))
                  &&
                  checkDisjoint(pos, flags,
+                                STATIC,
+                                DEFAULT)
+                 &&
+                 checkDisjoint(pos, flags,
                                ABSTRACT | INTERFACE,
                                FINAL | NATIVE | SYNCHRONIZED)
                  &&
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Mon Jan 21 20:15:16 2013 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Mon Jan 21 20:19:53 2013 +0000
@@ -124,6 +124,7 @@
         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 @@
      */
     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 @@
                               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 @@
             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/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Jan 21 20:15:16 2013 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Mon Jan 21 20:19:53 2013 +0000
@@ -948,6 +948,11 @@
 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 @@
     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)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/Static01.java	Mon Jan 21 20:19:53 2013 +0000
@@ -0,0 +1,51 @@
+/*
+ * 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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/Static02.java	Mon Jan 21 20:19:53 2013 +0000
@@ -0,0 +1,42 @@
+/*
+ * 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!
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/Static02.out	Mon Jan 21 20:19:53 2013 +0000
@@ -0,0 +1,2 @@
+Static02.java:40:15: compiler.err.illegal.static.intf.meth.call: Static02.I
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/hiding/InterfaceMethodHidingTest.java	Mon Jan 21 20:19:53 2013 +0000
@@ -0,0 +1,243 @@
+/*
+ * 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;
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/import/StaticImport1.java	Mon Jan 21 20:19:53 2013 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/import/StaticImport2.java	Mon Jan 21 20:19:53 2013 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/import/StaticImport2.out	Mon Jan 21 20:19:53 2013 +0000
@@ -0,0 +1,2 @@
+StaticImport2.java:36:9: compiler.err.cant.resolve.location.args: kindname.method, m, , , (compiler.misc.location: kindname.class, StaticImport2, null)
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/import/StaticImport3.java	Mon Jan 21 20:19:53 2013 +0000
@@ -0,0 +1,38 @@
+/*
+ * 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();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/import/StaticImport3.out	Mon Jan 21 20:19:53 2013 +0000
@@ -0,0 +1,2 @@
+StaticImport3.java:36:9: compiler.err.cant.resolve.location.args: kindname.method, m, , , (compiler.misc.location: kindname.class, StaticImport3, null)
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/import/pkg/A.java	Mon Jan 21 20:19:53 2013 +0000
@@ -0,0 +1,28 @@
+/*
+ * 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() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/import/pkg/B.java	Mon Jan 21 20:19:53 2013 +0000
@@ -0,0 +1,26 @@
+/*
+ * 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 { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/static/import/pkg/C.java	Mon Jan 21 20:19:53 2013 +0000
@@ -0,0 +1,26 @@
+/*
+ * 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 { }
--- a/langtools/test/tools/javac/defaultMethods/syntax/TestDefaultMethodsSyntax.java	Mon Jan 21 20:15:16 2013 +0000
+++ b/langtools/test/tools/javac/defaultMethods/syntax/TestDefaultMethodsSyntax.java	Mon Jan 21 20:19:53 2013 +0000
@@ -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 @@
         }
 
         List<String> getOptions() {
-            return Arrays.asList("-source", versionString);
+            return Arrays.asList("-XDallowStaticInterfaceMethods", "-source", versionString);
         }
     }
 
@@ -77,32 +77,6 @@
             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 @@
         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 @@
 
         boolean compatible(EnclosingKind ek) {
             switch (this) {
-                case STATIC:
                 case PRIVATE:
                 case PROTECTED:
                     return ek != EnclosingKind.INTERFACE;
@@ -176,16 +149,16 @@
 
         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 @@
         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) +
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/IllegalStaticIntfMethCall.java	Mon Jan 21 20:19:53 2013 +0000
@@ -0,0 +1,34 @@
+/*
+ * 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();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/StaticIntfMethodNotSupported.java	Mon Jan 21 20:19:53 2013 +0000
@@ -0,0 +1,29 @@
+/*
+ * 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() { }
+}