mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 11:04:34 +02:00
8025087: Annotation processing api returns default modifier for interface static method
ClassReader must not set Flags.DEFAULT for interface static methods Reviewed-by: vromero, jjg
This commit is contained in:
parent
7de3ec870d
commit
5ec0ba7c47
10 changed files with 365 additions and 24 deletions
|
@ -360,7 +360,7 @@
|
||||||
datafile="${build.coverage.dir}/cobertura.ser"/>
|
datafile="${build.coverage.dir}/cobertura.ser"/>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="diags-examples" depends="build-javac">
|
<target name="diags-examples" depends="build-javac,build-javap">
|
||||||
<!-- can override the following on the command line if desired. -->
|
<!-- can override the following on the command line if desired. -->
|
||||||
<property name="diags.examples.out" location="${build.dir}/diag-examples/diags-examples.html"/>
|
<property name="diags.examples.out" location="${build.dir}/diag-examples/diags-examples.html"/>
|
||||||
<mkdir dir="${build.dir}/diag-examples/classes"/>
|
<mkdir dir="${build.dir}/diag-examples/classes"/>
|
||||||
|
@ -370,7 +370,7 @@
|
||||||
destdir="${build.dir}/diag-examples/classes"
|
destdir="${build.dir}/diag-examples/classes"
|
||||||
includes="ArgTypeCompilerFactory.java,Example.java,FileManager.java,HTMLWriter.java,RunExamples.java,DocCommentProcessor.java"
|
includes="ArgTypeCompilerFactory.java,Example.java,FileManager.java,HTMLWriter.java,RunExamples.java,DocCommentProcessor.java"
|
||||||
sourcepath=""
|
sourcepath=""
|
||||||
classpath="${dist.lib.dir}/javac.jar"
|
classpath="${dist.lib.dir}/javac.jar;${dist.lib.dir}/javap.jar"
|
||||||
includeAntRuntime="no"
|
includeAntRuntime="no"
|
||||||
debug="${javac.debug}"
|
debug="${javac.debug}"
|
||||||
debuglevel="${javac.debuglevel}">
|
debuglevel="${javac.debuglevel}">
|
||||||
|
@ -379,7 +379,7 @@
|
||||||
<java fork="true"
|
<java fork="true"
|
||||||
jvm="${target.java.home}/bin/java"
|
jvm="${target.java.home}/bin/java"
|
||||||
dir="test/tools/javac/diags"
|
dir="test/tools/javac/diags"
|
||||||
classpath="${build.dir}/diag-examples/classes;${dist.lib.dir}/javac.jar"
|
classpath="${build.dir}/diag-examples/classes;${dist.lib.dir}/javac.jar;${dist.lib.dir}/javap.jar"
|
||||||
classname="RunExamples">
|
classname="RunExamples">
|
||||||
<jvmarg value="-Dtest.classes=${build.dir}/diag-examples/classes"/>
|
<jvmarg value="-Dtest.classes=${build.dir}/diag-examples/classes"/>
|
||||||
<arg value="-examples"/>
|
<arg value="-examples"/>
|
||||||
|
|
|
@ -1993,11 +1993,15 @@ public class ClassReader {
|
||||||
(flags & ABSTRACT) == 0 && !name.equals(names.clinit)) {
|
(flags & ABSTRACT) == 0 && !name.equals(names.clinit)) {
|
||||||
if (majorVersion > Target.JDK1_8.majorVersion ||
|
if (majorVersion > Target.JDK1_8.majorVersion ||
|
||||||
(majorVersion == Target.JDK1_8.majorVersion && minorVersion >= Target.JDK1_8.minorVersion)) {
|
(majorVersion == Target.JDK1_8.majorVersion && minorVersion >= Target.JDK1_8.minorVersion)) {
|
||||||
currentOwner.flags_field |= DEFAULT;
|
if ((flags & STATIC) == 0) {
|
||||||
flags |= DEFAULT | ABSTRACT;
|
currentOwner.flags_field |= DEFAULT;
|
||||||
|
flags |= DEFAULT | ABSTRACT;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
//protect against ill-formed classfiles
|
//protect against ill-formed classfiles
|
||||||
throw new CompletionFailure(currentOwner, "default method found in pre JDK 8 classfile");
|
throw badClassFile((flags & STATIC) == 0 ? "invalid.default.interface" : "invalid.static.interface",
|
||||||
|
Integer.toString(majorVersion),
|
||||||
|
Integer.toString(minorVersion));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (name == names.init && currentOwner.hasOuterInstance()) {
|
if (name == names.init && currentOwner.hasOuterInstance()) {
|
||||||
|
|
|
@ -1699,6 +1699,7 @@ compiler.err.cant.access=\
|
||||||
cannot access {0}\n\
|
cannot access {0}\n\
|
||||||
{1}
|
{1}
|
||||||
|
|
||||||
|
# 0: file name, 1: message segment
|
||||||
compiler.misc.bad.class.file.header=\
|
compiler.misc.bad.class.file.header=\
|
||||||
bad class file: {0}\n\
|
bad class file: {0}\n\
|
||||||
{1}\n\
|
{1}\n\
|
||||||
|
@ -1744,6 +1745,14 @@ compiler.misc.class.file.wrong.class=\
|
||||||
compiler.misc.class.file.not.found=\
|
compiler.misc.class.file.not.found=\
|
||||||
class file for {0} not found
|
class file for {0} not found
|
||||||
|
|
||||||
|
# 0: classfile major version, 1: classfile minor version
|
||||||
|
compiler.misc.invalid.default.interface=\
|
||||||
|
default method found in version {0}.{1} classfile
|
||||||
|
|
||||||
|
# 0: classfile major version, 1: classfile minor version
|
||||||
|
compiler.misc.invalid.static.interface=\
|
||||||
|
static method found in version {0}.{1} classfile
|
||||||
|
|
||||||
# 0: name
|
# 0: name
|
||||||
compiler.misc.file.doesnt.contain.class=\
|
compiler.misc.file.doesnt.contain.class=\
|
||||||
file does not contain class {0}
|
file does not contain class {0}
|
||||||
|
|
89
langtools/test/tools/javac/defaultMethods/BadClassfile.java
Normal file
89
langtools/test/tools/javac/defaultMethods/BadClassfile.java
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8025087
|
||||||
|
* @summary Verify that pre-JDK8 classfiles with default and/or static methods
|
||||||
|
* are refused correctly.
|
||||||
|
* @build BadClassfile
|
||||||
|
* @run main BadClassfile
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.sun.tools.classfile.*;
|
||||||
|
import com.sun.tools.javac.api.JavacTaskImpl;
|
||||||
|
import com.sun.tools.javac.code.Symbol;
|
||||||
|
import com.sun.tools.javac.jvm.ClassReader.BadClassFile;
|
||||||
|
import com.sun.tools.javac.jvm.Target;
|
||||||
|
import com.sun.tools.javac.util.Assert;
|
||||||
|
import com.sun.tools.javac.util.JCDiagnostic;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
|
import javax.tools.JavaCompiler;
|
||||||
|
import javax.tools.ToolProvider;
|
||||||
|
|
||||||
|
public class BadClassfile {
|
||||||
|
public static void main(String... args) throws Exception {
|
||||||
|
test("BadClassfile$DefaultMethodTest", "compiler.misc.invalid.default.interface");
|
||||||
|
test("BadClassfile$StaticMethodTest", "compiler.misc.invalid.static.interface");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void test(String classname, String expected) throws Exception {
|
||||||
|
File classfile = new File(System.getProperty("test.classes", "."), classname + ".class");
|
||||||
|
ClassFile cf = ClassFile.read(classfile);
|
||||||
|
|
||||||
|
cf = new ClassFile(cf.magic, Target.JDK1_7.minorVersion,
|
||||||
|
Target.JDK1_7.majorVersion, cf.constant_pool, cf.access_flags,
|
||||||
|
cf.this_class, cf.super_class, cf.interfaces, cf.fields,
|
||||||
|
cf.methods, cf.attributes);
|
||||||
|
|
||||||
|
new ClassWriter().write(cf, classfile);
|
||||||
|
|
||||||
|
JavaCompiler c = ToolProvider.getSystemJavaCompiler();
|
||||||
|
JavacTaskImpl task = (JavacTaskImpl) c.getTask(null, null, null, Arrays.asList("-classpath", System.getProperty("test.classes", ".")), null, null);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Symbol clazz = com.sun.tools.javac.main.JavaCompiler.instance(task.getContext()).resolveIdent(classname);
|
||||||
|
|
||||||
|
clazz.complete();
|
||||||
|
} catch (BadClassFile f) {
|
||||||
|
JCDiagnostic embeddedDiag = (JCDiagnostic) f.diag.getArgs()[1];
|
||||||
|
assertEquals(expected, embeddedDiag.getCode());
|
||||||
|
assertEquals(Integer.toString(Target.JDK1_7.majorVersion), embeddedDiag.getArgs()[0]);
|
||||||
|
assertEquals(Integer.toString(Target.JDK1_7.minorVersion), embeddedDiag.getArgs()[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertEquals(Object expected, Object actual) {
|
||||||
|
Assert.check(Objects.equals(expected, actual),
|
||||||
|
"expected: " + expected + ", but was: " + actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DefaultMethodTest {
|
||||||
|
default void test() { }
|
||||||
|
}
|
||||||
|
interface StaticMethodTest {
|
||||||
|
static void test() { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,7 +40,6 @@ compiler.err.type.var.more.than.once # UNUSED
|
||||||
compiler.err.type.var.more.than.once.in.result # UNUSED
|
compiler.err.type.var.more.than.once.in.result # UNUSED
|
||||||
compiler.err.unexpected.type
|
compiler.err.unexpected.type
|
||||||
compiler.err.unsupported.cross.fp.lit # Scanner: host system dependent
|
compiler.err.unsupported.cross.fp.lit # Scanner: host system dependent
|
||||||
compiler.misc.bad.class.file.header # bad class file
|
|
||||||
compiler.misc.bad.class.signature # bad class file
|
compiler.misc.bad.class.signature # bad class file
|
||||||
compiler.misc.bad.const.pool.tag # bad class file
|
compiler.misc.bad.const.pool.tag # bad class file
|
||||||
compiler.misc.bad.const.pool.tag.at # bad class file
|
compiler.misc.bad.const.pool.tag.at # bad class file
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// key: compiler.misc.invalid.default.interface
|
||||||
|
// key: compiler.misc.bad.class.file.header
|
||||||
|
// key: compiler.err.cant.access
|
||||||
|
// options: -processor CreateBadClassFile
|
||||||
|
|
||||||
|
/* The annotation processor will create an invalid classfile with version 51.0
|
||||||
|
* and a non-abstract method in an interface. Loading the classfile will produce
|
||||||
|
* the diagnostic.
|
||||||
|
*/
|
||||||
|
class InvalidDefaultInterface { }
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.sun.tools.classfile.*;
|
||||||
|
import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
|
||||||
|
import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info;
|
||||||
|
import com.sun.tools.classfile.ConstantPool.CPInfo;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.annotation.processing.*;
|
||||||
|
import javax.lang.model.*;
|
||||||
|
import javax.lang.model.element.*;
|
||||||
|
import javax.tools.*;
|
||||||
|
|
||||||
|
/* Create an invalid classfile with version 51.0 and a non-abstract method in an interface.*/
|
||||||
|
@SupportedAnnotationTypes("*")
|
||||||
|
public class CreateBadClassFile extends AbstractProcessor {
|
||||||
|
public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv) {
|
||||||
|
if (++round == 1) {
|
||||||
|
ConstantPool cp = new ConstantPool(new CPInfo[] {
|
||||||
|
new CONSTANT_Utf8_info(""), //0
|
||||||
|
new CONSTANT_Utf8_info("Test"), //1
|
||||||
|
new CONSTANT_Class_info(null, 1), //2
|
||||||
|
new CONSTANT_Utf8_info("java/lang/Object"), //3
|
||||||
|
new CONSTANT_Class_info(null, 3), //4
|
||||||
|
new CONSTANT_Utf8_info("test"), //5
|
||||||
|
new CONSTANT_Utf8_info("()V"), //6
|
||||||
|
});
|
||||||
|
ClassFile cf = new ClassFile(0xCAFEBABE,
|
||||||
|
0,
|
||||||
|
51,
|
||||||
|
cp,
|
||||||
|
new AccessFlags(AccessFlags.ACC_ABSTRACT |
|
||||||
|
AccessFlags.ACC_INTERFACE |
|
||||||
|
AccessFlags.ACC_PUBLIC),
|
||||||
|
2,
|
||||||
|
4,
|
||||||
|
new int[0],
|
||||||
|
new Field[0],
|
||||||
|
new Method[] {
|
||||||
|
//creating non-abstract method in 51.0 classfile:
|
||||||
|
new Method(new AccessFlags(AccessFlags.ACC_PUBLIC),
|
||||||
|
5,
|
||||||
|
new Descriptor(6),
|
||||||
|
new Attributes(cp, new Attribute[0]))
|
||||||
|
},
|
||||||
|
new Attributes(cp, new Attribute[0]));
|
||||||
|
try {
|
||||||
|
JavaFileObject clazz = processingEnv.getFiler().createClassFile("Test");
|
||||||
|
try (OutputStream out = clazz.openOutputStream()) {
|
||||||
|
new ClassWriter().write(cf, out);
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SourceVersion getSupportedSourceVersion() {
|
||||||
|
return SourceVersion.latest();
|
||||||
|
}
|
||||||
|
|
||||||
|
int round = 0;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// key: compiler.misc.invalid.static.interface
|
||||||
|
// key: compiler.misc.bad.class.file.header
|
||||||
|
// key: compiler.err.cant.access
|
||||||
|
// options: -processor CreateBadClassFile
|
||||||
|
|
||||||
|
/* The annotation processor will create an invalid classfile with version 51.0
|
||||||
|
* and a static method in an interface. Loading the classfile will produce
|
||||||
|
* the diagnostic.
|
||||||
|
*/
|
||||||
|
class InvalidDefaultInterface { }
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.sun.tools.classfile.*;
|
||||||
|
import com.sun.tools.classfile.ConstantPool.CONSTANT_Class_info;
|
||||||
|
import com.sun.tools.classfile.ConstantPool.CONSTANT_Utf8_info;
|
||||||
|
import com.sun.tools.classfile.ConstantPool.CPInfo;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.annotation.processing.*;
|
||||||
|
import javax.lang.model.*;
|
||||||
|
import javax.lang.model.element.*;
|
||||||
|
import javax.tools.*;
|
||||||
|
|
||||||
|
/* Create an invalid classfile with version 51.0 and a static method in an interface.*/
|
||||||
|
@SupportedAnnotationTypes("*")
|
||||||
|
public class CreateBadClassFile extends AbstractProcessor {
|
||||||
|
public boolean process(Set<? extends TypeElement> elems, RoundEnvironment renv) {
|
||||||
|
if (++round == 1) {
|
||||||
|
ConstantPool cp = new ConstantPool(new CPInfo[] {
|
||||||
|
new CONSTANT_Utf8_info(""), //0
|
||||||
|
new CONSTANT_Utf8_info("Test"), //1
|
||||||
|
new CONSTANT_Class_info(null, 1), //2
|
||||||
|
new CONSTANT_Utf8_info("java/lang/Object"), //3
|
||||||
|
new CONSTANT_Class_info(null, 3), //4
|
||||||
|
new CONSTANT_Utf8_info("test"), //5
|
||||||
|
new CONSTANT_Utf8_info("()V"), //6
|
||||||
|
});
|
||||||
|
ClassFile cf = new ClassFile(0xCAFEBABE,
|
||||||
|
0,
|
||||||
|
51,
|
||||||
|
cp,
|
||||||
|
new AccessFlags(AccessFlags.ACC_ABSTRACT |
|
||||||
|
AccessFlags.ACC_INTERFACE |
|
||||||
|
AccessFlags.ACC_PUBLIC),
|
||||||
|
2,
|
||||||
|
4,
|
||||||
|
new int[0],
|
||||||
|
new Field[0],
|
||||||
|
new Method[] {
|
||||||
|
//creating static method in 51.0 classfile:
|
||||||
|
new Method(new AccessFlags(AccessFlags.ACC_PUBLIC |
|
||||||
|
AccessFlags.ACC_STATIC),
|
||||||
|
5,
|
||||||
|
new Descriptor(6),
|
||||||
|
new Attributes(cp, new Attribute[0]))
|
||||||
|
},
|
||||||
|
new Attributes(cp, new Attribute[0]));
|
||||||
|
try {
|
||||||
|
JavaFileObject clazz = processingEnv.getFiler().createClassFile("Test");
|
||||||
|
try (OutputStream out = clazz.openOutputStream()) {
|
||||||
|
new ClassWriter().write(cf, out);
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SourceVersion getSupportedSourceVersion() {
|
||||||
|
return SourceVersion.latest();
|
||||||
|
}
|
||||||
|
|
||||||
|
int round = 0;
|
||||||
|
}
|
|
@ -23,54 +23,57 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 8005046 8011052
|
* @bug 8005046 8011052 8025087
|
||||||
* @summary Test basic properties of javax.lang.element.Element
|
* @summary Test basic properties of javax.lang.element.ExecutableElement
|
||||||
* @author Joseph D. Darcy
|
* @author Joseph D. Darcy
|
||||||
* @library /tools/javac/lib
|
* @library /tools/javac/lib
|
||||||
* @build JavacTestingAbstractProcessor TestExecutableElement
|
* @build JavacTestingAbstractProcessor TestExecutableElement
|
||||||
* @compile -processor TestExecutableElement -proc:only TestExecutableElement.java
|
* @compile -processor TestExecutableElement -proc:only -AexpectedMethodCount=7 TestExecutableElement.java
|
||||||
|
* @compile/process -processor TestExecutableElement -proc:only -AexpectedMethodCount=3 ProviderOfDefault
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
import java.util.Formatter;
|
import java.util.Formatter;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.regex.*;
|
import java.util.regex.*;
|
||||||
import javax.annotation.processing.*;
|
import javax.annotation.processing.*;
|
||||||
import javax.lang.model.SourceVersion;
|
|
||||||
import static javax.lang.model.SourceVersion.*;
|
|
||||||
import javax.lang.model.element.*;
|
import javax.lang.model.element.*;
|
||||||
import javax.lang.model.util.*;
|
|
||||||
import static javax.lang.model.util.ElementFilter.*;
|
import static javax.lang.model.util.ElementFilter.*;
|
||||||
import static javax.tools.Diagnostic.Kind.*;
|
import static javax.tools.Diagnostic.Kind.*;
|
||||||
import static javax.tools.StandardLocation.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test some basic workings of javax.lang.element.ExecutableElement
|
* Test some basic workings of javax.lang.element.ExecutableElement
|
||||||
*/
|
*/
|
||||||
|
@SupportedOptions("expectedMethodCount")
|
||||||
public class TestExecutableElement extends JavacTestingAbstractProcessor implements ProviderOfDefault {
|
public class TestExecutableElement extends JavacTestingAbstractProcessor implements ProviderOfDefault {
|
||||||
|
private int seenMethods = 0;
|
||||||
@IsDefault(false)
|
@IsDefault(false)
|
||||||
public boolean process(Set<? extends TypeElement> annotations,
|
public boolean process(Set<? extends TypeElement> annotations,
|
||||||
RoundEnvironment roundEnv) {
|
RoundEnvironment roundEnv) {
|
||||||
int errors = 0;
|
|
||||||
if (!roundEnv.processingOver()) {
|
if (!roundEnv.processingOver()) {
|
||||||
boolean hasRun = false;
|
|
||||||
for (Element element : roundEnv.getRootElements()) {
|
for (Element element : roundEnv.getRootElements()) {
|
||||||
for (ExecutableElement method : methodsIn(element.getEnclosedElements())) {
|
for (ExecutableElement method : methodsIn(element.getEnclosedElements())) {
|
||||||
hasRun = true;
|
checkIsDefault(method);
|
||||||
errors += checkIsDefault(method);
|
seenMethods++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
String expectedMethodCountStr = processingEnv.getOptions().get("expectedMethodCount");
|
||||||
|
if (expectedMethodCountStr == null) {
|
||||||
|
messager.printMessage(ERROR, "No expected method count specified.");
|
||||||
|
} else {
|
||||||
|
int expectedMethodCount = Integer.parseInt(expectedMethodCountStr);
|
||||||
|
|
||||||
if (!hasRun) {
|
if (seenMethods != expectedMethodCount) {
|
||||||
messager.printMessage(ERROR, "No test cases run; test fails.");
|
messager.printMessage(ERROR, "Wrong number of seen methods: " + seenMethods);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@IsDefault(false)
|
@IsDefault(false)
|
||||||
int checkIsDefault(ExecutableElement method) {
|
void checkIsDefault(ExecutableElement method) {
|
||||||
System.out.println("Testing " + method);
|
System.out.println("Testing " + method);
|
||||||
IsDefault expectedIsDefault = method.getAnnotation(IsDefault.class);
|
IsDefault expectedIsDefault = method.getAnnotation(IsDefault.class);
|
||||||
|
|
||||||
|
@ -116,9 +119,7 @@ public class TestExecutableElement extends JavacTestingAbstractProcessor impleme
|
||||||
expectedDefault,
|
expectedDefault,
|
||||||
methodIsDefault).toString(),
|
methodIsDefault).toString(),
|
||||||
method);
|
method);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,4 +143,6 @@ interface ProviderOfDefault {
|
||||||
|
|
||||||
@IsDefault(value=true, expectedTextRegex="\\s*@IsDefault\\(.*\\)\\s*default strictfp void quux\\(\\);\\s*$")
|
@IsDefault(value=true, expectedTextRegex="\\s*@IsDefault\\(.*\\)\\s*default strictfp void quux\\(\\);\\s*$")
|
||||||
default strictfp void quux() {};
|
default strictfp void quux() {};
|
||||||
|
@IsDefault(false)
|
||||||
|
static void statik() {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue