| /******************************************************************************* |
| * Copyright (c) 2017, 2018 IBM Corporation. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.jdt.core.tests.compiler.regression; |
| |
| import java.io.File; |
| import java.util.Arrays; |
| import java.util.stream.Stream; |
| |
| import org.eclipse.jdt.core.ToolFactory; |
| import org.eclipse.jdt.core.util.IAttributeNamesConstants; |
| import org.eclipse.jdt.core.util.IClassFileAttribute; |
| import org.eclipse.jdt.core.util.IClassFileReader; |
| import org.eclipse.jdt.core.util.IModuleAttribute; |
| import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; |
| |
| import junit.framework.Test; |
| |
| public class ModuleAttributeTests extends AbstractRegressionTest9 { |
| |
| public ModuleAttributeTests(String name) { |
| super(name); |
| } |
| |
| public static Class<?> testClass() { |
| return ModuleAttributeTests.class; |
| } |
| |
| private static String[] allowedAttributes = { |
| new String(IAttributeNamesConstants.MODULE), |
| new String(IAttributeNamesConstants.MODULE_MAIN_CLASS), |
| new String(IAttributeNamesConstants.MODULE_PACKAGES), |
| new String(IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS), |
| new String(IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS), |
| new String(IAttributeNamesConstants.SOURCE) |
| }; |
| // Use this static initializer to specify subset for tests |
| // All specified tests which does not belong to the class are skipped... |
| static { |
| // TESTS_PREFIX = "testBug95521"; |
| // TESTS_NAMES = new String[] { "testBug508889_003" }; |
| // TESTS_NUMBERS = new int[] { 53 }; |
| // TESTS_RANGE = new int[] { 23 -1,}; |
| } |
| public static Test suite() { |
| return buildMinimalComplianceTestSuite(testClass(), F_9); |
| } |
| |
| private IModuleAttribute getModuleAttribute(String[] contents) { |
| this.runConformTest(contents); |
| IClassFileReader cfr = ToolFactory.createDefaultClassFileReader(OUTPUT_DIR + File.separator + "module-info.class", IClassFileReader.CLASSFILE_ATTRIBUTES); |
| assertNotNull("Error reading module-info.class", cfr); |
| IClassFileAttribute attr = Arrays.stream(cfr.getAttributes()) |
| .filter(e -> new String(e.getAttributeName()).equals("Module")) |
| .findFirst() |
| .orElse(null); |
| assertNotNull("Module attribute not found", attr); |
| assertTrue("Not a module attribute", attr instanceof IModuleAttribute); |
| return (IModuleAttribute) attr; |
| } |
| |
| // basic test to check for presence of module attribute in module-info.class |
| public void test001() throws Exception { |
| this.runConformTest( |
| new String[] { |
| "module-info.java", |
| "module test {\n" + |
| "}\n", |
| }); |
| IClassFileReader cfr = ToolFactory.createDefaultClassFileReader(OUTPUT_DIR + File.separator + "module-info.class", IClassFileReader.CLASSFILE_ATTRIBUTES); |
| assertNotNull("Error reading module-info.class", cfr); |
| IClassFileAttribute moduleAttribute = null; |
| IClassFileAttribute[] attrs = cfr.getAttributes(); |
| for (int i=0,max=attrs.length;i<max;i++) { |
| if (new String(attrs[i].getAttributeName()).equals("Module")) { |
| moduleAttribute = attrs[i]; |
| } |
| } |
| assertNotNull("Module attribute not found", moduleAttribute); |
| } |
| // Test that there is at most one Module attribute in the attributes table of a ClassFile structure- JVMS Sec 4.7.25 |
| public void testBug508889_002() throws Exception { |
| this.runConformTest( |
| new String[] { |
| "module-info.java", |
| "module first {\n" + |
| "}\n", |
| }); |
| IClassFileReader cfr = ToolFactory.createDefaultClassFileReader(OUTPUT_DIR + File.separator + "module-info.class", IClassFileReader.CLASSFILE_ATTRIBUTES); |
| assertNotNull("Error reading module-info.class", cfr); |
| long count = Arrays.stream(cfr.getAttributes()) |
| .filter(e -> new String(e.getAttributeName()).equals("Module")) |
| .count(); |
| assertEquals("Unexpected number of module attributes", 1, count); |
| } |
| // Module Atrribute sanity |
| public void _testBug508889_003() throws Exception { |
| String[] contents = { |
| "module-info.java", |
| "module first {\n" + |
| "exports pack1;\n" + |
| "exports pack2 to zero;\n" + |
| "}\n", |
| "pack1/X11.java", |
| "package pack1;\n" + |
| "public class X11 {}\n", |
| "pack2/X21.java", |
| "package pack2;\n" + |
| "public class X21 {}\n", |
| }; |
| IModuleAttribute module = getModuleAttribute(contents); |
| assertEquals("Wrong Module Name", "first", new String(module.getModuleName())); |
| assertTrue("Unexpected attribute length", module.getAttributeLength() > 0); |
| //int flags = module.getModuleFlags(); |
| } |
| public void testBug521521() throws Exception { |
| this.runConformTest( |
| new String[] { |
| "module-info.java", |
| "module test {\n" + |
| "}\n", |
| }); |
| IClassFileReader cfr = ToolFactory.createDefaultClassFileReader(OUTPUT_DIR + File.separator + "module-info.class", IClassFileReader.CLASSFILE_ATTRIBUTES); |
| assertNotNull("Error reading module-info.class", cfr); |
| int flags = cfr.getAccessFlags(); |
| assertTrue("Invalid access flags", (flags & ~ClassFileConstants.AccModule) == 0); |
| } |
| public void testBug521521a() throws Exception { |
| this.runConformTest( |
| new String[] { |
| "module-info.java", |
| "open module test {\n" + |
| "}\n", |
| }); |
| IClassFileReader cfr = ToolFactory.createDefaultClassFileReader(OUTPUT_DIR + File.separator + "module-info.class", IClassFileReader.CLASSFILE_ATTRIBUTES); |
| assertNotNull("Error reading module-info.class", cfr); |
| int flags = cfr.getAccessFlags(); |
| assertTrue("Invalid access flags", (flags & ~ClassFileConstants.AccModule) == 0); |
| } |
| |
| public void testModuleCompile() throws Exception { |
| String pack1_x11java = "pack1/X11.java"; |
| String pack2_x21java = "pack2/X21.java"; |
| associateToModule("first", pack1_x11java, pack2_x21java); |
| String[] contents = { |
| "module-info.java", |
| "module first {\n" + |
| "exports pack1;\n" + |
| "exports pack2 to zero;\n" + |
| "}\n", |
| pack1_x11java, |
| "package pack1;\n" + |
| "public class X11 {}\n", |
| pack2_x21java, |
| "package pack2;\n" + |
| "public class X21 {}\n", |
| }; |
| this.runConformTest(contents); |
| } |
| public void testBug495967() throws Exception { |
| String pack1_x11java = "pack1/pack2/pack3/pack4/X11.java"; |
| String pack2_x21java = "pack21/pack22/pack23/pack24/X21.java"; |
| String pack3_x31java = "pack31/pack32/pack33/pack34/X31.java"; |
| String pack4_x41java = "pack41/pack42/pack43/pack44/X41.java"; |
| String pack5_x51java = "pack51/pack52/pack53/pack54/X51.java"; |
| String pack6_x61java = "pack61/pack62/pack63/pack64/X61.java"; |
| String pack7_x71java = "pack71/pack72/pack73/pack74/X71.java"; |
| String pack8_x81java = "pack81/pack82/pack83/pack84/X81.java"; |
| String pack9_x91java = "pack91/pack92/pack93/pack94/X91.java"; |
| associateToModule("first", pack1_x11java, pack2_x21java, pack3_x31java, pack4_x41java, pack5_x51java, pack6_x61java, pack7_x71java, pack8_x81java, pack9_x91java); |
| String[] contents = { |
| "module-info.java", |
| "module first {\n" + |
| "exports pack1.pack2.pack3.pack4 to zero, one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty;\n" + |
| "exports pack21.pack22.pack23.pack24 to zero, one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty;\n" + |
| "exports pack31.pack32.pack33.pack34 to zero, one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty;\n" + |
| "exports pack41.pack42.pack43.pack44 to zero, one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty;\n" + |
| "exports pack51.pack52.pack53.pack54 to zero, one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty;\n" + |
| "exports pack61.pack62.pack63.pack64 to zero, one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty;\n" + |
| "exports pack71.pack72.pack73.pack74 to zero, one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty;\n" + |
| "exports pack81.pack82.pack83.pack84 to zero, one, two, three, four, five;\n" + |
| "exports pack91.pack92.pack93.pack94 to zero, one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty;\n" + |
| "}\n", |
| pack1_x11java, |
| "package pack1.pack2.pack3.pack4;\n" + |
| "public class X11 {}\n", |
| pack2_x21java, |
| "package pack21.pack22.pack23.pack24;\n" + |
| "public class X21 {}\n", |
| pack3_x31java, |
| "package pack31.pack32.pack33.pack34;\n" + |
| "public class X31 {}\n", |
| pack4_x41java, |
| "package pack41.pack42.pack43.pack44;\n" + |
| "public class X41 {}\n", |
| pack5_x51java, |
| "package pack51.pack52.pack53.pack54;\n" + |
| "public class X51 {}\n", |
| pack6_x61java, |
| "package pack61.pack62.pack63.pack64;\n" + |
| "public class X61 {}\n", |
| pack7_x71java, |
| "package pack71.pack72.pack73.pack74;\n" + |
| "public class X71 {}\n", |
| pack8_x81java, |
| "package pack81.pack82.pack83.pack84;\n" + |
| "public class X81 {}\n", |
| pack9_x91java, |
| "package pack91.pack92.pack93.pack94;\n" + |
| "public class X91 {}\n", |
| }; |
| this.runConformTest(contents); |
| } |
| public void testBug519330() throws Exception { |
| String[] contents = { |
| "module-info.java", |
| "module java.base {\n" + |
| "}\n", |
| }; |
| IModuleAttribute moduleAttribute = getModuleAttribute(contents); |
| assertTrue("module java.base should not require any other modules", moduleAttribute.getRequiresCount() == 0); |
| } |
| public void testBug533134() throws Exception { |
| String[] contents = { |
| "module-info.java", |
| "@Deprecated\n" + |
| "module test {\n" + |
| "}\n", |
| }; |
| this.runConformTest(contents); |
| IClassFileReader cfr = ToolFactory.createDefaultClassFileReader(OUTPUT_DIR + File.separator + "module-info.class", IClassFileReader.CLASSFILE_ATTRIBUTES); |
| assertNotNull("Error reading module-info.class", cfr); |
| IClassFileAttribute[] attrs = cfr.getAttributes(); |
| for (IClassFileAttribute attr : attrs) { |
| String name = new String(attr.getAttributeName()); |
| assertTrue("Attribute " + name + " is not allowed", Stream.of(allowedAttributes).anyMatch(a -> a.equals(name))); |
| } |
| } |
| } |