aboutsummaryrefslogtreecommitdiffstats
path: root/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/ModuleTest.java
blob: d6e2b456b4b4f74279d94efc54620f73711e2e92 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/* *******************************************************************
 * Copyright (c) 2016 Contributors
 * 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: 
 *     Andy Clement -     initial implementation 
 * ******************************************************************/

package org.aspectj.apache.bcel.classfile.tests;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;

import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.Attribute;
import org.aspectj.apache.bcel.classfile.ClassParser;
import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.classfile.Module;
import org.aspectj.apache.bcel.classfile.Module.Export;
import org.aspectj.apache.bcel.classfile.Module.Provide;
import org.aspectj.apache.bcel.classfile.Module.Require;
import org.aspectj.apache.bcel.classfile.Module.Uses;
import org.aspectj.apache.bcel.classfile.SourceFile;
import org.aspectj.apache.bcel.classfile.Unknown;

/**
 * http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html
 * 
 * @author Andy Clement
 */
public class ModuleTest extends BcelTestCase {

	public void testLoadSimpleModuleClass() throws Exception {
		String moduleFilename = "testdata/modules/one/module-info.class";
		ClassParser classParser = new ClassParser(moduleFilename);
		JavaClass javaClass = classParser.parse();
		assertNotNull(javaClass);
		assertEquals(Constants.MAJOR_1_9,javaClass.getMajor());
		assertEquals(Constants.MINOR_1_9,javaClass.getMinor());
		assertEquals(Constants.ACC_MODULE,javaClass.getModifiers()); 
		assertEquals(0,javaClass.getSuperclassNameIndex());
		assertEquals(0,javaClass.getInterfaceIndices().length);
		assertEquals(0,javaClass.getFields().length);
		assertEquals(0,javaClass.getMethods().length);
		Attribute[] attrs = javaClass.getAttributes();
		assertEquals(2,attrs.length);
		SourceFile sourceFile = (SourceFile) getAttribute(attrs,Constants.ATTR_SOURCE_FILE);
		Module moduleAttr = new Module((Unknown)getAttribute(attrs,Constants.ATTR_UNKNOWN));
		byte[] originalData = moduleAttr.getBytes();
		String[] requiredModuleNames = moduleAttr.getRequiredModuleNames();
		assertEquals(1,requiredModuleNames.length);
		assertEquals("java.base",requiredModuleNames[0]);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		moduleAttr.dump(new DataOutputStream(baos));
		byte[] newData = baos.toByteArray();
		// The 6 offset here is because the newdata includes the 2byte cpool pointer for the name 'Module'
		// and the 4byte int length field for the attribute data
		if (newData.length!=originalData.length+6) {
			fail("Expected the length of the original attribute ("+originalData.length+") to match the new written length ("+newData.length+")");
		}
		for (int i=0;i<originalData.length;i++) {
			if (originalData[i]!=newData[i+6]) {
				fail("byte mismatch at position "+i+" of "+newData.length);
			}
		}
	}
	

	public void testRequires() throws Exception {
		Module moduleAttr = getModuleAttribute("testdata/modules/two/d/module-info.class");
		Require[] requires = moduleAttr.getRequires();
		assertEquals(3,requires.length);
		assertEquals("requires mandated java.base",requires[0].toString());
		assertEquals("requires a.b.c",requires[1].toString());
		assertEquals("requires public b.c.d",requires[2].toString());
		assertEquals("java.base",requires[0].getModuleName());
		assertEquals("a.b.c",requires[1].getModuleName());
		assertEquals("b.c.d",requires[2].getModuleName());
	}
	
	public void testExports() throws Exception {
		Module moduleAttr = getModuleAttribute("testdata/modules/two/e/module-info.class");
		Export[] exports = moduleAttr.getExports();
		assertEquals(3,exports.length);
		assertEquals("exports com.foo1",exports[0].toString());
		assertEquals("exports com.foo2 to a.b.c",exports[1].toString());
		assertEquals("exports com.foo3 to b.c.d, a.b.c",exports[2].toString());
		assertEquals("com/foo1",exports[0].getExportedPackage());
		assertEquals("com/foo2",exports[1].getExportedPackage());
		assertEquals("com/foo3",exports[2].getExportedPackage());
		assertEquals("a.b.c",exports[1].getToModuleNames()[0]);
		assertEquals("b.c.d",exports[2].getToModuleNames()[0]);
		assertEquals("a.b.c",exports[2].getToModuleNames()[1]);
	}
	
	public void testUses() throws Exception {
		Module moduleAttr = getModuleAttribute("testdata/modules/two/f/module-info.class");
		Uses[] uses = moduleAttr.getUses();
		assertEquals(1,uses.length);
		assertEquals("com/foo1/I1",uses[0].getTypeName());
		assertEquals("uses com.foo1.I1",uses[0].toString());
	}
	
	public void testProvides() throws Exception {
		Module moduleAttr = getModuleAttribute("testdata/modules/two/g/module-info.class");
		Provide[] provides = moduleAttr.getProvides();
		assertEquals(2,provides.length);
		assertEquals("provides com.foo1.I1 with com.foo1.C1",provides[0].toString());
		assertEquals("provides com.foo2.I2 with com.foo2.C2",provides[1].toString());
		assertEquals("com/foo1/I1",provides[0].getProvidedType());
		assertEquals("com/foo1/C1",provides[0].getWithType());
		assertEquals("com/foo2/I2",provides[1].getProvidedType());
		assertEquals("com/foo2/C2",provides[1].getWithType());
	}

	// ---
	
	private Module getModuleAttribute(String moduleInfoClass) throws Exception {
		ClassParser classParser = new ClassParser(moduleInfoClass);
		JavaClass javaClass = classParser.parse();
		Module moduleAttr = new Module((Unknown)getAttribute(javaClass.getAttributes(),Constants.ATTR_UNKNOWN));
		return moduleAttr;
	}
	
}