diff --git a/chapi-ast-typescript/src/main/antlr/TypeScriptParser.g4 b/chapi-ast-typescript/src/main/antlr/TypeScriptParser.g4 index d96b6dc9..dce3be58 100644 --- a/chapi-ast-typescript/src/main/antlr/TypeScriptParser.g4 +++ b/chapi-ast-typescript/src/main/antlr/TypeScriptParser.g4 @@ -715,7 +715,7 @@ exportStatement exportStatementTail : Default? declarationStatement #ExportElementDirectly - | Default identifierName #ExportElementAsDefault + | Default identifierName #ExportDefaultDeclaration | multipleExportElements (From StringLiteral)? #ExportElements | Multiply (As identifierName)? From StringLiteral #ExportModule | As Namespace identifierName eos #ExportAsNamespace @@ -749,7 +749,7 @@ variableDeclarationList ; variableDeclaration - : identifierName typeAnnotation? ('=' typeParameters? singleExpression)? // ECMAScript 6: Array & Object Matching + : identifierName typeAnnotation? ('=' typeParameters? singleExpression)? // ECMAScript 6: Array & Object Matching | arrayLiteral | objectLiteral ; @@ -874,10 +874,13 @@ singleExpression | arrowFunctionDeclaration # ArrowFunctionExpressionL | classExpression # ClassExpressionL - | Yield ({this.notLineTerminator()}? expressionSequence)? # YieldExpression + | singleExpression templateStringLiteral # TemplateStringExpression // ECMAScript 6 + | iteratorBlock # IteratorsExpression // ECMAScript 6 + | generatorBlock # GeneratorsExpression // ECMAScript 6 + | generatorFunctionDeclaration # GeneratorsFunctionExpression // ECMAScript 6 + | yieldStatement # YieldExpression // ECMAScript 6 | Await singleExpression # AwaitExpression - // TODO: careful use those | singleExpression '(' (argumentList ','?)? ')' # ArgumentsExpression // RealtionExpression will have conflict @@ -919,7 +922,7 @@ singleExpression | This # ThisExpression | Super # SuperExpression - | typeArguments? identifierName # IdentifierExpression + | typeArguments? identifierName singleExpression? # IdentifierExpression | literal # LiteralExpression | arrayLiteral # ArrayLiteralExpression | objectLiteral # ObjectLiteralExpression @@ -929,6 +932,9 @@ singleExpression | htmlElements # HtmlElementExpression ; +yieldStatement + : Yield ({this.notLineTerminator()}? expressionSequence)? eos + ; asExpression : singleExpression @@ -973,6 +979,10 @@ unaryOperator +generatorFunctionDeclaration + : Function '*' Identifier? '(' formalParameterList? ')' '{' functionBody '}' + ; + generatorBlock : '{' generatorDefinition (',' generatorDefinition)* ','? '}' ; diff --git a/chapi-ast-typescript/src/main/kotlin/chapi/ast/typescriptast/TypeScriptFullIdentListener.kt b/chapi-ast-typescript/src/main/kotlin/chapi/ast/typescriptast/TypeScriptFullIdentListener.kt index c4706a74..7e3d7da7 100644 --- a/chapi-ast-typescript/src/main/kotlin/chapi/ast/typescriptast/TypeScriptFullIdentListener.kt +++ b/chapi-ast-typescript/src/main/kotlin/chapi/ast/typescriptast/TypeScriptFullIdentListener.kt @@ -96,36 +96,36 @@ class TypeScriptFullIdentListener(node: TSIdentify) : TypeScriptAstListener() { ): CodeField { val key = it.getChild(0).text val singleExpression = it.singleExpression() - val field = CodeField(TypeKey = key, TypeValue = "", Modifiers = modifiers) -// val lastExpr = singleExpression.last() -// val field = CodeField(TypeKey = key, TypeValue = lastExpr.text, Modifiers = modifiers) -// -// when (lastExpr) { -// is TypeScriptParser.LiteralExpressionContext -> { -// if (lastExpr.literal().StringLiteral() != null) { -// field.TypeValue = unQuote(lastExpr.text) -// field.TypeType = "String" -// } -// } -// -// is IdentifierExpressionContext -> { -// singleExprToFieldCall(field, lastExpr.singleExpression(), lastExpr.identifierName().text) -// } -// -// is TypeScriptParser.YieldExpressionContext -> { -// if (lastExpr.yieldStatement().expressionSequence() != null) { -// val singeExprs = lastExpr.yieldStatement().expressionSequence().singleExpression() -// singeExprs.forEach { expr -> -// singleExprToFieldCall(field, expr, expr.text) -// } -// } -// } -// -// else -> { -// // println("variableToFields -> ${lastExpr.text} === ${lastExpr.javaClass.simpleName}") -// } -// } + val lastExpr = singleExpression + val field = CodeField(TypeKey = key, TypeValue = lastExpr.text, Modifiers = modifiers) + + when (lastExpr) { + is TypeScriptParser.LiteralExpressionContext -> { + if (lastExpr.literal().StringLiteral() != null) { + field.TypeValue = unQuote(lastExpr.text) + field.TypeType = "String" + } + } + + is IdentifierExpressionContext -> { + singleExprToFieldCall(field, lastExpr.singleExpression(), lastExpr.identifierName().text) + } + + is TypeScriptParser.YieldExpressionContext -> { + if (lastExpr.yieldStatement().expressionSequence() != null) { + val singeExprs = lastExpr.yieldStatement().expressionSequence().singleExpression() + singeExprs.forEach { expr -> + singleExprToFieldCall(field, expr, expr.text) + } + } + } + + else -> { + // println("variableToFields -> ${lastExpr.text} === ${lastExpr.javaClass.simpleName}") + } + } + return field } @@ -941,16 +941,13 @@ class TypeScriptFullIdentListener(node: TSIdentify) : TypeScriptAstListener() { CodeProperty(TypeValue = typeValue, TypeType = "") }?.toTypedArray() ?: arrayOf() -// override fun enterExportDefaultDeclaration(ctx: TypeScriptParser.ExportDefaultDeclarationContext?) { -// val singleExpr = ctx!!.singleExpression() -// if (singleExpr != null) { -// if (!singleExpr.text.contains("(")) { -// currentNode.Exports += CodeExport(singleExpr.text) -// defaultNode.Exports += CodeExport(singleExpr.text) -// } -// } -// } - + override fun enterExportDefaultDeclaration(ctx: TypeScriptParser.ExportDefaultDeclarationContext?) { + val name = ctx!!.identifierName() + if (name != null) { + currentNode.Exports += CodeExport(name.text) + defaultNode.Exports += CodeExport(name.text) + } + } fun getNodeInfo(): CodeContainer { for (entry in nodeMap) { diff --git a/chapi-ast-typescript/src/test/kotlin/chapi/ast/typescriptast/TypeScriptAnalyserTest.kt b/chapi-ast-typescript/src/test/kotlin/chapi/ast/typescriptast/TypeScriptAnalyserTest.kt index f05ece91..cf6ab18d 100644 --- a/chapi-ast-typescript/src/test/kotlin/chapi/ast/typescriptast/TypeScriptAnalyserTest.kt +++ b/chapi-ast-typescript/src/test/kotlin/chapi/ast/typescriptast/TypeScriptAnalyserTest.kt @@ -1,6 +1,8 @@ package chapi.ast.typescriptast import chapi.domain.core.DataStructType +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Test @@ -45,10 +47,15 @@ class TypeScriptAnalyserTest { val content = this::class.java.getResource("/grammar/Function.ts")!!.readText() val codeFile = TypeScriptAnalyser().analysis(content, "") + println(Json.encodeToString(codeFile)) + assertEquals(codeFile.DataStructures.size, 1) assertEquals(codeFile.DataStructures[0].NodeName, "default") val functions = codeFile.DataStructures[0].Functions - assertEquals(functions.size, 9) + assertEquals(functions.size, 3) + + val fields = codeFile.DataStructures[0].Fields + assertEquals(fields.size, 6) } @Test