11package api
22
33import 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
107import framework.api.js.JsClassId
118import framework.api.js.JsMethodId
129import framework.api.js.JsMultipleClassId
1310import framework.api.js.util.isJsBasic
1411import framework.api.js.util.jsErrorClassId
1512import fuzzer.JsFuzzer
1613import 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
1916import org.utbot.framework.plugin.api.EnvironmentModels
2017import org.utbot.framework.plugin.api.ExecutableId
2118import org.utbot.framework.plugin.api.UtAssembleModel
@@ -25,10 +22,8 @@ import org.utbot.framework.plugin.api.UtExecutionResult
2522import org.utbot.framework.plugin.api.UtExecutionSuccess
2623import org.utbot.framework.plugin.api.UtExplicitlyThrownException
2724import org.utbot.framework.plugin.api.UtModel
28- import org.utbot.framework.plugin.api.util.UtContext
2925import org.utbot.framework.plugin.api.util.isStatic
3026import org.utbot.framework.plugin.api.util.voidClassId
31- import org.utbot.framework.plugin.api.util.withUtContext
3227import org.utbot.fuzzer.FuzzedConcreteValue
3328import org.utbot.fuzzer.FuzzedMethodDescription
3429import org.utbot.fuzzer.FuzzedValue
@@ -37,6 +32,11 @@ import parser.JsClassAstVisitor
3732import parser.JsFunctionAstVisitor
3833import parser.JsFuzzerAstVisitor
3934import 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
4040import parser.JsToplevelFunctionAstVisitor
4141import service.CoverageServiceProvider
4242import service.ServiceContext
@@ -46,7 +46,6 @@ import settings.JsTestGenerationSettings.dummyClassName
4646import utils.PathResolver
4747import utils.constructClass
4848import utils.toJsAny
49- import java.io.File
5049
5150
5251class JsTestGenerator (
@@ -62,7 +61,7 @@ class JsTestGenerator(
6261
6362 private val exports = mutableSetOf<String >()
6463
65- private lateinit var parsedFile: FunctionNode
64+ private lateinit var parsedFile: Node
6665
6766 private val utbotDir = " utbotJs"
6867
@@ -97,7 +96,7 @@ class JsTestGenerator(
9796 parsedFile = parsedFile,
9897 strict = selectedMethods?.isNotEmpty() ? : false
9998 )
100- parentClassName = classNode?.ident?.name?.toString ()
99+ parentClassName = classNode?.getClassName ()
101100 val classId = makeJsClassId(classNode, ternService)
102101 val methods = makeMethodsToTest()
103102 if (methods.isEmpty()) throw IllegalArgumentException (" No methods to test were found!" )
@@ -115,14 +114,14 @@ class JsTestGenerator(
115114
116115 private fun makeTestsForMethod (
117116 classId : JsClassId ,
118- funcNode : FunctionNode ,
119- classNode : ClassNode ? ,
117+ funcNode : Node ,
118+ classNode : Node ? ,
120119 context : ServiceContext ,
121120 testSets : MutableList <CgMethodTestSet >,
122121 paramNames : MutableMap <ExecutableId , List <String >>
123122 ) {
124123 val execId = classId.allMethods.find {
125- it.name == funcNode.name.toString ()
124+ it.name == funcNode.getAbstractFunctionName ()
126125 } ? : throw IllegalStateException ()
127126 manageExports(classNode, funcNode, execId)
128127 val (concreteValues, fuzzedValues) = runFuzzer(funcNode, execId)
@@ -167,7 +166,7 @@ class JsTestGenerator(
167166 executions = testsForGenerator,
168167 )
169168 testSets + = testSet
170- paramNames[execId] = funcNode.parameters .map { it.name.toString () }
169+ paramNames[execId] = funcNode.getAbstractFunctionParams() .map { it.getParamName () }
171170 }
172171
173172 private fun makeImportPrefix (): String {
@@ -231,15 +230,15 @@ class JsTestGenerator(
231230 }
232231
233232 private fun runFuzzer (
234- funcNode : FunctionNode ,
233+ funcNode : Node ,
235234 execId : JsMethodId
236235 ): Pair <Set <FuzzedConcreteValue >, List<List<FuzzedValue>>> {
237236 val fuzzerVisitor = JsFuzzerAstVisitor ()
238- funcNode.body. accept(fuzzerVisitor )
237+ fuzzerVisitor. accept(funcNode )
239238 val methodUnderTestDescription =
240239 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 () }
243242 parameterNameMap = { index -> names.getOrNull(index) }
244243 }
245244 val fuzzedValues =
@@ -248,28 +247,27 @@ class JsTestGenerator(
248247 }
249248
250249 private fun manageExports (
251- classNode : ClassNode ? ,
252- funcNode : FunctionNode ,
250+ classNode : Node ? ,
251+ funcNode : Node ,
253252 execId : JsMethodId
254253 ) {
255- val obligatoryExport = (classNode?.ident?.name ? : funcNode.ident.name ).toString()
254+ val obligatoryExport = (classNode?.getClassName() ? : funcNode.getAbstractFunctionName() ).toString()
256255 val collectedExports = collectExports(execId)
257256 exports + = (collectedExports + obligatoryExport)
258257 exportsManager(exports.toList())
259258 }
260259
261- private fun makeMethodsToTest (): List <FunctionNode > {
260+ private fun makeMethodsToTest (): List <Node > {
262261 return selectedMethods?.map {
263262 getFunctionNode(
264263 focusedMethodName = it,
265264 parentClassName = parentClassName,
266- fileText = fileText
267265 )
268266 } ? : getMethodsToTest()
269267 }
270268
271269 private fun makeJsClassId (
272- classNode : ClassNode ? ,
270+ classNode : Node ? ,
273271 ternService : TernService
274272 ): JsClassId {
275273 return classNode?.let {
@@ -280,21 +278,12 @@ class JsTestGenerator(
280278 )
281279 }
282280
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))
294283
295- private fun extractToplevelFunctions (): List <FunctionNode > {
284+ private fun extractToplevelFunctions (): List <Node > {
296285 val visitor = JsToplevelFunctionAstVisitor ()
297- parsedFile.body. accept(visitor )
286+ visitor. accept(parsedFile )
298287 return visitor.extractedMethods
299288 }
300289
@@ -321,18 +310,12 @@ class JsTestGenerator(
321310 return resultList
322311 }
323312
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 {
331314 val visitor = JsFunctionAstVisitor (
332315 focusedMethodName,
333316 if (parentClassName != dummyClassName) parentClassName else null
334317 )
335- fileNode .accept(visitor )
318+ visitor .accept(parsedFile )
336319 return visitor.targetFunctionNode
337320 }
338321
@@ -343,12 +326,10 @@ class JsTestGenerator(
343326 getClassMethods(" " )
344327 }
345328
346- private fun getClassMethods (className : String ): List <FunctionNode > {
329+ private fun getClassMethods (className : String ): List <Node > {
347330 val visitor = JsClassAstVisitor (className)
348- parsedFile.body. accept(visitor )
331+ visitor. accept(parsedFile )
349332 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 " )
353334 }
354335}
0 commit comments