From aa5ca2f9a8f36fba434c28d33c67dfb25ffc86c3 Mon Sep 17 00:00:00 2001 From: Mark McCulloh Date: Fri, 22 Sep 2023 05:26:31 -0400 Subject: [PATCH] fix: automatically semicolon incorrectly inserted into `as` and `in` expressions (#4254) Fixes #4247 *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. --- libs/tree-sitter-wing/src/scanner.c | 30 +++++++++++++++++++ .../test/corpus/expressions.txt | 22 ++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/libs/tree-sitter-wing/src/scanner.c b/libs/tree-sitter-wing/src/scanner.c index 87a5fca5280..02ee7e61323 100644 --- a/libs/tree-sitter-wing/src/scanner.c +++ b/libs/tree-sitter-wing/src/scanner.c @@ -84,6 +84,16 @@ static bool scan_whitespace_and_comments(TSLexer *lexer) } } +/** + * Check if a character is a valid identifier character + * + * @return true if the character is a valid identifier character, false otherwise + */ +static bool iswidentifier(int c) +{ + return iswalnum(c) || c == '_'; +} + /** * Check if an automatic semicolon could be inserted * @@ -146,6 +156,26 @@ static bool scan_automatic_semicolon(TSLexer *lexer) case '!': skip(lexer); return lexer->lookahead != '='; + + // Don't insert a semicolon before `in` (unless it's part of an identifier) + case 'i': + skip(lexer); + if (lexer->lookahead == 'n') + { + skip(lexer); + if (!iswidentifier(lexer->lookahead)) + return false; + } + + // Don't insert a semicolon before `as` (unless it's part of an identifier) + case 'a': + skip(lexer); + if (lexer->lookahead == 's') + { + skip(lexer); + if (!iswidentifier(lexer->lookahead)) + return false; + } } return true; diff --git a/libs/tree-sitter-wing/test/corpus/expressions.txt b/libs/tree-sitter-wing/test/corpus/expressions.txt index f04eca2346a..abddffe1961 100644 --- a/libs/tree-sitter-wing/test/corpus/expressions.txt +++ b/libs/tree-sitter-wing/test/corpus/expressions.txt @@ -158,6 +158,28 @@ new A() as "b" in c; -------------------------------------------------------------------------------- +(source + (expression_statement + (new_expression + class: (custom_type + object: (type_identifier)) + args: (argument_list) + id: (string) + scope: (reference + (reference_identifier))))) + +================================================================================ +New expression with id and scope on different lines +================================================================================ + +new A() + as + "b" + in + c; + +-------------------------------------------------------------------------------- + (source (expression_statement (new_expression