From 2dad6e0d0444ebc8d048a8b9646b6727fd293b11 Mon Sep 17 00:00:00 2001 From: Simon Martineau Date: Sun, 1 Sep 2024 17:22:45 -0400 Subject: [PATCH] refactor: add smoke parsing test --- TODO.md | 4 +- .../lang/parser/GleamParser.java | 39 +++++---- grammars/Gleam.bnf | 1 - .../intellijgleam/GleamParserTest.kt | 19 ----- .../themartdev/intellijgleam/GleamTestUtil.kt | 9 --- .../intellijgleam/lexer/GleamLexerTest.kt | 1 - .../parser/GleamParsingTestCase.kt | 21 +++++ .../intellijgleam/parser/SmokeTest.kt | 7 ++ src/test/testData/parser/simple.gleam | 11 --- src/test/testData/parser/simple.txt | 79 ------------------- src/test/testData/parser/smoke/smoke1.gleam | 5 ++ src/test/testData/parser/smoke/smoke1.txt | 45 +++++++++++ 12 files changed, 99 insertions(+), 142 deletions(-) delete mode 100644 src/test/kotlin/com/github/themartdev/intellijgleam/GleamParserTest.kt delete mode 100644 src/test/kotlin/com/github/themartdev/intellijgleam/GleamTestUtil.kt create mode 100644 src/test/kotlin/com/github/themartdev/intellijgleam/parser/GleamParsingTestCase.kt create mode 100644 src/test/kotlin/com/github/themartdev/intellijgleam/parser/SmokeTest.kt delete mode 100644 src/test/testData/parser/simple.gleam delete mode 100644 src/test/testData/parser/simple.txt create mode 100644 src/test/testData/parser/smoke/smoke1.gleam create mode 100644 src/test/testData/parser/smoke/smoke1.txt diff --git a/TODO.md b/TODO.md index 287264e..3aa4f0f 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,6 @@ # Lexer/Parser -- `panic as` -- `todo as` +- `panic as` ✔ +- `todo as` ✔ - `@external` - `@deprecated` - tuple integer access like this: `tuple.1` diff --git a/gen/com/github/themartdev/intellijgleam/lang/parser/GleamParser.java b/gen/com/github/themartdev/intellijgleam/lang/parser/GleamParser.java index 133162f..624ffcb 100644 --- a/gen/com/github/themartdev/intellijgleam/lang/parser/GleamParser.java +++ b/gen/com/github/themartdev/intellijgleam/lang/parser/GleamParser.java @@ -3386,10 +3386,9 @@ private static boolean wholeNumber_1_0(PsiBuilder b, int l) { // 12: ATOM(expressionBitStringExpr) // 13: ATOM(blockExpr) // 14: ATOM(caseExpr) - // 15: ATOM(letExpr) - // 16: PREFIX(useExpr) - // 17: PREFIX(recordUpdateExpr) - // 18: ATOM(panicExpr) + // 15: PREFIX(useExpr) + // 16: PREFIX(recordUpdateExpr) + // 17: ATOM(letExpr) ATOM(panicExpr) public static boolean expression(PsiBuilder b, int l, int g) { if (!recursion_guard_(b, l, "expression")) return false; addVariant(b, ""); @@ -3407,9 +3406,9 @@ public static boolean expression(PsiBuilder b, int l, int g) { if (!r) r = expressionBitStringExpr(b, l + 1); if (!r) r = blockExpr(b, l + 1); if (!r) r = caseExpr(b, l + 1); - if (!r) r = letExpr(b, l + 1); if (!r) r = useExpr(b, l + 1); if (!r) r = recordUpdateExpr(b, l + 1); + if (!r) r = letExpr(b, l + 1); if (!r) r = panicExpr(b, l + 1); p = r; r = r && expression_0(b, l + 1, g); @@ -3832,19 +3831,6 @@ public static boolean caseExpr(PsiBuilder b, int l) { return r; } - // simpleLetExpr - // | assertLetExpr - public static boolean letExpr(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "letExpr")) return false; - if (!nextTokenIsSmart(b, LET)) return false; - boolean r; - Marker m = enter_section_(b, l, _COLLAPSE_, LET_EXPR, null); - r = simpleLetExpr(b, l + 1); - if (!r) r = assertLetExpr(b, l + 1); - exit_section_(b, l, m, r, false, null); - return r; - } - public static boolean useExpr(PsiBuilder b, int l) { if (!recursion_guard_(b, l, "useExpr")) return false; if (!nextTokenIsSmart(b, USE)) return false; @@ -3852,7 +3838,7 @@ public static boolean useExpr(PsiBuilder b, int l) { Marker m = enter_section_(b, l, _NONE_, null); r = useExpr_0(b, l + 1); p = r; - r = p && expression(b, l, 16); + r = p && expression(b, l, 15); exit_section_(b, l, m, USE_EXPR, r, p, null); return r || p; } @@ -3883,7 +3869,7 @@ public static boolean recordUpdateExpr(PsiBuilder b, int l) { Marker m = enter_section_(b, l, _NONE_, null); r = recordUpdateExpr_0(b, l + 1); p = r; - r = p && expression(b, l, 17); + r = p && expression(b, l, 16); r = p && report_error_(b, recordUpdateExpr_1(b, l + 1)) && r; exit_section_(b, l, m, RECORD_UPDATE_EXPR, r, p, null); return r || p; @@ -3921,6 +3907,19 @@ private static boolean recordUpdateExpr_1(PsiBuilder b, int l) { return r; } + // simpleLetExpr + // | assertLetExpr + public static boolean letExpr(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "letExpr")) return false; + if (!nextTokenIsSmart(b, LET)) return false; + boolean r; + Marker m = enter_section_(b, l, _COLLAPSE_, LET_EXPR, null); + r = simpleLetExpr(b, l + 1); + if (!r) r = assertLetExpr(b, l + 1); + exit_section_(b, l, m, r, false, null); + return r; + } + // PANIC (AS stringLiteral)? public static boolean panicExpr(PsiBuilder b, int l) { if (!recursion_guard_(b, l, "panicExpr")) return false; diff --git a/grammars/Gleam.bnf b/grammars/Gleam.bnf index 81437ab..6fc1fd8 100644 --- a/grammars/Gleam.bnf +++ b/grammars/Gleam.bnf @@ -294,7 +294,6 @@ expression ::= parenthesizedExpr | expressionBitStringExpr | blockExpr | caseExpr - | letExpr | useExpr | recordUpdateExpr | simpleKeywordExpr diff --git a/src/test/kotlin/com/github/themartdev/intellijgleam/GleamParserTest.kt b/src/test/kotlin/com/github/themartdev/intellijgleam/GleamParserTest.kt deleted file mode 100644 index b2e2a60..0000000 --- a/src/test/kotlin/com/github/themartdev/intellijgleam/GleamParserTest.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.github.themartdev.intellijgleam - -import com.github.themartdev.intellijgleam.lang.parser.GleamParserDefinition -import com.intellij.testFramework.ParsingTestCase - -class GleamParserTest : ParsingTestCase( - "parser", - "gleam", - true, - GleamParserDefinition() -) { - override fun getTestDataPath(): String = "src/test/testData" - - fun testSimple() = doTest(true, true) -// -// fun testSanityCheck() { -// TestCase.assertEquals(1, 1) -// } -} \ No newline at end of file diff --git a/src/test/kotlin/com/github/themartdev/intellijgleam/GleamTestUtil.kt b/src/test/kotlin/com/github/themartdev/intellijgleam/GleamTestUtil.kt deleted file mode 100644 index fc60617..0000000 --- a/src/test/kotlin/com/github/themartdev/intellijgleam/GleamTestUtil.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.github.themartdev.intellijgleam - -import com.intellij.testFramework.fixtures.IdeaTestExecutionPolicy - -fun getGleamTestDataPath(): String { - val homePath = IdeaTestExecutionPolicy.getHomePathWithPolicy() - return "$homePath/src/test/testData" -} - diff --git a/src/test/kotlin/com/github/themartdev/intellijgleam/lexer/GleamLexerTest.kt b/src/test/kotlin/com/github/themartdev/intellijgleam/lexer/GleamLexerTest.kt index cc76f71..1be5eec 100644 --- a/src/test/kotlin/com/github/themartdev/intellijgleam/lexer/GleamLexerTest.kt +++ b/src/test/kotlin/com/github/themartdev/intellijgleam/lexer/GleamLexerTest.kt @@ -14,6 +14,5 @@ class GleamLexerTest { println("${lexer.tokenType}: ${lexer.tokenText}") lexer.advance() } - } } \ No newline at end of file diff --git a/src/test/kotlin/com/github/themartdev/intellijgleam/parser/GleamParsingTestCase.kt b/src/test/kotlin/com/github/themartdev/intellijgleam/parser/GleamParsingTestCase.kt new file mode 100644 index 0000000..3ec0401 --- /dev/null +++ b/src/test/kotlin/com/github/themartdev/intellijgleam/parser/GleamParsingTestCase.kt @@ -0,0 +1,21 @@ +package com.github.themartdev.intellijgleam.parser + +import com.github.themartdev.intellijgleam.lang.parser.GleamParserDefinition +import com.intellij.testFramework.ParsingTestCase + +abstract class GleamParsingTestCase : ParsingTestCase( + "", + "gleam", + true, + GleamParserDefinition() +) { + override fun getTestDataPath(): String = "src/test/testData/parser" + + override fun skipSpaces(): Boolean = false + + override fun includeRanges(): Boolean = true + + protected fun assertParsedCorrectly() { + doTest(true, true) + } +} diff --git a/src/test/kotlin/com/github/themartdev/intellijgleam/parser/SmokeTest.kt b/src/test/kotlin/com/github/themartdev/intellijgleam/parser/SmokeTest.kt new file mode 100644 index 0000000..a284217 --- /dev/null +++ b/src/test/kotlin/com/github/themartdev/intellijgleam/parser/SmokeTest.kt @@ -0,0 +1,7 @@ +package com.github.themartdev.intellijgleam.parser + +class SmokeTest : GleamParsingTestCase() { + override fun getTestDataPath(): String = super.getTestDataPath() + "/smoke" + + fun testSmoke1() = assertParsedCorrectly() +} \ No newline at end of file diff --git a/src/test/testData/parser/simple.gleam b/src/test/testData/parser/simple.gleam deleted file mode 100644 index 3691729..0000000 --- a/src/test/testData/parser/simple.gleam +++ /dev/null @@ -1,11 +0,0 @@ -import gleam/string as text -import gleam/io -import gleam/io.{println} - -pub fn main() { - // Use the function in a qualified fashion - io.println("This is qualified") - - // Or an unqualified fashion - println("This is unqualified") -} \ No newline at end of file diff --git a/src/test/testData/parser/simple.txt b/src/test/testData/parser/simple.txt deleted file mode 100644 index d05f4b9..0000000 --- a/src/test/testData/parser/simple.txt +++ /dev/null @@ -1,79 +0,0 @@ -Gleam File - GleamStatementImpl(STATEMENT) - GleamImportDeclarationImpl(IMPORT_DECLARATION) - PsiElement(import)('import') - PsiWhiteSpace(' ') - GleamImportPathImpl(IMPORT_PATH) - PsiElement(IDENTIFIER)('gleam') - PsiElement(BAD_CHARACTER)('/') - PsiElement(IDENTIFIER)('string') - PsiWhiteSpace(' ') - PsiElement(as)('as') - PsiWhiteSpace(' ') - PsiElement(IDENTIFIER)('text') - PsiWhiteSpace('\n') - GleamStatementImpl(STATEMENT) - GleamImportDeclarationImpl(IMPORT_DECLARATION) - PsiElement(import)('import') - PsiWhiteSpace(' ') - GleamImportPathImpl(IMPORT_PATH) - PsiElement(IDENTIFIER)('gleam') - PsiElement(BAD_CHARACTER)('/') - PsiElement(IDENTIFIER)('io') - PsiWhiteSpace('\n') - GleamStatementImpl(STATEMENT) - GleamImportDeclarationImpl(IMPORT_DECLARATION) - PsiElement(import)('import') - PsiWhiteSpace(' ') - GleamImportPathImpl(IMPORT_PATH) - PsiElement(IDENTIFIER)('gleam') - PsiElement(BAD_CHARACTER)('/') - PsiElement(IDENTIFIER)('io') - PsiElement(.)('.') - GleamImportListImpl(IMPORT_LIST) - PsiElement({)('{') - PsiElement(IDENTIFIER)('println') - PsiElement(})('}') - PsiWhiteSpace('\n\n') - GleamStatementImpl(STATEMENT) - GleamFunctionDeclarationImpl(FUNCTION_DECLARATION) - PsiElement(pub)('pub') - PsiWhiteSpace(' ') - PsiElement(fn)('fn') - PsiWhiteSpace(' ') - PsiElement(IDENTIFIER)('main') - PsiElement(()('(') - PsiElement())(')') - PsiWhiteSpace(' ') - GleamBlockImpl(BLOCK) - PsiElement({)('{') - PsiWhiteSpace('\n ') - PsiElement(LINE_COMMENT)('// Use the function in a qualified fashion') - PsiWhiteSpace('\n ') - GleamStatementImpl(STATEMENT) - GleamExpressionImpl(EXPRESSION) - GleamFunctionCallImpl(FUNCTION_CALL) - PsiElement(IDENTIFIER)('io') - PsiElement(.)('.') - PsiElement(IDENTIFIER)('println') - PsiElement(()('(') - GleamArgumentListImpl(ARGUMENT_LIST) - GleamExpressionImpl(EXPRESSION) - GleamStringLiteralImpl(STRING_LITERAL) - PsiElement(STRING_LITERAL)('"This is qualified"') - PsiElement())(')') - PsiWhiteSpace('\n\n ') - PsiElement(LINE_COMMENT)('// Or an unqualified fashion') - PsiWhiteSpace('\n ') - GleamStatementImpl(STATEMENT) - GleamExpressionImpl(EXPRESSION) - GleamFunctionCallImpl(FUNCTION_CALL) - PsiElement(IDENTIFIER)('println') - PsiElement(()('(') - GleamArgumentListImpl(ARGUMENT_LIST) - GleamExpressionImpl(EXPRESSION) - GleamStringLiteralImpl(STRING_LITERAL) - PsiElement(STRING_LITERAL)('"This is unqualified"') - PsiElement())(')') - PsiWhiteSpace('\n') - PsiElement(})('}') diff --git a/src/test/testData/parser/smoke/smoke1.gleam b/src/test/testData/parser/smoke/smoke1.gleam new file mode 100644 index 0000000..30530b2 --- /dev/null +++ b/src/test/testData/parser/smoke/smoke1.gleam @@ -0,0 +1,5 @@ +import gleam/io + +pub fn main() { + io.println("Hello, Joe!") +} diff --git a/src/test/testData/parser/smoke/smoke1.txt b/src/test/testData/parser/smoke/smoke1.txt new file mode 100644 index 0000000..819f99c --- /dev/null +++ b/src/test/testData/parser/smoke/smoke1.txt @@ -0,0 +1,45 @@ +Gleam File(0,62) + GleamTopLevelStatementImpl(TOP_LEVEL_STATEMENT)(0,15) + GleamImportStatementImpl(IMPORT_STATEMENT)(0,15) + PsiElement(import)('import')(0,6) + PsiWhiteSpace(' ')(6,7) + GleamModuleImpl(MODULE)(7,15) + PsiElement(IDENTIFIER)('gleam')(7,12) + PsiElement(/)('/')(12,13) + PsiElement(IDENTIFIER)('io')(13,15) + PsiWhiteSpace('\n\n')(15,17) + GleamTopLevelStatementImpl(TOP_LEVEL_STATEMENT)(17,62) + GleamFunctionImpl(FUNCTION)(17,62) + GleamVisibilityModifierImpl(VISIBILITY_MODIFIER)(17,20) + PsiElement(pub)('pub')(17,20) + PsiWhiteSpace(' ')(20,21) + PsiElement(fn)('fn')(21,23) + PsiWhiteSpace(' ')(23,24) + GleamFunctionNameDefinitionImpl(FUNCTION_NAME_DEFINITION)(24,28) + PsiElement(IDENTIFIER)('main')(24,28) + GleamFunctionParametersImpl(FUNCTION_PARAMETERS)(28,30) + PsiElement(()('(')(28,29) + PsiElement())(')')(29,30) + PsiWhiteSpace(' ')(30,31) + GleamFunctionBodyImpl(FUNCTION_BODY)(31,62) + PsiElement({)('{')(31,32) + PsiWhiteSpace('\n ')(32,35) + GleamExpressionSeqImpl(EXPRESSION_SEQ)(35,60) + GleamCallExprImpl(CALL_EXPR)(35,60) + GleamAccessExprImpl(ACCESS_EXPR)(35,45) + GleamReferenceExprImpl(REFERENCE_EXPR)(35,37) + PsiElement(IDENTIFIER)('io')(35,37) + PsiElement(.)('.')(37,38) + GleamLabelImpl(LABEL)(38,45) + PsiElement(IDENTIFIER)('println')(38,45) + GleamArgumentsImpl(ARGUMENTS)(45,60) + PsiElement(()('(')(45,46) + GleamArgumentImpl(ARGUMENT)(46,59) + GleamLiteralExprImpl(LITERAL_EXPR)(46,59) + GleamStringLiteralImpl(STRING_LITERAL)(46,59) + PsiElement(OPEN_QUOTE)('"')(46,47) + PsiElement(REGULAR_STRING_PART)('Hello, Joe!')(47,58) + PsiElement(")('"')(58,59) + PsiElement())(')')(59,60) + PsiWhiteSpace('\n')(60,61) + PsiElement(})('}')(61,62) \ No newline at end of file