27 * |
27 * |
28 * @test |
28 * @test |
29 * @run |
29 * @run |
30 */ |
30 */ |
31 |
31 |
|
32 /* |
|
33 * This test script depends on nashorn Compiler internals. It uses reflection |
|
34 * to get access to private field and many public methods of Compiler and |
|
35 * FunctionNode classes. Note that this is trusted code and access to such |
|
36 * internal package classes and methods is okay. But, if you modify any |
|
37 * Compiler or FunctionNode class, you may have to revisit this script. |
|
38 * We cannot use direct Java class (via dynalink bean linker) to Compiler |
|
39 * and FunctionNode because of package-access check and so reflective calls. |
|
40 */ |
|
41 |
|
42 var Compiler = Java.type("jdk.nashorn.internal.codegen.Compiler") |
|
43 var Context = Java.type("jdk.nashorn.internal.runtime.Context") |
|
44 var Source = Java.type("jdk.nashorn.internal.runtime.Source") |
|
45 var FunctionNode = Java.type("jdk.nashorn.internal.ir.FunctionNode") |
|
46 |
|
47 // Compiler class methods and fields |
|
48 |
|
49 // Compiler.compile(Source, Context) |
|
50 var compilerMethod = Compiler.class.getMethod("compiler", Source.class, Context.class); |
|
51 // Compiler.compile() |
|
52 var compileMethod = Compiler.class.getMethod("compile"); |
|
53 |
|
54 // NOTE: private field. But this is a trusted test! |
|
55 // Compiler.functionNode |
|
56 var functionNodeField = Compiler.class.getDeclaredField("functionNode"); |
|
57 functionNodeField.setAccessible(true); |
|
58 |
|
59 // FunctionNode methods |
|
60 |
|
61 // FunctionNode.getFunctions method |
|
62 var getFunctionsMethod = FunctionNode.class.getMethod("getFunctions"); |
|
63 |
|
64 // These are method names of methods in FunctionNode class |
|
65 var allAssertionList = ['isVarArg', 'needsParentScope', 'needsCallee', 'needsScope', 'needsSelfSymbol', 'isSplit', 'hasEval', 'hasWith', 'hasDeepWithOrEval', 'varsInScope', 'isStrictMode'] |
|
66 |
|
67 // corresponding Method objects of FunctionNode class |
|
68 var functionNodeMethods = {}; |
|
69 // initialize FunctionNode methods |
|
70 (function() { |
|
71 for (var f in allAssertionList) { |
|
72 var method = allAssertionList[f]; |
|
73 functionNodeMethods[method] = FunctionNode.class.getMethod(method); |
|
74 } |
|
75 })(); |
|
76 |
|
77 // returns "script" functionNode from Compiler instance |
|
78 function getScriptNode(compiler) { |
|
79 // compiler.functionNode |
|
80 return functionNodeField.get(compiler); |
|
81 } |
|
82 |
|
83 // returns functionNode.getFunctions().get(0) |
|
84 function getFirstFunction(functionNode) { |
|
85 // functionNode.getFunctions().get(0) |
|
86 return getFunctionsMethod.invoke(functionNode).get(0); |
|
87 } |
|
88 |
32 // compile(script) -- compiles a script specified as a string with its |
89 // compile(script) -- compiles a script specified as a string with its |
33 // source code, returns a jdk.nashorn.internal.ir.FunctionNode object |
90 // source code, returns a jdk.nashorn.internal.ir.FunctionNode object |
34 // representing it. |
91 // representing it. |
35 var compile = (function() { |
92 function compile(source) { |
36 var Compiler = Java.type("jdk.nashorn.internal.codegen.Compiler") |
93 var compiler = compilerMethod.invoke(null, |
37 var Context = Java.type("jdk.nashorn.internal.runtime.Context") |
94 new Source("<no name>", source), Context.getContext()) |
38 var Source = Java.type("jdk.nashorn.internal.runtime.Source") |
95 compileMethod.invoke(compiler); |
39 var CompilerAccess = Java.type("jdk.nashorn.internal.codegen.CompilerAccess") |
96 return getScriptNode(compiler) |
40 return function(source) { |
97 }; |
41 var compiler = Compiler.compiler(new Source("<no name>", source), Context.getContext()) |
|
42 compiler.compile() |
|
43 return CompilerAccess.getScriptNode(compiler) |
|
44 } |
|
45 })(); |
|
46 |
98 |
47 var allAssertions = (function() { |
99 var allAssertions = (function() { |
48 var allAssertionList = ['isVarArg', 'needsParentScope', 'needsCallee', 'needsScope', 'needsSelfSymbol', 'isSplit', 'hasEval', 'hasWith', 'hasDeepWithOrEval', 'varsInScope', 'isStrictMode'] |
|
49 var allAssertions = {} |
100 var allAssertions = {} |
50 for(var assertion in allAssertionList) { |
101 for(var assertion in allAssertionList) { |
51 allAssertions[allAssertionList[assertion]] = true |
102 allAssertions[allAssertionList[assertion]] = true |
52 } |
103 } |
53 return allAssertions; |
104 return allAssertions; |
54 })(); |
105 })(); |
|
106 |
55 |
107 |
56 // test(f[, assertions...]) tests whether all the specified assertions on the |
108 // test(f[, assertions...]) tests whether all the specified assertions on the |
57 // passed function node are true. |
109 // passed function node are true. |
58 function test(f) { |
110 function test(f) { |
59 var assertions = {} |
111 var assertions = {} |
64 } |
116 } |
65 assertions[assertion] = true |
117 assertions[assertion] = true |
66 } |
118 } |
67 for(var assertion in allAssertions) { |
119 for(var assertion in allAssertions) { |
68 var expectedValue = !!assertions[assertion] |
120 var expectedValue = !!assertions[assertion] |
69 if(f[assertion] == null) { |
121 if(functionNodeMethods[assertion].invoke(f) !== expectedValue) { |
70 throw "Can't find " + assertion + " on " + f; |
|
71 } |
|
72 if(f[assertion]() !== expectedValue) { |
|
73 throw "Expected " + assertion + " === " + expectedValue + " for " + f; |
122 throw "Expected " + assertion + " === " + expectedValue + " for " + f; |
74 } |
123 } |
75 } |
124 } |
76 } |
125 } |
77 |
126 |
78 // testFirstFn(script[, assertions...] tests whether all the specified |
127 // testFirstFn(script[, assertions...] tests whether all the specified |
79 // assertions are true in the first function in the given script; "script" |
128 // assertions are true in the first function in the given script; "script" |
80 // is a string with the source text of the script. |
129 // is a string with the source text of the script. |
81 function testFirstFn(script) { |
130 function testFirstFn(script) { |
82 arguments[0] = compile(script).functions[0] |
131 arguments[0] = getFirstFunction(compile(script)) |
83 test.apply(null, arguments) |
132 test.apply(null, arguments) |
84 } |
133 } |
85 |
134 |
86 // ---------------------------------- ACTUAL TESTS START HERE -------------- |
135 // ---------------------------------- ACTUAL TESTS START HERE -------------- |
87 |
136 |