1
1
package api
2
2
3
3
import codegen.JsCodeGenerator
4
- import com.oracle.js.parser.ErrorManager
5
- import com.oracle.js.parser.Parser
6
- import com.oracle.js.parser.ScriptEnvironment
7
- import com.oracle.js.parser.Source
8
- import com.oracle.js.parser.ir.ClassNode
9
- import com.oracle.js.parser.ir.FunctionNode
4
+ import com.google.javascript.jscomp.Compiler
5
+ import com.google.javascript.jscomp.SourceFile
6
+ import com.google.javascript.rhino.Node
10
7
import framework.api.js.JsClassId
11
8
import framework.api.js.JsMethodId
12
9
import framework.api.js.JsMultipleClassId
13
10
import framework.api.js.util.isJsBasic
14
11
import framework.api.js.util.jsErrorClassId
15
12
import fuzzer.JsFuzzer
16
13
import fuzzer.providers.JsObjectModelProvider
17
- import org.graalvm.polyglot.Context
18
- import org.utbot.framework.codegen.model.constructor .CgMethodTestSet
14
+ import java.io.File
15
+ import org.utbot.framework.codegen.domain.models .CgMethodTestSet
19
16
import org.utbot.framework.plugin.api.EnvironmentModels
20
17
import org.utbot.framework.plugin.api.ExecutableId
21
18
import org.utbot.framework.plugin.api.UtAssembleModel
@@ -25,10 +22,8 @@ import org.utbot.framework.plugin.api.UtExecutionResult
25
22
import org.utbot.framework.plugin.api.UtExecutionSuccess
26
23
import org.utbot.framework.plugin.api.UtExplicitlyThrownException
27
24
import org.utbot.framework.plugin.api.UtModel
28
- import org.utbot.framework.plugin.api.util.UtContext
29
25
import org.utbot.framework.plugin.api.util.isStatic
30
26
import org.utbot.framework.plugin.api.util.voidClassId
31
- import org.utbot.framework.plugin.api.util.withUtContext
32
27
import org.utbot.fuzzer.FuzzedConcreteValue
33
28
import org.utbot.fuzzer.FuzzedMethodDescription
34
29
import org.utbot.fuzzer.FuzzedValue
@@ -37,6 +32,11 @@ import parser.JsClassAstVisitor
37
32
import parser.JsFunctionAstVisitor
38
33
import parser.JsFuzzerAstVisitor
39
34
import parser.JsParserUtils
35
+ import parser.JsParserUtils.getAbstractFunctionName
36
+ import parser.JsParserUtils.getAbstractFunctionParams
37
+ import parser.JsParserUtils.getClassMethods
38
+ import parser.JsParserUtils.getClassName
39
+ import parser.JsParserUtils.getParamName
40
40
import parser.JsToplevelFunctionAstVisitor
41
41
import service.CoverageServiceProvider
42
42
import service.ServiceContext
@@ -46,7 +46,6 @@ import settings.JsTestGenerationSettings.dummyClassName
46
46
import utils.PathResolver
47
47
import utils.constructClass
48
48
import utils.toJsAny
49
- import java.io.File
50
49
51
50
52
51
class JsTestGenerator (
@@ -62,7 +61,7 @@ class JsTestGenerator(
62
61
63
62
private val exports = mutableSetOf<String >()
64
63
65
- private lateinit var parsedFile: FunctionNode
64
+ private lateinit var parsedFile: Node
66
65
67
66
private val utbotDir = " utbotJs"
68
67
@@ -97,7 +96,7 @@ class JsTestGenerator(
97
96
parsedFile = parsedFile,
98
97
strict = selectedMethods?.isNotEmpty() ? : false
99
98
)
100
- parentClassName = classNode?.ident?.name?.toString ()
99
+ parentClassName = classNode?.getClassName ()
101
100
val classId = makeJsClassId(classNode, ternService)
102
101
val methods = makeMethodsToTest()
103
102
if (methods.isEmpty()) throw IllegalArgumentException (" No methods to test were found!" )
@@ -115,14 +114,14 @@ class JsTestGenerator(
115
114
116
115
private fun makeTestsForMethod (
117
116
classId : JsClassId ,
118
- funcNode : FunctionNode ,
119
- classNode : ClassNode ? ,
117
+ funcNode : Node ,
118
+ classNode : Node ? ,
120
119
context : ServiceContext ,
121
120
testSets : MutableList <CgMethodTestSet >,
122
121
paramNames : MutableMap <ExecutableId , List <String >>
123
122
) {
124
123
val execId = classId.allMethods.find {
125
- it.name == funcNode.name.toString ()
124
+ it.name == funcNode.getAbstractFunctionName ()
126
125
} ? : throw IllegalStateException ()
127
126
manageExports(classNode, funcNode, execId)
128
127
val (concreteValues, fuzzedValues) = runFuzzer(funcNode, execId)
@@ -167,7 +166,7 @@ class JsTestGenerator(
167
166
executions = testsForGenerator,
168
167
)
169
168
testSets + = testSet
170
- paramNames[execId] = funcNode.parameters .map { it.name.toString () }
169
+ paramNames[execId] = funcNode.getAbstractFunctionParams() .map { it.getParamName () }
171
170
}
172
171
173
172
private fun makeImportPrefix (): String {
@@ -231,15 +230,15 @@ class JsTestGenerator(
231
230
}
232
231
233
232
private fun runFuzzer (
234
- funcNode : FunctionNode ,
233
+ funcNode : Node ,
235
234
execId : JsMethodId
236
235
): Pair <Set <FuzzedConcreteValue >, List<List<FuzzedValue>>> {
237
236
val fuzzerVisitor = JsFuzzerAstVisitor ()
238
- funcNode.body. accept(fuzzerVisitor )
237
+ fuzzerVisitor. accept(funcNode )
239
238
val methodUnderTestDescription =
240
239
FuzzedMethodDescription (execId, fuzzerVisitor.fuzzedConcreteValues).apply {
241
- compilableName = funcNode.name.toString ()
242
- val names = funcNode.parameters .map { it.name.toString () }
240
+ compilableName = funcNode.getAbstractFunctionName ()
241
+ val names = funcNode.getAbstractFunctionParams() .map { it.getParamName () }
243
242
parameterNameMap = { index -> names.getOrNull(index) }
244
243
}
245
244
val fuzzedValues =
@@ -248,28 +247,27 @@ class JsTestGenerator(
248
247
}
249
248
250
249
private fun manageExports (
251
- classNode : ClassNode ? ,
252
- funcNode : FunctionNode ,
250
+ classNode : Node ? ,
251
+ funcNode : Node ,
253
252
execId : JsMethodId
254
253
) {
255
- val obligatoryExport = (classNode?.ident?.name ? : funcNode.ident.name ).toString()
254
+ val obligatoryExport = (classNode?.getClassName() ? : funcNode.getAbstractFunctionName() ).toString()
256
255
val collectedExports = collectExports(execId)
257
256
exports + = (collectedExports + obligatoryExport)
258
257
exportsManager(exports.toList())
259
258
}
260
259
261
- private fun makeMethodsToTest (): List <FunctionNode > {
260
+ private fun makeMethodsToTest (): List <Node > {
262
261
return selectedMethods?.map {
263
262
getFunctionNode(
264
263
focusedMethodName = it,
265
264
parentClassName = parentClassName,
266
- fileText = fileText
267
265
)
268
266
} ? : getMethodsToTest()
269
267
}
270
268
271
269
private fun makeJsClassId (
272
- classNode : ClassNode ? ,
270
+ classNode : Node ? ,
273
271
ternService : TernService
274
272
): JsClassId {
275
273
return classNode?.let {
@@ -280,21 +278,12 @@ class JsTestGenerator(
280
278
)
281
279
}
282
280
283
- private fun runParser (fileText : String ): FunctionNode {
284
- // Fixes problem with Graal.polyglot missing from classpath, resulting in error.
285
- withUtContext(UtContext (Context ::class .java.classLoader)) {
286
- val parser = Parser (
287
- ScriptEnvironment .builder().build(),
288
- Source .sourceFor(" jsFile" , fileText),
289
- ErrorManager .ThrowErrorManager ()
290
- )
291
- return parser.parse()
292
- }
293
- }
281
+ private fun runParser (fileText : String ): Node =
282
+ Compiler ().parse(SourceFile .fromCode(" jsFile" , fileText))
294
283
295
- private fun extractToplevelFunctions (): List <FunctionNode > {
284
+ private fun extractToplevelFunctions (): List <Node > {
296
285
val visitor = JsToplevelFunctionAstVisitor ()
297
- parsedFile.body. accept(visitor )
286
+ visitor. accept(parsedFile )
298
287
return visitor.extractedMethods
299
288
}
300
289
@@ -321,18 +310,12 @@ class JsTestGenerator(
321
310
return resultList
322
311
}
323
312
324
- private fun getFunctionNode (focusedMethodName : String , parentClassName : String? , fileText : String ): FunctionNode {
325
- val parser = Parser (
326
- ScriptEnvironment .builder().build(),
327
- Source .sourceFor(" jsFile" , fileText),
328
- ErrorManager .ThrowErrorManager ()
329
- )
330
- val fileNode = parser.parse()
313
+ private fun getFunctionNode (focusedMethodName : String , parentClassName : String? ): Node {
331
314
val visitor = JsFunctionAstVisitor (
332
315
focusedMethodName,
333
316
if (parentClassName != dummyClassName) parentClassName else null
334
317
)
335
- fileNode .accept(visitor )
318
+ visitor .accept(parsedFile )
336
319
return visitor.targetFunctionNode
337
320
}
338
321
@@ -343,12 +326,10 @@ class JsTestGenerator(
343
326
getClassMethods(" " )
344
327
}
345
328
346
- private fun getClassMethods (className : String ): List <FunctionNode > {
329
+ private fun getClassMethods (className : String ): List <Node > {
347
330
val visitor = JsClassAstVisitor (className)
348
- parsedFile.body. accept(visitor )
331
+ visitor. accept(parsedFile )
349
332
val classNode = JsParserUtils .searchForClassDecl(className, parsedFile)
350
- return classNode?.classElements?.filter {
351
- it.value is FunctionNode
352
- }?.map { it.value as FunctionNode } ? : throw IllegalStateException (" Can't extract methods of class $className " )
333
+ return classNode?.getClassMethods() ? : throw IllegalStateException (" Can't extract methods of class $className " )
353
334
}
354
335
}
0 commit comments