From 1980a3efc3f318cd39507781848c0fd876bc954b Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 1 Sep 2021 11:08:38 +0200 Subject: [PATCH 001/133] Adjust readme to scoped package name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e80270f..89fd6a1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# lezer-javascript +# @lezer/javascript This is a JavaScript grammar for the [lezer](https://lezer.codemirror.net/) parser system. From c95e9c3fb13de3da1834311de4c86bb86dcf5a11 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 3 Sep 2021 08:59:30 +0200 Subject: [PATCH 002/133] Implement override TypeScript keyword FEATURE: Recognize TypeScript 4.3's `override` keyword. --- src/javascript.grammar | 1 + test/statement.txt | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index e998e6e..a6078f8 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -134,6 +134,7 @@ privacyArg { MethodDeclaration[group=ClassItem] { privacy? (pkwMod<"static"> | tsPkwMod<"abstract">)? + pkwMod<"override">? pkwMod<"async">? (pkwMod<"get"> | pkwMod<"set"> | Star)? PropertyNameDefinition diff --git a/test/statement.txt b/test/statement.txt index c8fd5b0..4612101 100644 --- a/test/statement.txt +++ b/test/statement.txt @@ -176,6 +176,7 @@ class Foo { class Foo extends require('another-class') { constructor() { super(); } bar() { super.a(); } + override baz() {} } ==> @@ -187,7 +188,8 @@ Script( MethodDeclaration(PropertyNameDefinition,ParamList,Block))), ClassDeclaration(class,VariableDefinition,extends,CallExpression(VariableName,ArgList(String)),ClassBody( MethodDeclaration(PropertyNameDefinition,ParamList,Block(ExpressionStatement(CallExpression(super,ArgList)))), - MethodDeclaration(PropertyNameDefinition,ParamList,Block(ExpressionStatement(CallExpression(MemberExpression(super,PropertyName),ArgList))))))) + MethodDeclaration(PropertyNameDefinition,ParamList,Block(ExpressionStatement(CallExpression(MemberExpression(super,PropertyName),ArgList)))), + MethodDeclaration(override, PropertyNameDefinition,ParamList,Block)))) # Imports From bd3a39830fca48b2382e0bdcb5c0e63198fed121 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 3 Nov 2021 12:30:06 +0100 Subject: [PATCH 003/133] Support TypeScript per-name type imports FIX: Add support for TypeScript `import {type X} from y` syntax. --- src/javascript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index a6078f8..499a41e 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -78,7 +78,7 @@ ImportDeclaration { } ImportGroup { - "{" commaSep VariableDefinition> "}" + "{" commaSep? (VariableDefinition | VariableName ckw<"as"> VariableDefinition)> "}" } ForSpec { From c6888eee80c8f9e5529d171112fe91d68ac07808 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 12 Nov 2021 13:48:53 +0100 Subject: [PATCH 004/133] Support private fields and clean up indexed types FIX: Indexed TypeScript types can now take type parameters. FIX: Add support for private field syntax. --- src/javascript.grammar | 26 ++++++++++++++++++-------- test/statement.txt | 25 +++++++++++++++++++++++-- test/typescript.txt | 10 ++++++++++ 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 499a41e..b8945fa 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -134,10 +134,10 @@ privacyArg { MethodDeclaration[group=ClassItem] { privacy? (pkwMod<"static"> | tsPkwMod<"abstract">)? - pkwMod<"override">? + tsPkwMod<"override">? pkwMod<"async">? (pkwMod<"get"> | pkwMod<"set"> | Star)? - PropertyNameDefinition + (PropertyNameDefinition | PrivatePropertyDefinition) functionSignature Block } @@ -146,7 +146,7 @@ PropertyDeclaration[group=ClassItem] { privacy? (pkwMod<"static"> | tsPkwMod<"abstract">)? pkwMod<"readonly">? - PropertyNameDefinition + (PropertyNameDefinition | PrivatePropertyDefinition) (Optional | LogicOp<"!">)? TypeAnnotation? ("=" expressionNoComma)? @@ -188,7 +188,7 @@ AmbientDeclaration { ClassBody { "{" ( MethodDeclaration { privacy? (pkwMod<"static"> | tsPkwMod<"abstract">)? pkwMod<"async">? (pkwMod<"get"> | pkwMod<"set"> | Star)? - PropertyNameDefinition TypeParamList? ParamList (TypeAnnotation | TypePredicate) semi + (PropertyNameDefinition | PrivatePropertyDefinition) TypeParamList? ParamList (TypeAnnotation | TypePredicate) semi } | PropertyDeclaration | IndexSignature @@ -331,7 +331,7 @@ AssignmentExpression { } MemberExpression { - expressionNoComma !member (("." | "?.") PropertyName | "[" expression "]") + expressionNoComma !member (("." | "?.") (PropertyName | PrivatePropertyName) | "[" expression "]") } ArgList { @@ -373,7 +373,7 @@ type[@isGroup=Type] { ParenthesizedType { "(" type ")" } | FunctionSignature { ParamTypeList "=>" type } | NewSignature { kw<"new"> ParamTypeList "=>" type } | - IndexedType { type !typeMember ("." PropertyName | "[" (String | Number) "]")+ } | + IndexedType | TupleType { "[" commaSep<(Label ":")? type | "..." type> "]" } | ArrayType { type "[" "]" | type "[" "]" } | ReadonlyType { tskw<"readonly"> !readonly type } | @@ -381,10 +381,14 @@ type[@isGroup=Type] { UnionType { type !union LogicOp { "|" } type } | IntersectionType { type !intersection LogicOp { "&" } type } | ConditionalType { type !typeTernary questionOp ~arrow type LogicOp<":"> type } | - ParameterizedType { TypeName !typeargs TypeArgList } | + ParameterizedType { (TypeName | IndexedType) !typeargs TypeArgList } | TypeName } +IndexedType { + type !typeMember ("." TypeName | "[" (String | Number) "]")+ +} + ObjectType { "{" ( MethodType | @@ -518,6 +522,10 @@ PropertyName { word } PropertyNameDefinition { word } +PrivatePropertyName { privateIdentifier } + +PrivatePropertyDefinition { privateIdentifier } + Optional { "?" } questionOp[@name=LogicOp] { "?" } @@ -526,7 +534,7 @@ questionOp[@name=LogicOp] { "?" } @context trackNewline from "./tokens.js" -@external extend { identifier } tsExtends from "./tokens" { TSExtends[@name=extends] } +@external specialize { identifier } tsExtends from "./tokens" { TSExtends[@name=extends] } @external tokens noSemicolon from "./tokens" { noSemi } @@ -566,6 +574,8 @@ questionOp[@name=LogicOp] { "?" } identifier { word } + privateIdentifier { "#" word } + @precedence { spaces, newline, identifier } @precedence { spaces, newline, JSXIdentifier } diff --git a/test/statement.txt b/test/statement.txt index 4612101..1042fa1 100644 --- a/test/statement.txt +++ b/test/statement.txt @@ -176,7 +176,8 @@ class Foo { class Foo extends require('another-class') { constructor() { super(); } bar() { super.a(); } - override baz() {} + prop; + etc = 20; } ==> @@ -189,7 +190,27 @@ Script( ClassDeclaration(class,VariableDefinition,extends,CallExpression(VariableName,ArgList(String)),ClassBody( MethodDeclaration(PropertyNameDefinition,ParamList,Block(ExpressionStatement(CallExpression(super,ArgList)))), MethodDeclaration(PropertyNameDefinition,ParamList,Block(ExpressionStatement(CallExpression(MemberExpression(super,PropertyName),ArgList)))), - MethodDeclaration(override, PropertyNameDefinition,ParamList,Block)))) + PropertyDeclaration(PropertyNameDefinition), + PropertyDeclaration(PropertyNameDefinition,Equals,Number)))) + +# Private properties + +class Foo { + #bar() { this.#a() + this?.#prop; } + #prop; + #etc = 20; +} + +==> + +Script(ClassDeclaration(class,VariableDefinition,ClassBody( + MethodDeclaration(PrivatePropertyDefinition,ParamList,Block( + ExpressionStatement(BinaryExpression( + CallExpression(MemberExpression(this,PrivatePropertyName),ArgList), + ArithOp, + MemberExpression(this,PrivatePropertyName))))), + PropertyDeclaration(PrivatePropertyDefinition), + PropertyDeclaration(PrivatePropertyDefinition,Equals,Number)))) # Imports diff --git a/test/typescript.txt b/test/typescript.txt index a3cb464..f1f0918 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -149,3 +149,13 @@ type Tmpl = `${string} ${5}` | `one ${Two}` Script(TypeAliasDeclaration(type, TypeDefinition, TypeParamList(TypeDefinition), Equals, UnionType(TemplateType(TypeName, LiteralType(Number)), LogicOp, TemplateType(TypeName)))) + +# Extending complex types {"dialect": "ts"} + +class Foo extends A.B {} + +==> + +Script(ClassDeclaration(class, VariableDefinition, + extends, ParameterizedType(IndexedType(TypeName, TypeName), TypeArgList(TypeName)), + ClassBody)) From 23b297287c00a03236c2930077637a65293f8ed0 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 12 Nov 2021 13:54:47 +0100 Subject: [PATCH 005/133] Rename PropertyNameDefinition -> PropertyDefinition for consistency FIX: Rename PropertyNameDefinition node to PropertyDefinition for consistency with other names. --- src/javascript.grammar | 18 +++++++++--------- test/expression.txt | 40 ++++++++++++++++++++-------------------- test/statement.txt | 16 ++++++++-------- test/typescript.txt | 14 +++++++------- 4 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index b8945fa..55d3079 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -137,7 +137,7 @@ MethodDeclaration[group=ClassItem] { tsPkwMod<"override">? pkwMod<"async">? (pkwMod<"get"> | pkwMod<"set"> | Star)? - (PropertyNameDefinition | PrivatePropertyDefinition) + (PropertyDefinition | PrivatePropertyDefinition) functionSignature Block } @@ -146,7 +146,7 @@ PropertyDeclaration[group=ClassItem] { privacy? (pkwMod<"static"> | tsPkwMod<"abstract">)? pkwMod<"readonly">? - (PropertyNameDefinition | PrivatePropertyDefinition) + (PropertyDefinition | PrivatePropertyDefinition) (Optional | LogicOp<"!">)? TypeAnnotation? ("=" expressionNoComma)? @@ -170,7 +170,7 @@ EnumDeclaration { } NamespaceDeclaration { - (tskw<"namespace"> | tskw<"module">) VariableDefinition ("." PropertyNameDefinition)* Block + (tskw<"namespace"> | tskw<"module">) VariableDefinition ("." PropertyDefinition)* Block } AmbientDeclaration { @@ -188,7 +188,7 @@ AmbientDeclaration { ClassBody { "{" ( MethodDeclaration { privacy? (pkwMod<"static"> | tsPkwMod<"abstract">)? pkwMod<"async">? (pkwMod<"get"> | pkwMod<"set"> | Star)? - (PropertyNameDefinition | PrivatePropertyDefinition) TypeParamList? ParamList (TypeAnnotation | TypePredicate) semi + (PropertyDefinition | PrivatePropertyDefinition) TypeParamList? ParamList (TypeAnnotation | TypePredicate) semi } | PropertyDeclaration | IndexSignature @@ -280,7 +280,7 @@ ArrayExpression { "[" commaSep1<"..."? expressionNoComma | ""> ~destructure "]" } -propName { PropertyNameDefinition | "[" expression "]" | Number | String } +propName { PropertyDefinition | "[" expression "]" | Number | String } Property { pkwMod<"async">? (pkwMod<"get"> | pkwMod<"set"> | Star)? propName functionSignature Block | @@ -401,20 +401,20 @@ ObjectType { } IndexSignature { - pkwMod<"readonly">? "[" PropertyNameDefinition (TypeAnnotation | kw<"in"> type) "]" TypeAnnotation semi + pkwMod<"readonly">? "[" PropertyDefinition (TypeAnnotation | kw<"in"> type) "]" TypeAnnotation semi } MethodType { pkwMod<"async">? (pkwMod<"get"> | pkwMod<"set"> | Star)? - PropertyNameDefinition + PropertyDefinition functionSignature semi } PropertyType { (ArithOp<"+" | "-">? pkwMod<"readonly">)? - PropertyNameDefinition + PropertyDefinition (ArithOp<"+" | "-">? Optional)? TypeAnnotation semi @@ -520,7 +520,7 @@ Label { identifier } PropertyName { word } -PropertyNameDefinition { word } +PropertyDefinition { word } PrivatePropertyName { privateIdentifier } diff --git a/test/expression.txt b/test/expression.txt index 438b2d9..5631aba 100644 --- a/test/expression.txt +++ b/test/expression.txt @@ -156,8 +156,8 @@ Script( ==> Script(ExpressionStatement(ParenthesizedExpression(ObjectExpression( - Property(PropertyNameDefinition,ArrowFunction(ParamList,Arrow,Number)), - Property(PropertyNameDefinition,String))))) + Property(PropertyDefinition,ArrowFunction(ParamList,Arrow,Number)), + Property(PropertyDefinition,String))))) # Long potential arrow function @@ -368,11 +368,11 @@ foo({}, Script(ExpressionStatement(CallExpression(VariableName,ArgList( ObjectExpression, - ObjectExpression(Property(PropertyNameDefinition,String)), - ObjectExpression(Property(PropertyNameDefinition,String),Property(String,VariableName),Property(Number,Number)), - ObjectExpression(Property(PropertyNameDefinition),Property(VariableName,ParamList,Block)), - ObjectExpression(Property(PropertyNameDefinition),Property(PropertyNameDefinition)), - ObjectExpression(Property(PropertyNameDefinition)))))) + ObjectExpression(Property(PropertyDefinition,String)), + ObjectExpression(Property(PropertyDefinition,String),Property(String,VariableName),Property(Number,Number)), + ObjectExpression(Property(PropertyDefinition),Property(VariableName,ParamList,Block)), + ObjectExpression(Property(PropertyDefinition),Property(PropertyDefinition)), + ObjectExpression(Property(PropertyDefinition)))))) # Method definitions @@ -395,14 +395,14 @@ Script(ExpressionStatement(CallExpression(VariableName,ArgList( ==> Script(ExpressionStatement(ParenthesizedExpression(ObjectExpression( - Property(PropertyNameDefinition,BooleanLiteral), - Property(PropertyNameDefinition,ParamList(VariableDefinition,VariableDefinition), + Property(PropertyDefinition,BooleanLiteral), + Property(PropertyDefinition,ParamList(VariableDefinition,VariableDefinition), Block(ReturnStatement(return,BinaryExpression(VariableName,ArithOp,VariableName)))), - Property(get,PropertyNameDefinition,ParamList,Block(ReturnStatement(return,VariableName))), - Property(set,PropertyNameDefinition,ParamList(VariableDefinition), + Property(get,PropertyDefinition,ParamList,Block(ReturnStatement(return,VariableName))), + Property(set,PropertyDefinition,ParamList(VariableDefinition), Block(ExpressionStatement(AssignmentExpression(VariableName,Equals,VariableName)))), - Property(Star,PropertyNameDefinition,ParamList,Block(ExpressionStatement(UnaryExpression(yield,VariableName)))), - Property(PropertyNameDefinition,ParamList,Block(ReturnStatement(return,Number))))))) + Property(Star,PropertyDefinition,ParamList,Block(ExpressionStatement(UnaryExpression(yield,VariableName)))), + Property(PropertyDefinition,ParamList,Block(ReturnStatement(return,Number))))))) # Keyword property names @@ -418,12 +418,12 @@ Script(ExpressionStatement(ParenthesizedExpression(ObjectExpression( ==> Script(ExpressionStatement(ParenthesizedExpression(ObjectExpression( - Property(PropertyNameDefinition,ParamList,Block), - Property(PropertyNameDefinition,ParamList,Block), - Property(PropertyNameDefinition,FunctionExpression(function,ParamList,Block)), - Property(PropertyNameDefinition,ParamList,Block), - Property(PropertyNameDefinition,BooleanLiteral), - Property(PropertyNameDefinition,BooleanLiteral))))) + Property(PropertyDefinition,ParamList,Block), + Property(PropertyDefinition,ParamList,Block), + Property(PropertyDefinition,FunctionExpression(function,ParamList,Block)), + Property(PropertyDefinition,ParamList,Block), + Property(PropertyDefinition,BooleanLiteral), + Property(PropertyDefinition,BooleanLiteral))))) # Generator functions @@ -642,7 +642,7 @@ c = {d: (3, 4 + 5)}; Script( ExpressionStatement(SequenceExpression(AssignmentExpression(VariableName,Equals,Number),AssignmentExpression(VariableName,Equals,Number))), ExpressionStatement(AssignmentExpression(VariableName,Equals,ObjectExpression( - Property(PropertyNameDefinition,ParenthesizedExpression(SequenceExpression(Number,BinaryExpression(Number,ArithOp,Number)))))))) + Property(PropertyDefinition,ParenthesizedExpression(SequenceExpression(Number,BinaryExpression(Number,ArithOp,Number)))))))) # Punctuation diff --git a/test/statement.txt b/test/statement.txt index 1042fa1..aecc7b6 100644 --- a/test/statement.txt +++ b/test/statement.txt @@ -34,7 +34,7 @@ async (a) => { return foo; }; Script( FunctionDeclaration(async,function,VariableDefinition,ParamList,Block), - ClassDeclaration(class,VariableDefinition,ClassBody(MethodDeclaration(async,PropertyNameDefinition,ParamList,Block))), + ClassDeclaration(class,VariableDefinition,ClassBody(MethodDeclaration(async,PropertyDefinition,ParamList,Block))), ExpressionStatement(ArrowFunction(async,ParamList(VariableDefinition),Arrow,Block(ReturnStatement(return,VariableName))))) # If statements @@ -184,14 +184,14 @@ class Foo extends require('another-class') { Script( ClassDeclaration(class,VariableDefinition,ClassBody( - MethodDeclaration(static,PropertyNameDefinition,ParamList(VariableDefinition),Block(ReturnStatement(return,VariableName))), - MethodDeclaration(PropertyNameDefinition,ParamList(VariableDefinition),Block(ReturnStatement(return,VariableName))), - MethodDeclaration(PropertyNameDefinition,ParamList,Block))), + MethodDeclaration(static,PropertyDefinition,ParamList(VariableDefinition),Block(ReturnStatement(return,VariableName))), + MethodDeclaration(PropertyDefinition,ParamList(VariableDefinition),Block(ReturnStatement(return,VariableName))), + MethodDeclaration(PropertyDefinition,ParamList,Block))), ClassDeclaration(class,VariableDefinition,extends,CallExpression(VariableName,ArgList(String)),ClassBody( - MethodDeclaration(PropertyNameDefinition,ParamList,Block(ExpressionStatement(CallExpression(super,ArgList)))), - MethodDeclaration(PropertyNameDefinition,ParamList,Block(ExpressionStatement(CallExpression(MemberExpression(super,PropertyName),ArgList)))), - PropertyDeclaration(PropertyNameDefinition), - PropertyDeclaration(PropertyNameDefinition,Equals,Number)))) + MethodDeclaration(PropertyDefinition,ParamList,Block(ExpressionStatement(CallExpression(super,ArgList)))), + MethodDeclaration(PropertyDefinition,ParamList,Block(ExpressionStatement(CallExpression(MemberExpression(super,PropertyName),ArgList)))), + PropertyDeclaration(PropertyDefinition), + PropertyDeclaration(PropertyDefinition,Equals,Number)))) # Private properties diff --git a/test/typescript.txt b/test/typescript.txt index f1f0918..796976d 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -48,11 +48,11 @@ interface Foo { ==> Script(InterfaceDeclaration(interface, TypeDefinition, ObjectType( - PropertyType(readonly, PropertyNameDefinition, TypeAnnotation(TypeName)), - MethodType(PropertyNameDefinition, ParamList(VariableDefinition, TypeAnnotation(TypeName)), TypeAnnotation(VoidType(void))), + PropertyType(readonly, PropertyDefinition, TypeAnnotation(TypeName)), + MethodType(PropertyDefinition, ParamList(VariableDefinition, TypeAnnotation(TypeName)), TypeAnnotation(VoidType(void))), CallSignature(ParamList(VariableDefinition, TypeAnnotation(TypeName)), TypeAnnotation(TypeName)), NewSignature(new,ParamList, TypeAnnotation(TypeName)), - IndexSignature(readonly, PropertyNameDefinition, TypeAnnotation(TypeName), TypeAnnotation(TypeName))))) + IndexSignature(readonly, PropertyDefinition, TypeAnnotation(TypeName), TypeAnnotation(TypeName))))) # Call type args {"dialect": "ts"} @@ -120,13 +120,13 @@ Script(ClassDeclaration( extends ParameterizedType(TypeName, TypeArgList(TypeName)), implements TypeName, ClassBody( - PropertyDeclaration(PropertyNameDefinition, TypeAnnotation(TypeName)), - PropertyDeclaration(Privacy, readonly, PropertyNameDefinition, TypeAnnotation(TypeName), Equals, String), - MethodDeclaration(PropertyNameDefinition, ParamList( + PropertyDeclaration(PropertyDefinition, TypeAnnotation(TypeName)), + PropertyDeclaration(Privacy, readonly, PropertyDefinition, TypeAnnotation(TypeName), Equals, String), + MethodDeclaration(PropertyDefinition, ParamList( readonly, VariableDefinition, TypeAnnotation(TypeName), Privacy, VariableDefinition, TypeAnnotation(TypeName), VariableDefinition, TypeAnnotation(TypeName)), Block), - MethodDeclaration(Privacy, static, PropertyNameDefinition, ParamList, TypeAnnotation(VoidType(void)), Block)))) + MethodDeclaration(Privacy, static, PropertyDefinition, ParamList, TypeAnnotation(VoidType(void)), Block)))) # Arrow with type params {"dialect": "ts"} From d8248bf0ec4835fe69c72c4cbe3efaae2faba37a Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 12 Nov 2021 13:55:36 +0100 Subject: [PATCH 006/133] Mark version 0.15.1 --- CHANGELOG.md | 16 ++++++++++++++++ package.json | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d93f54..3bd35b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +## 0.15.1 (2021-11-12) + +### Bug fixes + +Add support for TypeScript `import {type X} from y` syntax. + +Indexed TypeScript types can now take type parameters. + +Add support for private field syntax. + +Rename PropertyNameDefinition node to PropertyDefinition for consistency with other names. + +### New features + +Recognize TypeScript 4.3's `override` keyword. + ## 0.15.0 (2021-08-11) ### Breaking changes diff --git a/package.json b/package.json index 4adfe6e..6c2a95f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "0.15.0", + "version": "0.15.1", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From a0de8e7fc107f795c58bd38db18b339a31d009cf Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 18 Nov 2021 09:41:50 +0100 Subject: [PATCH 007/133] Add support for '#x in y' syntax --- src/javascript.grammar | 3 ++- test/statement.txt | 13 ++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 55d3079..9ad99a8 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -314,7 +314,8 @@ BinaryExpression { expressionNoComma !times (divide | ArithOp<"%"> | ArithOp<"*">) expressionNoComma | expressionNoComma !plus ArithOp<"+" | "-"> expressionNoComma | expressionNoComma !shift BitOp<">>" ">"? | "<<"> expressionNoComma | - expressionNoComma !rel (LessThan | CompareOp<"<=" | ">" "="?> | kw<"in"> | kw<"instanceof">) expressionNoComma | + expressionNoComma !rel (LessThan | CompareOp<"<=" | ">" "="?> | kw<"instanceof">) expressionNoComma | + (expressionNoComma | PrivatePropertyName) !rel kw<"in"> expressionNoComma | expressionNoComma !rel ckw<"as"> (kw<"const"> | type) | expressionNoComma !equal CompareOp<"==" "="? | "!=" "="?> expressionNoComma | expressionNoComma !bitOr BitOp { "|" } expressionNoComma | diff --git a/test/statement.txt b/test/statement.txt index aecc7b6..d9f1b72 100644 --- a/test/statement.txt +++ b/test/statement.txt @@ -196,7 +196,7 @@ Script( # Private properties class Foo { - #bar() { this.#a() + this?.#prop; } + #bar() { this.#a() + this?.#prop == #prop in this; } #prop; #etc = 20; } @@ -206,9 +206,12 @@ class Foo { Script(ClassDeclaration(class,VariableDefinition,ClassBody( MethodDeclaration(PrivatePropertyDefinition,ParamList,Block( ExpressionStatement(BinaryExpression( - CallExpression(MemberExpression(this,PrivatePropertyName),ArgList), - ArithOp, - MemberExpression(this,PrivatePropertyName))))), + BinaryExpression( + CallExpression(MemberExpression(this,PrivatePropertyName),ArgList), + ArithOp, + MemberExpression(this,PrivatePropertyName)), + CompareOp, + BinaryExpression(PrivatePropertyName, in, this))))), PropertyDeclaration(PrivatePropertyDefinition), PropertyDeclaration(PrivatePropertyDefinition,Equals,Number)))) @@ -294,7 +297,7 @@ Script( # Recover from invalid char -const {foo#bar} = {}; +const {foobar} = {}; ==> From 4a6798aa16df8b6ded6f331c8408910e06ae5b54 Mon Sep 17 00:00:00 2001 From: Ashton Date: Wed, 24 Nov 2021 08:51:32 +0000 Subject: [PATCH 008/133] Fix node name of TaggedTemplateExpression FIX: Fix a typo in the `TaggedTemplateExpression` node name. --- src/javascript.grammar | 2 +- test/expression.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 9ad99a8..b98ca66 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -264,7 +264,7 @@ expressionNoComma { AssignmentExpression | PostfixExpression { expressionNoComma !postfix (incdec | LogicOp<"!">) } | CallExpression { expressionNoComma !call TypeArgList? ArgList } | - TaggedTemplatExpression { expressionNoComma !taggedTemplate TemplateString } | + TaggedTemplateExpression { expressionNoComma !taggedTemplate TemplateString } | DynamicImport { kw<"import"> "(" expressionNoComma ")" } | ImportMeta { kw<"import"> "." PropertyName } | JSXElement | diff --git a/test/expression.txt b/test/expression.txt index 5631aba..2dd77fd 100644 --- a/test/expression.txt +++ b/test/expression.txt @@ -333,7 +333,7 @@ Script( ExpressionStatement(TemplateString(VariableName)), ExpressionStatement(TemplateString), ExpressionStatement(TemplateString(TemplateString(TemplateString))), - ExpressionStatement(TaggedTemplatExpression(VariableName,TemplateString(VariableName)))) + ExpressionStatement(TaggedTemplateExpression(VariableName,TemplateString(VariableName)))) # Atoms From 9f8087ac24eca24a79cb3e3227fb31f78e091af9 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 8 Dec 2021 18:09:44 +0100 Subject: [PATCH 009/133] Support n suffixes after non-decimal integers FIX: Add support for non-decimal bignum literals (). --- src/javascript.grammar | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index b98ca66..91f1da9 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -587,9 +587,9 @@ questionOp[@name=LogicOp] { "?" } (std.digit ("_" | std.digit)* ("." ("_" | std.digit)*)? | "." std.digit ("_" | std.digit)*) (("e" | "E") ("+" | "-")? ("_" | std.digit)+)? | std.digit ("_" | std.digit)* "n" | - "0x" (std.digit | $[a-fA-F] | "_")+ | - "0b" $[01_]+ | - "0o" $[0-7_]+ + "0x" (std.digit | $[a-fA-F] | "_")+ "n"? | + "0b" $[01_]+ "n"? | + "0o" $[0-7_]+ "n"? } String { From 920fc0902c22cd3a0ecd9ba37d994613e64dca9f Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 8 Dec 2021 18:18:25 +0100 Subject: [PATCH 010/133] Add support for static class blocks FIX: Add support for static class initialization blocks. --- src/javascript.grammar | 6 +++++- test/statement.txt | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 91f1da9..a45c690 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -120,7 +120,7 @@ ClassDeclaration { } ClassBody { - "{" (MethodDeclaration | PropertyDeclaration | ";")* "}" + "{" (MethodDeclaration | PropertyDeclaration | StaticBlock | ";")* "}" } privacy { @@ -142,6 +142,10 @@ MethodDeclaration[group=ClassItem] { Block } +StaticBlock[group=ClassItem] { + pkwMod<"static"> Block +} + PropertyDeclaration[group=ClassItem] { privacy? (pkwMod<"static"> | tsPkwMod<"abstract">)? diff --git a/test/statement.txt b/test/statement.txt index d9f1b72..036563e 100644 --- a/test/statement.txt +++ b/test/statement.txt @@ -178,6 +178,7 @@ class Foo extends require('another-class') { bar() { super.a(); } prop; etc = 20; + static { f() } } ==> @@ -191,7 +192,8 @@ Script( MethodDeclaration(PropertyDefinition,ParamList,Block(ExpressionStatement(CallExpression(super,ArgList)))), MethodDeclaration(PropertyDefinition,ParamList,Block(ExpressionStatement(CallExpression(MemberExpression(super,PropertyName),ArgList)))), PropertyDeclaration(PropertyDefinition), - PropertyDeclaration(PropertyDefinition,Equals,Number)))) + PropertyDeclaration(PropertyDefinition,Equals,Number), + StaticBlock(static, Block(ExpressionStatement(CallExpression(VariableName,ArgList))))))) # Private properties From bd5a11488a6f3ff6a315e4fa2e81812db47d1b91 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 8 Dec 2021 18:19:55 +0100 Subject: [PATCH 011/133] Mark version 0.15.2 --- CHANGELOG.md | 10 ++++++++++ package.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bd35b7..a083d5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## 0.15.2 (2021-12-08) + +### Bug fixes + +Fix a typo in the `TaggedTemplateExpression` node name. Support n suffixes after non-decimal integers + +Add support for non-decimal bignum literals (). + +Add support for static class initialization blocks. + ## 0.15.1 (2021-11-12) ### Bug fixes diff --git a/package.json b/package.json index 6c2a95f..c8ea610 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "0.15.1", + "version": "0.15.2", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From b9fa5da1af81f80d89d40a48dfb9caf5f5e392ac Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Sat, 1 Jan 2022 18:39:40 +0100 Subject: [PATCH 012/133] Properly parse array patterns with holes FIX: Support missing values in array pattern syntax. Closes https://github.com/codemirror/codemirror.next/issues/662 --- src/javascript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index a45c690..0ba12e5 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -206,7 +206,7 @@ AmbientDeclaration { pattern { VariableDefinition | ArrayPattern | ObjectPattern } -ArrayPattern { "[" commaSep<"..."? patternAssign> ~destructure "]" } +ArrayPattern { "[" commaSep<("..."? patternAssign)?> ~destructure "]" } ObjectPattern { "{" commaSep ~destructure "}" } From afdc2da19789486e8f42c966a2daddd54907614c Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 3 Jan 2022 14:45:35 +0100 Subject: [PATCH 013/133] Add support for quoted export name FIX: Support quoted module export names. --- src/javascript.grammar | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 0ba12e5..475a74f 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -60,7 +60,7 @@ statement[@isGroup=Statement] { } ExportDeclaration { - kw<"export"> Star (ckw<"as"> VariableName)? ckw<"from"> String semi | + kw<"export"> Star (ckw<"as"> (VariableName | String))? ckw<"from"> String semi | kw<"export"> kw<"default"> (FunctionDeclaration | ClassDeclaration | expression semi) | kw<"export"> tskw<"type">? declaration | kw<"export"> tskw<"type">? ExportGroup (ckw<"from"> String)? semi | @@ -68,7 +68,7 @@ ExportDeclaration { } ExportGroup { - "{" commaSep VariableName { word })?> "}" + "{" commaSep (VariableName { word } | String))?> "}" } ImportDeclaration { @@ -78,7 +78,7 @@ ImportDeclaration { } ImportGroup { - "{" commaSep? (VariableDefinition | VariableName ckw<"as"> VariableDefinition)> "}" + "{" commaSep? (VariableDefinition | (VariableName | String) ckw<"as"> VariableDefinition)> "}" } ForSpec { From 523af97d41c63b7600a9ffe68dcb7af2da7454ee Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 17 Jan 2022 11:34:34 +0100 Subject: [PATCH 014/133] Add tree structure for template string interpolations FEATURE: Template string interpolations now get their own nodes in the syntax tree. Issue https://github.com/codemirror/lang-javascript/pull/3 --- src/javascript.grammar | 8 ++++---- src/tokens.js | 4 ++-- test/expression.txt | 12 ++++++++---- test/typescript.txt | 2 +- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 475a74f..965f0a5 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -439,9 +439,9 @@ ParamTypeList[@name=ParamList] { } } -templateExpr { templateDollarBrace expression templateClosingBrace } +templateExpr[@name=Interpolation] { InterpolationStart expression InterpolationEnd } -templateType { templateDollarBrace type templateClosingBrace } +templateType[@name=Interpolation] { InterpolationStart type InterpolationEnd } @skip {} { JSXElement { @@ -550,7 +550,7 @@ questionOp[@name=LogicOp] { "?" } @external tokens template from "./tokens" { templateContent, - templateDollarBrace, + InterpolationStart[closedBy=InterpolationEnd], templateEnd } @@ -603,7 +603,7 @@ questionOp[@name=LogicOp] { "?" } templateStart { "`" } - templateClosingBrace { "}" } + InterpolationEnd[openedBy=InterpolationStart] { "}" } ArithOp { expr } LogicOp { expr } diff --git a/src/tokens.js b/src/tokens.js index 2445cce..7d2c614 100644 --- a/src/tokens.js +++ b/src/tokens.js @@ -2,7 +2,7 @@ expressed by lezer's built-in tokenizer. */ import {ExternalTokenizer, ContextTracker} from "@lezer/lr" -import {insertSemi, noSemi, incdec, incdecPrefix, templateContent, templateDollarBrace, templateEnd, +import {insertSemi, noSemi, incdec, incdecPrefix, templateContent, InterpolationStart, templateEnd, spaces, newline, BlockComment, LineComment, TSExtends, Dialect_ts} from "./parser.terms.js" @@ -57,7 +57,7 @@ export const template = new ExternalTokenizer(input => { else input.acceptToken(templateEnd, 1) break } else if (next == braceL && afterDollar) { - if (i == 1) input.acceptToken(templateDollarBrace, 1) + if (i == 1) input.acceptToken(InterpolationStart, 1) else input.acceptToken(templateContent, -1) break } else if (next == 10 /* "\n" */ && i) { diff --git a/test/expression.txt b/test/expression.txt index 2dd77fd..491bfd5 100644 --- a/test/expression.txt +++ b/test/expression.txt @@ -327,13 +327,17 @@ f`hi${there}`; Script( ExpressionStatement(TemplateString), ExpressionStatement(TemplateString), - ExpressionStatement(TemplateString(BinaryExpression(Number,ArithOp,Number),SequenceExpression(Number,Number))), + ExpressionStatement(TemplateString( + Interpolation(InterpolationStart,BinaryExpression(Number,ArithOp,Number),InterpolationEnd), + Interpolation(InterpolationStart,SequenceExpression(Number,Number),InterpolationEnd))), ExpressionStatement(TemplateString), ExpressionStatement(TemplateString), - ExpressionStatement(TemplateString(VariableName)), + ExpressionStatement(TemplateString(Interpolation(InterpolationStart,VariableName,InterpolationEnd))), ExpressionStatement(TemplateString), - ExpressionStatement(TemplateString(TemplateString(TemplateString))), - ExpressionStatement(TaggedTemplateExpression(VariableName,TemplateString(VariableName)))) + ExpressionStatement(TemplateString(Interpolation(InterpolationStart,TemplateString( + Interpolation(InterpolationStart,TemplateString,InterpolationEnd)),InterpolationEnd))), + ExpressionStatement(TaggedTemplateExpression(VariableName,TemplateString( + Interpolation(InterpolationStart,VariableName,InterpolationEnd))))) # Atoms diff --git a/test/typescript.txt b/test/typescript.txt index 796976d..eabd55a 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -148,7 +148,7 @@ type Tmpl = `${string} ${5}` | `one ${Two}` ==> Script(TypeAliasDeclaration(type, TypeDefinition, TypeParamList(TypeDefinition), Equals, - UnionType(TemplateType(TypeName, LiteralType(Number)), LogicOp, TemplateType(TypeName)))) + UnionType(TemplateType(Interpolation(InterpolationStart,TypeName,InterpolationEnd), Interpolation(InterpolationStart,LiteralType(Number),InterpolationEnd)), LogicOp, TemplateType(Interpolation(InterpolationStart,TypeName,InterpolationEnd))))) # Extending complex types {"dialect": "ts"} From 2a8c2eb03fe5ddefacd616a5b91de11749a51144 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 26 Jan 2022 08:36:26 +0100 Subject: [PATCH 015/133] Mark version 0.15.3 --- CHANGELOG.md | 12 ++++++++++++ package.json | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a083d5a..7fd9906 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.15.3 (2022-01-26) + +### Bug fixes + +Support missing values in array pattern syntax. + +Support quoted module export names. + +### New features + +Template string interpolations now get their own nodes in the syntax tree. + ## 0.15.2 (2021-12-08) ### Bug fixes diff --git a/package.json b/package.json index c8ea610..700c7b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "0.15.2", + "version": "0.15.3", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 909e1b4a0bb0b443e1ec57049ce5f3c1285e679a Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 27 Jan 2022 12:32:38 +0100 Subject: [PATCH 016/133] Add CatchClause and FinallyClause nodes FEATURE: Add `CatchClause` and `FinallyClause` nodes wrapping parts of `TryStatement`. --- src/javascript.grammar | 6 +++++- test/statement.txt | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 965f0a5..cf5f618 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -46,7 +46,11 @@ statement[@isGroup=Statement] { DoStatement { kw<"do"> statement kw<"while"> ParenthesizedExpression semi } | IfStatement { kw<"if"> ParenthesizedExpression statement (!else kw<"else"> statement)? } | SwitchStatement { kw<"switch"> ParenthesizedExpression SwitchBody { "{" switchItem* "}" } } | - TryStatement { kw<"try"> Block (kw<"catch"> ("(" pattern ")")? Block)? (kw<"finally"> Block)? } | + TryStatement { + kw<"try"> Block + CatchClause { kw<"catch"> ("(" pattern ")")? Block }? + FinallyClause { kw<"finally"> Block }? + } | ReturnStatement { kw<"return"> (noSemi expression)? semi } | ThrowStatement { kw<"throw"> expression semi } | BreakStatement { kw<"break"> (noSemi Label)? semi } | diff --git a/test/statement.txt b/test/statement.txt index 036563e..ebac997 100644 --- a/test/statement.txt +++ b/test/statement.txt @@ -97,10 +97,10 @@ try { 1; } catch (x) { 2; } finally { 3; } ==> Script( - TryStatement(try,Block(ThrowStatement(throw,NewExpression(new,VariableName))),catch,Block), + TryStatement(try,Block(ThrowStatement(throw,NewExpression(new,VariableName))),CatchClause(catch,Block)), TryStatement(try,Block(ExpressionStatement(Number)), - catch,VariableDefinition,Block(ExpressionStatement(Number)), - finally,Block(ExpressionStatement(Number)))) + CatchClause(catch,VariableDefinition,Block(ExpressionStatement(Number))), + FinallyClause(finally,Block(ExpressionStatement(Number))))) # Switch From 9f272142048342de132e93fbab6be36b33bb0ae1 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 8 Mar 2022 12:07:13 +0100 Subject: [PATCH 017/133] Allow comma separator in TS object types FIX: Allow commas as separators in TypeScript object type syntax. --- src/javascript.grammar | 16 +++++++--------- test/typescript.txt | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index cf5f618..ec9b0c0 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -400,17 +400,17 @@ IndexedType { ObjectType { "{" ( - MethodType | - PropertyType | - IndexSignature | - CallSignature { ParamTypeList (TypeAnnotation | TypePredicate) semi } | - NewSignature[@dynamicPrecedence=1] { @extend[@name=new] ParamTypeList TypeAnnotation semi } | - ";" + (MethodType | + PropertyType | + IndexSignature | + CallSignature { ParamTypeList (TypeAnnotation | TypePredicate) } | + NewSignature[@dynamicPrecedence=1] { @extend[@name=new] ParamTypeList TypeAnnotation }) + ("," | semi) )* "}" } IndexSignature { - pkwMod<"readonly">? "[" PropertyDefinition (TypeAnnotation | kw<"in"> type) "]" TypeAnnotation semi + pkwMod<"readonly">? "[" PropertyDefinition (TypeAnnotation | kw<"in"> type) "]" TypeAnnotation } MethodType { @@ -418,7 +418,6 @@ MethodType { (pkwMod<"get"> | pkwMod<"set"> | Star)? PropertyDefinition functionSignature - semi } PropertyType { @@ -426,7 +425,6 @@ PropertyType { PropertyDefinition (ArithOp<"+" | "-">? Optional)? TypeAnnotation - semi } ParamTypeList[@name=ParamList] { diff --git a/test/typescript.txt b/test/typescript.txt index eabd55a..f891d07 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -159,3 +159,18 @@ class Foo extends A.B {} Script(ClassDeclaration(class, VariableDefinition, extends, ParameterizedType(IndexedType(TypeName, TypeName), TypeArgList(TypeName)), ClassBody)) + +# Object type {"dialect": "ts"} + +type A = {a: number, b: number} +type B = {a: number; b: number;} + +==> + +Script( + TypeAliasDeclaration(type,TypeDefinition,Equals,ObjectType( + PropertyType(PropertyDefinition,TypeAnnotation(TypeName)), + PropertyType(PropertyDefinition,TypeAnnotation(TypeName)))), + TypeAliasDeclaration(type,TypeDefinition,Equals,ObjectType( + PropertyType(PropertyDefinition,TypeAnnotation(TypeName)), + PropertyType(PropertyDefinition,TypeAnnotation(TypeName))))) From 2637504ad33cfe4824348a39be1edf9b06912fa7 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 24 Mar 2022 09:02:38 +0100 Subject: [PATCH 018/133] Add highlighting information FEATURE: The parser now includes syntax highlighting information in its node types. --- package.json | 3 ++- src/highlight.js | 57 ++++++++++++++++++++++++++++++++++++++++++ src/javascript.grammar | 2 ++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 src/highlight.js diff --git a/package.json b/package.json index 700c7b1..853dc79 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "@rollup/plugin-node-resolve": "^9.0.0" }, "dependencies": { - "@lezer/lr": "^0.15.0" + "@lezer/lr": "^0.15.0", + "@lezer/highlight": "^0.15.0" }, "repository": { "type": "git", diff --git a/src/highlight.js b/src/highlight.js new file mode 100644 index 0000000..8479ce5 --- /dev/null +++ b/src/highlight.js @@ -0,0 +1,57 @@ +import {styleTags, tags as t} from "@lezer/highlight" + +export const jsHighlight = styleTags({ + "get set async static": t.modifier, + "for while do if else switch try catch finally return throw break continue default case": t.controlKeyword, + "in of await yield void typeof delete instanceof": t.operatorKeyword, + "let var const function class extends": t.definitionKeyword, + "import export from": t.moduleKeyword, + "with debugger as new": t.keyword, + TemplateString: t.special(t.string), + Super: t.atom, + BooleanLiteral: t.bool, + this: t.self, + null: t.null, + Star: t.modifier, + VariableName: t.variableName, + "CallExpression/VariableName TaggedTemplateExpression/VariableName": t.function(t.variableName), + VariableDefinition: t.definition(t.variableName), + Label: t.labelName, + PropertyName: t.propertyName, + PrivatePropertyName: t.special(t.propertyName), + "CallExpression/MemberExpression/PropertyName": t.function(t.propertyName), + "FunctionDeclaration/VariableDefinition": t.function(t.definition(t.variableName)), + "ClassDeclaration/VariableDefinition": t.definition(t.className), + PropertyDefinition: t.definition(t.propertyName), + PrivatePropertyDefinition: t.definition(t.special(t.propertyName)), + UpdateOp: t.updateOperator, + LineComment: t.lineComment, + BlockComment: t.blockComment, + Number: t.number, + String: t.string, + ArithOp: t.arithmeticOperator, + LogicOp: t.logicOperator, + BitOp: t.bitwiseOperator, + CompareOp: t.compareOperator, + RegExp: t.regexp, + Equals: t.definitionOperator, + "Arrow : Spread": t.punctuation, + "( )": t.paren, + "[ ]": t.squareBracket, + "{ }": t.brace, + "InterpolationStart InterpolationEnd": t.special(t.brace), + ".": t.derefOperator, + ", ;": t.separator, + + TypeName: t.typeName, + TypeDefinition: t.definition(t.typeName), + "type enum interface implements namespace module declare": t.definitionKeyword, + "abstract global Privacy readonly override": t.modifier, + "is keyof unique infer": t.operatorKeyword, + + JSXAttributeValue: t.attributeValue, + JSXText: t.content, + "JSXStartTag JSXStartCloseTag JSXSelfCloseEndTag JSXEndTag": t.angleBracket, + "JSXIdentifier JSXNameSpacedName": t.tagName, + "JSXAttribute/JSXIdentifier JSXAttribute/JSXNameSpacedName": t.attributeName +}) diff --git a/src/javascript.grammar b/src/javascript.grammar index ec9b0c0..219c3ce 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -646,4 +646,6 @@ questionOp[@name=LogicOp] { "?" } @external tokens insertSemicolon from "./tokens" { insertSemi } +@external propSource jsHighlight from "./highlight" + @detectDelim From b54a3af280d4781210cc618cae42f9116d8aa2fa Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 20 Apr 2022 15:09:49 +0200 Subject: [PATCH 019/133] Mark version 0.16.0 --- CHANGELOG.md | 16 ++++++++++++++++ package.json | 8 ++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fd9906..f36e8a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +## 0.16.0 (2022-04-20) + +### Breaking changes + +Move to 0.16 serialized parser format. + +### Bug fixes + +Allow commas as separators in TypeScript object type syntax. + +### New features + +Add `CatchClause` and `FinallyClause` nodes wrapping parts of `TryStatement`. + +The parser now includes syntax highlighting information in its node types. + ## 0.15.3 (2022-01-26) ### Bug fixes diff --git a/package.json b/package.json index 853dc79..e13127f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "0.15.3", + "version": "0.16.0", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", @@ -13,14 +13,14 @@ "author": "Marijn Haverbeke ", "license": "MIT", "devDependencies": { - "@lezer/generator": "^0.15.0", + "@lezer/generator": "^0.16.0", "mocha": "^9.0.1", "rollup": "^2.52.2", "@rollup/plugin-node-resolve": "^9.0.0" }, "dependencies": { - "@lezer/lr": "^0.15.0", - "@lezer/highlight": "^0.15.0" + "@lezer/lr": "^0.16.0", + "@lezer/highlight": "^0.16.0" }, "repository": { "type": "git", From 8ef45643798fbd6e58218a4434a43106bb5c36a8 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 6 Jun 2022 16:27:36 +0200 Subject: [PATCH 020/133] Mark version 1.0.0 --- CHANGELOG.md | 6 ++++++ package.json | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f36e8a3..c68363d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.0.0 (2022-06-06) + +### New features + +First stable version. + ## 0.16.0 (2022-04-20) ### Breaking changes diff --git a/package.json b/package.json index e13127f..0a81c27 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "0.16.0", + "version": "1.0.0", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", @@ -13,14 +13,14 @@ "author": "Marijn Haverbeke ", "license": "MIT", "devDependencies": { - "@lezer/generator": "^0.16.0", + "@lezer/generator": "^1.0.0", "mocha": "^9.0.1", "rollup": "^2.52.2", "@rollup/plugin-node-resolve": "^9.0.0" }, "dependencies": { - "@lezer/lr": "^0.16.0", - "@lezer/highlight": "^0.16.0" + "@lezer/lr": "^1.0.0", + "@lezer/highlight": "^1.0.0" }, "repository": { "type": "git", From 719f260acf76fb92bd5435c44a820654016afb80 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 27 Jun 2022 11:16:59 +0200 Subject: [PATCH 021/133] Fix parsing of TypeScript conditional types FIX: Fix parsing of TypeScript conditional types. Issue https://github.com/lezer-parser/javascript/issues/9 --- src/javascript.grammar | 6 +++--- src/tokens.js | 14 +++++++++++--- test/typescript.txt | 10 ++++++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 219c3ce..2078ee3 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -6,7 +6,7 @@ typePrefix, intersection @left, union @left, - typeTernary @right, + typeExtends @right, else @right, member, readonly, @@ -389,7 +389,7 @@ type[@isGroup=Type] { ObjectType | UnionType { type !union LogicOp { "|" } type } | IntersectionType { type !intersection LogicOp { "&" } type } | - ConditionalType { type !typeTernary questionOp ~arrow type LogicOp<":"> type } | + ConditionalType { type !typeExtends TSExtends type questionOp ~arrow type LogicOp<":"> type } | ParameterizedType { (TypeName | IndexedType) !typeargs TypeArgList } | TypeName } @@ -541,7 +541,7 @@ questionOp[@name=LogicOp] { "?" } @context trackNewline from "./tokens.js" -@external specialize { identifier } tsExtends from "./tokens" { TSExtends[@name=extends] } +@external tokens tsExtends from "./tokens" { TSExtends[@name=extends] } @external tokens noSemicolon from "./tokens" { noSemi } diff --git a/src/tokens.js b/src/tokens.js index 7d2c614..6b8cfc1 100644 --- a/src/tokens.js +++ b/src/tokens.js @@ -73,6 +73,14 @@ export const template = new ExternalTokenizer(input => { } }) -export function tsExtends(value, stack) { - return value == "extends" && stack.dialectEnabled(Dialect_ts) ? TSExtends : -1 -} +export const tsExtends = new ExternalTokenizer((input, stack) => { + if (input.next != 101 || !stack.dialectEnabled(Dialect_ts)) return + input.advance() + for (let i = 0; i < 6; i++) { + if (input.next != "xtends".charCodeAt(i)) return + input.advance() + } + if (input.next >= 57 && input.next <= 65 || input.next >= 48 && input.next <= 90 || + input.next == 95 || input.next >= 97 && input.next <= 122 || input.next > 160) return + input.acceptToken(TSExtends) +}) diff --git a/test/typescript.txt b/test/typescript.txt index f891d07..4b11bda 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -174,3 +174,13 @@ Script( TypeAliasDeclaration(type,TypeDefinition,Equals,ObjectType( PropertyType(PropertyDefinition,TypeAnnotation(TypeName)), PropertyType(PropertyDefinition,TypeAnnotation(TypeName))))) + +# Conditional Type {"dialect": "ts"} + +type X = T extends E ? number : A + +==> + +Script( + TypeAliasDeclaration(type,TypeDefinition,TypeParamList(TypeDefinition),Equals, + ConditionalType(TypeName,extends,TypeName,LogicOp,TypeName,LogicOp,TypeName))) From 8be1f259c3a7bb110d18282ff021643ea9f94884 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 27 Jun 2022 11:26:16 +0200 Subject: [PATCH 022/133] Allow type parameters in function types FIX: Support type parameters in TypeScript function type syntax. Issue https://github.com/lezer-parser/javascript/issues/9 --- src/javascript.grammar | 2 +- test/typescript.txt | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 2078ee3..49c02cd 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -380,7 +380,7 @@ type[@isGroup=Type] { ImportType { kw<"import"> "(" String ")" } | InferredType { tskw<"infer"> TypeName } | ParenthesizedType { "(" type ")" } | - FunctionSignature { ParamTypeList "=>" type } | + FunctionSignature { TypeParamList? ParamTypeList "=>" type } | NewSignature { kw<"new"> ParamTypeList "=>" type } | IndexedType | TupleType { "[" commaSep<(Label ":")? type | "..." type> "]" } | diff --git a/test/typescript.txt b/test/typescript.txt index 4b11bda..e732a5d 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -184,3 +184,13 @@ type X = T extends E ? number : A Script( TypeAliasDeclaration(type,TypeDefinition,TypeParamList(TypeDefinition),Equals, ConditionalType(TypeName,extends,TypeName,LogicOp,TypeName,LogicOp,TypeName))) + +# Generic Function Type {"dialect": "ts"} + +let f: () => T + +==> + +Script( + VariableDeclaration(let,VariableDefinition,TypeAnnotation( + FunctionSignature(TypeParamList(TypeDefinition),ParamList,Arrow,TypeName)))) From 386ab15e5440595890806a4205dd2c36bce368b2 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 27 Jun 2022 11:26:38 +0200 Subject: [PATCH 023/133] Mark version 1.0.1 --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c68363d..7541576 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.0.1 (2022-06-27) + +### Bug fixes + +Fix parsing of TypeScript conditional types. + +Support type parameters in TypeScript function type syntax. + ## 1.0.0 (2022-06-06) ### New features diff --git a/package.json b/package.json index 0a81c27..a2ff855 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.0.0", + "version": "1.0.1", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 3a9dae38307e646a5f5c5f23a97e8e1fb2d974d8 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 27 Jun 2022 18:01:40 +0200 Subject: [PATCH 024/133] Remove deprecated std. syntax --- src/javascript.grammar | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 49c02cd..ff6b520 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -575,9 +575,9 @@ questionOp[@name=LogicOp] { "?" } @precedence { BlockComment, LineComment, RegExp } - identifierChar { std.asciiLetter | $[_$\u{a1}-\u{10ffff}] } + identifierChar { @asciiLetter | $[_$\u{a1}-\u{10ffff}] } - word { identifierChar (identifierChar | std.digit)* } + word { identifierChar (identifierChar | @digit)* } identifier { word } @@ -590,10 +590,10 @@ questionOp[@name=LogicOp] { "?" } @precedence { spaces, newline, word } Number { - (std.digit ("_" | std.digit)* ("." ("_" | std.digit)*)? | "." std.digit ("_" | std.digit)*) - (("e" | "E") ("+" | "-")? ("_" | std.digit)+)? | - std.digit ("_" | std.digit)* "n" | - "0x" (std.digit | $[a-fA-F] | "_")+ "n"? | + (@digit ("_" | @digit)* ("." ("_" | @digit)*)? | "." @digit ("_" | @digit)*) + (("e" | "E") ("+" | "-")? ("_" | @digit)+)? | + @digit ("_" | @digit)* "n" | + "0x" (@digit | $[a-fA-F] | "_")+ "n"? | "0b" $[01_]+ "n"? | "0o" $[0-7_]+ "n"? } @@ -625,7 +625,7 @@ questionOp[@name=LogicOp] { "?" } "?." "." "," ";" ":" - JSXIdentifier { identifierChar (identifierChar | std.digit | "-")* } + JSXIdentifier { identifierChar (identifierChar | @digit | "-")* } JSXAttributeValue { '"' !["]* '"' | "'" ![']* "'" } From eacd7e4c6e4c4c2bc4808bdfa1d40085673600c7 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 21 Jul 2022 11:19:52 +0200 Subject: [PATCH 025/133] Fix highlighting tag for 'super' keyword FIX: Properly assign a highlighting tag to the `super` keyword. See https://discuss.codemirror.net/t/javascript-syntax-highlighting-tags/4740 --- src/highlight.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/highlight.js b/src/highlight.js index 8479ce5..1ce17b0 100644 --- a/src/highlight.js +++ b/src/highlight.js @@ -8,7 +8,7 @@ export const jsHighlight = styleTags({ "import export from": t.moduleKeyword, "with debugger as new": t.keyword, TemplateString: t.special(t.string), - Super: t.atom, + super: t.atom, BooleanLiteral: t.bool, this: t.self, null: t.null, From 4bc18299444b1726de2fc082e95f273d9f06eabc Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 21 Jul 2022 11:22:12 +0200 Subject: [PATCH 026/133] Tag arrows as function(punctuation) --- src/highlight.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/highlight.js b/src/highlight.js index 1ce17b0..0891048 100644 --- a/src/highlight.js +++ b/src/highlight.js @@ -35,7 +35,8 @@ export const jsHighlight = styleTags({ CompareOp: t.compareOperator, RegExp: t.regexp, Equals: t.definitionOperator, - "Arrow : Spread": t.punctuation, + Arrow: t.function(t.punctuation), + ": Spread": t.punctuation, "( )": t.paren, "[ ]": t.squareBracket, "{ }": t.brace, From bd511639e1bdf3b85ca97290c4e736188fbfa15b Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 21 Jul 2022 11:22:26 +0200 Subject: [PATCH 027/133] Mark version 1.0.2 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7541576..208da2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.0.2 (2022-07-21) + +### Bug fixes + +Properly assign a highlighting tag to the `super` keyword. + ## 1.0.1 (2022-06-27) ### Bug fixes diff --git a/package.json b/package.json index a2ff855..e39a9d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.0.1", + "version": "1.0.2", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 3bd6b9651d8f2f2569340587bc5e37c2dd1e41d6 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 4 Aug 2022 17:09:29 +0200 Subject: [PATCH 028/133] Add support for optional calls FEATURE: Add support for optional call syntax. --- src/javascript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index ff6b520..814783a 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -271,7 +271,7 @@ expressionNoComma { ConditionalExpression { expressionNoComma !ternary questionOp expressionNoComma LogicOp<":"> expressionNoComma } | AssignmentExpression | PostfixExpression { expressionNoComma !postfix (incdec | LogicOp<"!">) } | - CallExpression { expressionNoComma !call TypeArgList? ArgList } | + CallExpression { expressionNoComma !call "?."? TypeArgList? ArgList } | TaggedTemplateExpression { expressionNoComma !taggedTemplate TemplateString } | DynamicImport { kw<"import"> "(" expressionNoComma ")" } | ImportMeta { kw<"import"> "." PropertyName } | From 46bcdcba8ba6523371a4718e5fc4c6495bcd3732 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 4 Aug 2022 17:11:53 +0200 Subject: [PATCH 029/133] Also allow ?. before bracketed member derefs --- src/javascript.grammar | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 814783a..bda563e 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -271,7 +271,7 @@ expressionNoComma { ConditionalExpression { expressionNoComma !ternary questionOp expressionNoComma LogicOp<":"> expressionNoComma } | AssignmentExpression | PostfixExpression { expressionNoComma !postfix (incdec | LogicOp<"!">) } | - CallExpression { expressionNoComma !call "?."? TypeArgList? ArgList } | + CallExpression { expressionNoComma !call TypeArgList? "?."? ArgList } | TaggedTemplateExpression { expressionNoComma !taggedTemplate TemplateString } | DynamicImport { kw<"import"> "(" expressionNoComma ")" } | ImportMeta { kw<"import"> "." PropertyName } | @@ -340,7 +340,7 @@ AssignmentExpression { } MemberExpression { - expressionNoComma !member (("." | "?.") (PropertyName | PrivatePropertyName) | "[" expression "]") + expressionNoComma !member (("." | "?.") (PropertyName | PrivatePropertyName) | "?."? "[" expression "]") } ArgList { From 00173306dc20e2b1f364cc30b6de0398156e8f42 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 30 Sep 2022 08:57:11 +0200 Subject: [PATCH 030/133] Mark lower-case JSX element names with JSXBuiltin nodes FEATURE: Distinguish lower-case JSX element names syntactically, give them a `standard(tagName)` highlight tag. Issue https://github.com/codemirror/dev/issues/956 --- src/highlight.js | 3 ++- src/javascript.grammar | 12 +++++++----- test/jsx.txt | 8 ++++---- test/typescript.txt | 4 ++-- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/highlight.js b/src/highlight.js index 0891048..05c73d3 100644 --- a/src/highlight.js +++ b/src/highlight.js @@ -54,5 +54,6 @@ export const jsHighlight = styleTags({ JSXText: t.content, "JSXStartTag JSXStartCloseTag JSXSelfCloseEndTag JSXEndTag": t.angleBracket, "JSXIdentifier JSXNameSpacedName": t.tagName, - "JSXAttribute/JSXIdentifier JSXAttribute/JSXNameSpacedName": t.attributeName + "JSXAttribute/JSXIdentifier JSXAttribute/JSXNameSpacedName": t.attributeName, + "JSXBuiltin/JSXIdentifier": t.standard(t.tagName) }) diff --git a/src/javascript.grammar b/src/javascript.grammar index bda563e..fabf87e 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -462,17 +462,18 @@ JSXCloseTag { JSXStartCloseTag jsxElementName? JSXEndTag } jsxElementName { JSXIdentifier | + JSXBuiltin { JSXLowerIdentifier } | JSXNamespacedName | JSXMemberExpression } -JSXMemberExpression { (JSXMemberExpression | JSXIdentifier) "." JSXIdentifier } +JSXMemberExpression { (JSXMemberExpression | JSXIdentifier | JSXLowerIdentifier) "." (JSXIdentifier | JSXLowerIdentifier) } -JSXNamespacedName { (JSXIdentifier | JSXNamespacedName) ":" JSXIdentifier } +JSXNamespacedName { (JSXIdentifier | JSXNamespacedName | JSXLowerIdentifier) ":" (JSXIdentifier | JSXLowerIdentifier) } jsxAttribute { JSXSpreadAttribute { "{" "..." expression "}" } | - JSXAttribute { (JSXIdentifier | JSXNamespacedName) ("=" jsxAttributeValue)? } + JSXAttribute { (JSXIdentifier | JSXNamespacedName | JSXLowerIdentifier) ("=" jsxAttributeValue)? } } jsxAttributeValue { @@ -585,7 +586,7 @@ questionOp[@name=LogicOp] { "?" } @precedence { spaces, newline, identifier } - @precedence { spaces, newline, JSXIdentifier } + @precedence { spaces, newline, JSXIdentifier, JSXLowerIdentifier } @precedence { spaces, newline, word } @@ -625,7 +626,8 @@ questionOp[@name=LogicOp] { "?" } "?." "." "," ";" ":" - JSXIdentifier { identifierChar (identifierChar | @digit | "-")* } + JSXIdentifier { $[A-Z_$\u{a1}-\u{10ffff}] (identifierChar | @digit | "-")* } + JSXLowerIdentifier[@name=JSXIdentifier] { $[a-z] (identifierChar | @digit | "-")* } JSXAttributeValue { '"' !["]* '"' | "'" ![']* "'" } diff --git a/test/jsx.txt b/test/jsx.txt index 47e5eaf..837d939 100644 --- a/test/jsx.txt +++ b/test/jsx.txt @@ -4,7 +4,7 @@ ==> -Script(ExpressionStatement(JSXElement(JSXSelfClosingTag(JSXStartTag,JSXIdentifier,JSXSelfCloseEndTag)))) +Script(ExpressionStatement(JSXElement(JSXSelfClosingTag(JSXStartTag,JSXBuiltin(JSXIdentifier),JSXSelfCloseEndTag)))) # Regular element {"dialect": "jsx"} @@ -53,7 +53,7 @@ Script(ExpressionStatement(JSXElement( ==> Script(ExpressionStatement(JSXElement( - JSXOpenTag(JSXStartTag, JSXIdentifier, JSXEndTag), + JSXOpenTag(JSXStartTag, JSXBuiltin(JSXIdentifier), JSXEndTag), JSXElement( JSXOpenTag(JSXStartTag, JSXMemberExpression(JSXIdentifier, JSXIdentifier), JSXEndTag), JSXText, @@ -61,11 +61,11 @@ Script(ExpressionStatement(JSXElement( JSXEscape(VariableName), JSXText, JSXEscape(Spread, VariableName), - JSXCloseTag(JSXStartCloseTag, JSXIdentifier, JSXEndTag)))) + JSXCloseTag(JSXStartCloseTag, JSXBuiltin(JSXIdentifier), JSXEndTag)))) # Attributes {"dialect": "jsx"} - + ==> diff --git a/test/typescript.txt b/test/typescript.txt index e732a5d..e8da699 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -100,9 +100,9 @@ Script(ExpressionStatement(PrefixCast(TypeName, VariableName))) ==> Script(ExpressionStatement(JSXElement( - JSXOpenTag(JSXStartTag, JSXIdentifier, JSXEndTag), + JSXOpenTag(JSXStartTag, JSXBuiltin(JSXIdentifier), JSXEndTag), JSXText, - JSXCloseTag(JSXStartCloseTag, JSXIdentifier, JSXEndTag)))) + JSXCloseTag(JSXStartCloseTag, JSXBuiltin(JSXIdentifier), JSXEndTag)))) # Class definition {"dialect": "ts"} From b0e4877851231107fdefac8dce1097d1b9b9a603 Mon Sep 17 00:00:00 2001 From: Benedikt Meurer Date: Fri, 28 Oct 2022 10:15:32 +0200 Subject: [PATCH 031/133] Fix parsing of 'null' as type FIX: Fix parsing of 'null' as type in TypeScript. --- src/javascript.grammar | 5 +++-- test/typescript.txt | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index fabf87e..5acf53f 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -198,7 +198,7 @@ AmbientDeclaration { privacy? (pkwMod<"static"> | tsPkwMod<"abstract">)? pkwMod<"async">? (pkwMod<"get"> | pkwMod<"set"> | Star)? (PropertyDefinition | PrivatePropertyDefinition) TypeParamList? ParamList (TypeAnnotation | TypePredicate) semi } | - PropertyDeclaration | + PropertyDeclaration | IndexSignature )* "}" } } | @@ -373,6 +373,7 @@ type[@isGroup=Type] { String } | TemplateType | + NullType { kw<"null"> } | VoidType { kw<"void"> } | TypeofType { kw<"typeof"> (VariableName | typeofMemberExpression) } | KeyofType { !typePrefix tskw<"keyof"> type } | @@ -425,7 +426,7 @@ PropertyType { PropertyDefinition (ArithOp<"+" | "-">? Optional)? TypeAnnotation -} +} ParamTypeList[@name=ParamList] { "(" commaSep<"..."? VariableDefinition ~arrow Optional? ~arrow TypeAnnotation?> ")" diff --git a/test/typescript.txt b/test/typescript.txt index e8da699..fa236ff 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -1,3 +1,16 @@ +# Undefined and Null Type {"dialect": "ts"} + +let x: undefined +let y: null + +==> + +Script( + VariableDeclaration(let,VariableDefinition,TypeAnnotation( + TypeName)), + VariableDeclaration(let,VariableDefinition,TypeAnnotation( + NullType(null)))) + # Type declaration {"dialect": "ts"} function foo(a: number, b: "literal" | Map): RegExp[] {} From f1868bce357d80abfcb75c1b3f70a01bc5a50dd5 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 28 Oct 2022 12:16:20 +0200 Subject: [PATCH 032/133] Support computed properties in object destructuring patterns FIX: Allow computed properties in object destructuring patterns. Closes https://github.com/lezer-parser/javascript/issues/12 --- src/javascript.grammar | 3 ++- test/statement.txt | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 5acf53f..8647ea3 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -298,7 +298,8 @@ Property { PatternProperty { "..." patternAssign | - (PropertyName | Number | String) ~destructure (":" pattern)? ("=" expressionNoComma)? + ((PropertyName | Number | String) ~destructure (":" pattern)? | + ("[" expression "]" ~destructure ":" pattern)) ("=" expressionNoComma)? } ClassExpression { diff --git a/test/statement.txt b/test/statement.txt index ebac997..ec4ff62 100644 --- a/test/statement.txt +++ b/test/statement.txt @@ -321,3 +321,24 @@ function g() {} Script( FunctionDeclaration(function,VariableDefinition,ParamList,Block(ExpressionStatement(CallExpression(VariableName,ArgList(...))))), FunctionDeclaration(function,VariableDefinition,ParamList,Block)) + +# Destructuring + +({x} = y); +[u, v] = w; +let [a,, b = 0] = c; +let {x, y: z = 1} = d; +let {[f]: m} = e; + +==> + +Script( + ExpressionStatement(ParenthesizedExpression(AssignmentExpression( + ObjectPattern(PatternProperty(PropertyName)),Equals,VariableName))), + ExpressionStatement(AssignmentExpression(ArrayPattern(VariableDefinition,VariableDefinition),Equals,VariableName)), + VariableDeclaration(let,ArrayPattern(VariableDefinition,VariableDefinition,Equals,Number),Equals,VariableName), + VariableDeclaration(let,ObjectPattern( + PatternProperty(PropertyName), + PatternProperty(PropertyName,VariableDefinition,Equals,Number) + ),Equals,VariableName), + VariableDeclaration(let,ObjectPattern(PatternProperty(VariableName,VariableDefinition)),Equals,VariableName)) From 59c79b009f274d37759052aa3daea7ce5338145c Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 3 Nov 2022 13:02:33 +0100 Subject: [PATCH 033/133] Add support for TypeScript's satisfies operator FIX: Add TypeScript 4.9's `satisfies` operator. --- src/javascript.grammar | 2 ++ test/typescript.txt | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/src/javascript.grammar b/src/javascript.grammar index 8647ea3..4aa3ffb 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -22,6 +22,7 @@ shift @left, loop, rel @left, + satisfies, equal @left, bitOr @left, bitXor @left, @@ -324,6 +325,7 @@ BinaryExpression { expressionNoComma !plus ArithOp<"+" | "-"> expressionNoComma | expressionNoComma !shift BitOp<">>" ">"? | "<<"> expressionNoComma | expressionNoComma !rel (LessThan | CompareOp<"<=" | ">" "="?> | kw<"instanceof">) expressionNoComma | + expressionNoComma !satisfies tskw<"satisfies"> type | (expressionNoComma | PrivatePropertyName) !rel kw<"in"> expressionNoComma | expressionNoComma !rel ckw<"as"> (kw<"const"> | type) | expressionNoComma !equal CompareOp<"==" "="? | "!=" "="?> expressionNoComma | diff --git a/test/typescript.txt b/test/typescript.txt index fa236ff..4130396 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -207,3 +207,11 @@ let f: () => T Script( VariableDeclaration(let,VariableDefinition,TypeAnnotation( FunctionSignature(TypeParamList(TypeDefinition),ParamList,Arrow,TypeName)))) + +# Satisfies operator {"dialect": "ts"} + +let x = 1 satisfies number + +==> + +Script(VariableDeclaration(let,VariableDefinition,Equals,BinaryExpression(Number,satisfies,TypeName))) From 4e0ad7a4c88a47aae0ec1c2e2687ad7adfec2af7 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 3 Nov 2022 13:06:00 +0100 Subject: [PATCH 034/133] Add support for accessor syntax FIX: Support `accessor` syntax on class properties. --- src/javascript.grammar | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 4aa3ffb..586a30f 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -154,7 +154,7 @@ StaticBlock[group=ClassItem] { PropertyDeclaration[group=ClassItem] { privacy? (pkwMod<"static"> | tsPkwMod<"abstract">)? - pkwMod<"readonly">? + (tsPkwMod<"readonly"> | pkwMod<"accessor">)? (PropertyDefinition | PrivatePropertyDefinition) (Optional | LogicOp<"!">)? TypeAnnotation? @@ -414,7 +414,7 @@ ObjectType { } IndexSignature { - pkwMod<"readonly">? "[" PropertyDefinition (TypeAnnotation | kw<"in"> type) "]" TypeAnnotation + tsPkwMod<"readonly">? "[" PropertyDefinition (TypeAnnotation | kw<"in"> type) "]" TypeAnnotation } MethodType { @@ -425,7 +425,7 @@ MethodType { } PropertyType { - (ArithOp<"+" | "-">? pkwMod<"readonly">)? + (ArithOp<"+" | "-">? tsPkwMod<"readonly">)? PropertyDefinition (ArithOp<"+" | "-">? Optional)? TypeAnnotation From 52589851c13c465c6fea42c34b074a87e5e0c4c5 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 14 Nov 2022 14:48:28 +0100 Subject: [PATCH 035/133] Emit tokens for closing angle brackets of type argument lists --- src/javascript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 586a30f..16822af 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -626,7 +626,7 @@ questionOp[@name=LogicOp] { "?" } "..."[@name=Spread] "=>"[@name=Arrow] - "(" ")" "[" "]" "{" "}" + "(" ")" "[" "]" "{" "}" ">" "?." "." "," ";" ":" From 5912fc75576ed0826b0b7cb7b13753fae380d792 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 17 Nov 2022 14:36:38 +0100 Subject: [PATCH 036/133] Mark version 1.1.0 --- CHANGELOG.md | 18 ++++++++++++++++++ package.json | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 208da2b..0d60614 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +## 1.1.0 (2022-11-17) + +### Bug fixes + +Fix parsing of 'null' as type in TypeScript. + +Allow computed properties in object destructuring patterns. + +Add TypeScript 4.9's `satisfies` operator. + +Support `accessor` syntax on class properties. + +### New features + +Add support for optional call syntax. + +Distinguish lower-case JSX element names syntactically, give them a `standard(tagName)` highlight tag. + ## 1.0.2 (2022-07-21) ### Bug fixes diff --git a/package.json b/package.json index e39a9d0..88f7f39 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.0.2", + "version": "1.1.0", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 63fb2f79ea5876bf73ace8d8c5272be8b8a7abf6 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Sat, 19 Nov 2022 16:15:28 +0100 Subject: [PATCH 037/133] Add support for computed properties in class definitions FIX: Fix parsing of computed properties in class declarations. Closes https://github.com/lezer-parser/lezer/issues/31 --- src/javascript.grammar | 10 ++++++---- test/statement.txt | 13 +++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 16822af..0acb499 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -142,7 +142,7 @@ MethodDeclaration[group=ClassItem] { tsPkwMod<"override">? pkwMod<"async">? (pkwMod<"get"> | pkwMod<"set"> | Star)? - (PropertyDefinition | PrivatePropertyDefinition) + (propName | PrivatePropertyDefinition) functionSignature Block } @@ -155,7 +155,7 @@ PropertyDeclaration[group=ClassItem] { privacy? (pkwMod<"static"> | tsPkwMod<"abstract">)? (tsPkwMod<"readonly"> | pkwMod<"accessor">)? - (PropertyDefinition | PrivatePropertyDefinition) + (propName | PrivatePropertyDefinition) (Optional | LogicOp<"!">)? TypeAnnotation? ("=" expressionNoComma)? @@ -326,7 +326,7 @@ BinaryExpression { expressionNoComma !shift BitOp<">>" ">"? | "<<"> expressionNoComma | expressionNoComma !rel (LessThan | CompareOp<"<=" | ">" "="?> | kw<"instanceof">) expressionNoComma | expressionNoComma !satisfies tskw<"satisfies"> type | - (expressionNoComma | PrivatePropertyName) !rel kw<"in"> expressionNoComma | + (expressionNoComma | PrivatePropertyName) !rel ~tsIn kw<"in"> expressionNoComma | expressionNoComma !rel ckw<"as"> (kw<"const"> | type) | expressionNoComma !equal CompareOp<"==" "="? | "!=" "="?> expressionNoComma | expressionNoComma !bitOr BitOp { "|" } expressionNoComma | @@ -414,7 +414,7 @@ ObjectType { } IndexSignature { - tsPkwMod<"readonly">? "[" PropertyDefinition (TypeAnnotation | kw<"in"> type) "]" TypeAnnotation + tsPkwMod<"readonly">? "[" PropertyDefinition { identifier } (TypeAnnotation | ~tsIn kw<"in"> type) "]" TypeAnnotation } MethodType { @@ -603,6 +603,8 @@ questionOp[@name=LogicOp] { "?" } "0o" $[0-7_]+ "n"? } + @precedence { Number "." } + String { '"' (![\\\n"] | "\\" _)* '"'? | "'" (![\\\n'] | "\\" _)* "'"? diff --git a/test/statement.txt b/test/statement.txt index ec4ff62..27ee868 100644 --- a/test/statement.txt +++ b/test/statement.txt @@ -217,6 +217,19 @@ Script(ClassDeclaration(class,VariableDefinition,ClassBody( PropertyDeclaration(PrivatePropertyDefinition), PropertyDeclaration(PrivatePropertyDefinition,Equals,Number)))) +# Computed properties + +class Foo { + [x] = 44; + [Symbol.iterator]() {} +} + +==> + +Script(ClassDeclaration(class,VariableDefinition,ClassBody( + PropertyDeclaration(VariableName,Equals,Number), + MethodDeclaration(MemberExpression(VariableName,PropertyName),ParamList,Block)))) + # Imports import defaultMember from "module-name"; From 9e08c6dca8294b0dc9fa26c4167c7a78e236df1e Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Sat, 19 Nov 2022 16:15:35 +0100 Subject: [PATCH 038/133] Mark version 1.1.1 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d60614..ddf76fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.1.1 (2022-11-19) + +### Bug fixes + +Fix parsing of computed properties in class declarations. + ## 1.1.0 (2022-11-17) ### Bug fixes diff --git a/package.json b/package.json index 88f7f39..3248a53 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.1.0", + "version": "1.1.1", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 45071056dca5e0cee3946ba15f5b6633ac98ffb0 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 22 Nov 2022 14:58:20 +0100 Subject: [PATCH 039/133] Add SingleExpression top rule FEATURE: The grammar now supports `top: "SingleExpression"` to parse an expression rather than a script. Issue https://github.com/codemirror/dev/issues/1004 --- src/javascript.grammar | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/javascript.grammar b/src/javascript.grammar index 0acb499..bb8a41f 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -38,6 +38,8 @@ @top Script { statement+ } +@top SingleExpression { expression } + statement[@isGroup=Statement] { ExportDeclaration | ImportDeclaration | From 7f9d8000395ee5cf2e5ad7dc64cdb46eacca98e1 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 24 Nov 2022 11:13:31 +0100 Subject: [PATCH 040/133] Mark version 1.2.0 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ddf76fc..4a90842 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.2.0 (2022-11-24) + +### New features + +The grammar now supports `top: "SingleExpression"` to parse an expression rather than a script. + ## 1.1.1 (2022-11-19) ### Bug fixes diff --git a/package.json b/package.json index 3248a53..c4ca5d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.1.1", + "version": "1.2.0", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 6a410f39766c490c9c567bd6443f53ac46cd0758 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 28 Nov 2022 16:59:25 +0100 Subject: [PATCH 041/133] Add support for decorators Following TC39 syntax, with added support for TypeScript-style parameter decorators. FEATURE: Add support for decorator syntax. --- src/highlight.js | 1 + src/javascript.grammar | 17 +++++++++-- test/decorator.txt | 64 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 test/decorator.txt diff --git a/src/highlight.js b/src/highlight.js index 05c73d3..e37ce29 100644 --- a/src/highlight.js +++ b/src/highlight.js @@ -43,6 +43,7 @@ export const jsHighlight = styleTags({ "InterpolationStart InterpolationEnd": t.special(t.brace), ".": t.derefOperator, ", ;": t.separator, + "@": t.meta, TypeName: t.typeName, TypeDefinition: t.definition(t.typeName), diff --git a/src/javascript.grammar b/src/javascript.grammar index bb8a41f..59c56f2 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -120,7 +120,7 @@ FunctionDeclaration { } ClassDeclaration { - !statement tskw<"abstract">? kw<"class"> VariableDefinition TypeParamList? + !statement Decorator* tskw<"abstract">? kw<"class"> VariableDefinition TypeParamList? (kw<"extends"> expression | TSExtends type)? (tskw<"implements"> commaSep1)? ClassBody @@ -139,6 +139,7 @@ privacyArg { } MethodDeclaration[group=ClassItem] { + Decorator* privacy? (pkwMod<"static"> | tsPkwMod<"abstract">)? tsPkwMod<"override">? @@ -154,6 +155,7 @@ StaticBlock[group=ClassItem] { } PropertyDeclaration[group=ClassItem] { + Decorator* privacy? (pkwMod<"static"> | tsPkwMod<"abstract">)? (tsPkwMod<"readonly"> | pkwMod<"accessor">)? @@ -211,6 +213,15 @@ AmbientDeclaration { ) } +decoratorExpression { + VariableName | + MemberExpression { decoratorExpression !member ("." | "?.") (PropertyName | PrivatePropertyName) } | + CallExpression { decoratorExpression !call TypeArgList? "?."? ArgList } | + ParenthesizedExpression +} + +Decorator { "@" decoratorExpression } + pattern { VariableDefinition | ArrayPattern | ObjectPattern } ArrayPattern { "[" commaSep<("..."? patternAssign)?> ~destructure "]" } @@ -230,7 +241,7 @@ patternAssignTyped { } ParamList { - "(" commaSep<"..." patternAssignTyped | privacyArg? tskw<"readonly">? patternAssignTyped> ")" + "(" commaSep<"..." patternAssignTyped | Decorator* privacyArg? tskw<"readonly">? patternAssignTyped> ")" } Block { @@ -622,6 +633,8 @@ questionOp[@name=LogicOp] { "?" } CompareOp { expr } UpdateOp { expr } + @precedence { "*", ArithOp } + RegExp { "/" (![/\\\n[] | "\\" ![\n] | "[" (![\n\\\]] | "\\" ![\n])* "]")+ ("/" $[gimsuy]*)? } LessThan[@name=CompareOp] { "<" } diff --git a/test/decorator.txt b/test/decorator.txt new file mode 100644 index 0000000..56679f7 --- /dev/null +++ b/test/decorator.txt @@ -0,0 +1,64 @@ +# Decorators on classes and class fields + +@d1 class Foo { + @d2 bar() {} + @d3 get baz() { return 1 } + @d4 quux = 1 +} + +==> + +Script(ClassDeclaration( + Decorator(VariableName), + class,VariableDefinition,ClassBody( + MethodDeclaration(Decorator(VariableName),PropertyDefinition,ParamList,Block), + MethodDeclaration(Decorator(VariableName),get,PropertyDefinition,ParamList,Block( + ReturnStatement(return,Number))), + PropertyDeclaration(Decorator(VariableName),PropertyDefinition,Equals,Number)))) + +# Multiple decorators + +@d1 @d2 class Y {} + +==> + +Script(ClassDeclaration(Decorator(VariableName),Decorator(VariableName),class,VariableDefinition,ClassBody)) + +# Member decorators + +@one.two class X {} + +==> + +Script(ClassDeclaration(Decorator(MemberExpression(VariableName,PropertyName)),class,VariableDefinition,ClassBody)) + +# Call decorators + +@d(2) @a.b() class Z {} + +==> + +Script(ClassDeclaration( + Decorator(CallExpression(VariableName,ArgList(Number))), + Decorator(CallExpression(MemberExpression(VariableName,PropertyName),ArgList)), + class,VariableDefinition,ClassBody)) + +# Parenthesized decorators + +@(a instanceof Array ? x : y)(2) class P {} + +==> + +Script(ClassDeclaration( + Decorator(CallExpression(ParenthesizedExpression( + ConditionalExpression(BinaryExpression(VariableName,instanceof,VariableName),LogicOp,VariableName,LogicOp,VariableName)), + ArgList(Number))), + class,VariableDefinition,ClassBody)) + +# Parameter decorators + +function foo(@d bar) {} + +==> + +Script(FunctionDeclaration(function,VariableDefinition,ParamList(Decorator(VariableName),VariableDefinition),Block)) From e3d643a99ee49df4ee32afd9dfa167575bee44a7 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 28 Nov 2022 16:59:41 +0100 Subject: [PATCH 042/133] Mark version 1.3.0 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a90842..a8a7465 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.3.0 (2022-11-28) + +### New features + +Add support for decorator syntax. + ## 1.2.0 (2022-11-24) ### New features diff --git a/package.json b/package.json index c4ca5d0..fb9047b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.2.0", + "version": "1.3.0", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From eaa9afccdac5390ec0bcf2ab0090794ebc225fe7 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 29 Nov 2022 11:49:24 +0100 Subject: [PATCH 043/133] Emit a token for @ FIX: Actually emit a tree node for the `@` characters in decorators. --- src/javascript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 59c56f2..497c039 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -645,7 +645,7 @@ questionOp[@name=LogicOp] { "?" } "(" ")" "[" "]" "{" "}" ">" - "?." "." "," ";" ":" + "?." "." "," ";" ":" "@" JSXIdentifier { $[A-Z_$\u{a1}-\u{10ffff}] (identifierChar | @digit | "-")* } JSXLowerIdentifier[@name=JSXIdentifier] { $[a-z] (identifierChar | @digit | "-")* } From b8d2511b6121c540c1bab0788dda524dbf9ce7a2 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 29 Nov 2022 13:39:15 +0100 Subject: [PATCH 044/133] Mark version 1.3.1 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8a7465..814d9ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.3.1 (2022-11-29) + +### Bug fixes + +Actually emit a tree node for the `@` characters in decorators. + ## 1.3.0 (2022-11-28) ### New features diff --git a/package.json b/package.json index fb9047b..54e90ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.3.0", + "version": "1.3.1", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 96b5b4dafa7d98730598929c2240444b4e06c0e5 Mon Sep 17 00:00:00 2001 From: Benedikt Meurer Date: Fri, 9 Dec 2022 09:25:54 +0100 Subject: [PATCH 045/133] Fix missing support for override on properties. FIX: Typescript allows `override` on all class elements, not just methods. --- src/javascript.grammar | 1 + test/typescript.txt | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/javascript.grammar b/src/javascript.grammar index 497c039..fedf472 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -158,6 +158,7 @@ PropertyDeclaration[group=ClassItem] { Decorator* privacy? (pkwMod<"static"> | tsPkwMod<"abstract">)? + tsPkwMod<"override">? (tsPkwMod<"readonly"> | pkwMod<"accessor">)? (propName | PrivatePropertyDefinition) (Optional | LogicOp<"!">)? diff --git a/test/typescript.txt b/test/typescript.txt index 4130396..13d6db9 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -215,3 +215,18 @@ let x = 1 satisfies number ==> Script(VariableDeclaration(let,VariableDefinition,Equals,BinaryExpression(Number,satisfies,TypeName))) + +# Override modifier on properties {"dialect": "ts"} + +class A { + override accessor a; + static override b = 1; + override c = 2; +} + +==> + +Script(ClassDeclaration(class,VariableDefinition,ClassBody( + PropertyDeclaration(override,accessor,PropertyDefinition), + PropertyDeclaration(static,override,PropertyDefinition,Equals,Number), + PropertyDeclaration(override,PropertyDefinition,Equals,Number)))) From d1729e4ac3c9bf8729d0aa9e9d97e89bb1241761 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 14 Dec 2022 09:56:23 +0100 Subject: [PATCH 046/133] Parse class extends clauses as expressions FIX: Allow expressions in class extends clauses in TypeScript. Closes https://github.com/lezer-parser/javascript/issues/16 --- src/javascript.grammar | 16 +++++++--------- src/tokens.js | 17 +++-------------- test/typescript.txt | 12 ++++++++++-- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index fedf472..432c741 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -121,7 +121,7 @@ FunctionDeclaration { ClassDeclaration { !statement Decorator* tskw<"abstract">? kw<"class"> VariableDefinition TypeParamList? - (kw<"extends"> expression | TSExtends type)? + (kw<"extends"> ((VariableName | MemberExpression) !typeargs TypeArgList | expression))? (tskw<"implements"> commaSep1)? ClassBody } @@ -176,7 +176,7 @@ TypeAliasDeclaration { } InterfaceDeclaration { - tskw<"interface"> TypeDefinition TypeParamList? (TSExtends type)? ObjectType + tskw<"interface"> TypeDefinition TypeParamList? (kw<"extends"> type)? ObjectType } EnumDeclaration { @@ -197,7 +197,7 @@ AmbientDeclaration { GlobalDeclaration { tskw<"global"> Block } | ClassDeclaration { tskw<"abstract">? kw<"class"> VariableDefinition TypeParamList? - (kw<"extends"> expression | TSExtends type)? + (kw<"extends"> expression)? (tskw<"implements"> commaSep1)? ClassBody { "{" ( MethodDeclaration { @@ -205,7 +205,7 @@ AmbientDeclaration { (PropertyDefinition | PrivatePropertyDefinition) TypeParamList? ParamList (TypeAnnotation | TypePredicate) semi } | PropertyDeclaration | - IndexSignature + IndexSignature semi )* "}" } } | AmbientFunctionDeclaration { @@ -318,7 +318,7 @@ PatternProperty { } ClassExpression { - kw<"class"> VariableDefinition? (kw<"extends"> expression | TSExtends type)? ClassBody + kw<"class"> VariableDefinition? (kw<"extends"> expression)? ClassBody } functionSignature { TypeParamList? ParamList (TypeAnnotation | TypePredicate)? } @@ -376,7 +376,7 @@ TypeParamList { "<" commaSep ">" } -typeParam { TypeDefinition ~tsAngle (TSExtends type)? ("=" type)? } +typeParam { TypeDefinition ~tsAngle (kw<"extends"> type)? ("=" type)? } typeofMemberExpression[@name=MemberExpression] { VariableName !member (("." | "?.") PropertyName | "[" expression "]") @@ -407,7 +407,7 @@ type[@isGroup=Type] { ObjectType | UnionType { type !union LogicOp { "|" } type } | IntersectionType { type !intersection LogicOp { "&" } type } | - ConditionalType { type !typeExtends TSExtends type questionOp ~arrow type LogicOp<":"> type } | + ConditionalType { type !typeExtends kw<"extends"> type questionOp ~arrow type LogicOp<":"> type } | ParameterizedType { (TypeName | IndexedType) !typeargs TypeArgList } | TypeName } @@ -560,8 +560,6 @@ questionOp[@name=LogicOp] { "?" } @context trackNewline from "./tokens.js" -@external tokens tsExtends from "./tokens" { TSExtends[@name=extends] } - @external tokens noSemicolon from "./tokens" { noSemi } @external tokens incdecToken from "./tokens" { diff --git a/src/tokens.js b/src/tokens.js index 6b8cfc1..42e83af 100644 --- a/src/tokens.js +++ b/src/tokens.js @@ -4,13 +4,14 @@ import {ExternalTokenizer, ContextTracker} from "@lezer/lr" import {insertSemi, noSemi, incdec, incdecPrefix, templateContent, InterpolationStart, templateEnd, spaces, newline, BlockComment, LineComment, - TSExtends, Dialect_ts} from "./parser.terms.js" + Dialect_ts} from "./parser.terms.js" const space = [9, 10, 11, 12, 13, 32, 133, 160, 5760, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8232, 8233, 8239, 8287, 12288] const braceR = 125, braceL = 123, semicolon = 59, slash = 47, star = 42, - plus = 43, minus = 45, dollar = 36, backtick = 96, backslash = 92 + plus = 43, minus = 45, dollar = 36, backtick = 96, backslash = 92, + angleL = 60, angleR = 62, period = 46 export const trackNewline = new ContextTracker({ start: false, @@ -72,15 +73,3 @@ export const template = new ExternalTokenizer(input => { input.advance() } }) - -export const tsExtends = new ExternalTokenizer((input, stack) => { - if (input.next != 101 || !stack.dialectEnabled(Dialect_ts)) return - input.advance() - for (let i = 0; i < 6; i++) { - if (input.next != "xtends".charCodeAt(i)) return - input.advance() - } - if (input.next >= 57 && input.next <= 65 || input.next >= 48 && input.next <= 90 || - input.next == 95 || input.next >= 97 && input.next <= 122 || input.next > 160) return - input.acceptToken(TSExtends) -}) diff --git a/test/typescript.txt b/test/typescript.txt index 13d6db9..cf6a104 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -130,7 +130,7 @@ class Foo extends Bar implements Stuff { Script(ClassDeclaration( class, VariableDefinition, TypeParamList(TypeDefinition), - extends ParameterizedType(TypeName, TypeArgList(TypeName)), + extends, VariableName, TypeArgList(TypeName), implements TypeName, ClassBody( PropertyDeclaration(PropertyDefinition, TypeAnnotation(TypeName)), @@ -170,7 +170,7 @@ class Foo extends A.B {} ==> Script(ClassDeclaration(class, VariableDefinition, - extends, ParameterizedType(IndexedType(TypeName, TypeName), TypeArgList(TypeName)), + extends, MemberExpression(VariableName, PropertyName), TypeArgList(TypeName), ClassBody)) # Object type {"dialect": "ts"} @@ -230,3 +230,11 @@ Script(ClassDeclaration(class,VariableDefinition,ClassBody( PropertyDeclaration(override,accessor,PropertyDefinition), PropertyDeclaration(static,override,PropertyDefinition,Equals,Number), PropertyDeclaration(override,PropertyDefinition,Equals,Number)))) + +# Class extending expression {"dialect": "ts"} + +class X extends class {} {} + +==> + +Script(ClassDeclaration(class,VariableDefinition,extends,ClassExpression(class,ClassBody),ClassBody)) From 2fe010ec8846589a0195e48eb07e2643a2049fc6 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 14 Dec 2022 09:59:29 +0100 Subject: [PATCH 047/133] Mark version 1.3.2 --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 814d9ee..01d1297 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.3.2 (2022-12-14) + +### Bug fixes + +Typescript allows `override` on all class elements, not just methods. + +Allow expressions in class extends clauses in TypeScript. + ## 1.3.1 (2022-11-29) ### Bug fixes diff --git a/package.json b/package.json index 54e90ff..7d50e0a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.3.1", + "version": "1.3.2", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From bf8d1f76ef95fa4de6357c7c28bb87f52c22469c Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 19 Dec 2022 12:27:35 +0100 Subject: [PATCH 048/133] Add SingleClassItem top rule FEATURE: The new `"SingleClassItem"` top-level rule can be used to parse only a class item (method, property, or static block). Issue https://github.com/lezer-parser/javascript/pull/17 --- README.md | 4 ++++ src/javascript.grammar | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 89fd6a1..3d4e9fc 100644 --- a/README.md +++ b/README.md @@ -7,4 +7,8 @@ It parses ES2020, and supports a `"ts"` [dialect](https://lezer.codemirror.net/docs/guide/#dialects) to parse TypeScript, and a `"jsx"` dialect to parse JSX. +The `top` option can be set to `"SingleExpression"` or +`"SingleClassItem"` to parse an expression or class item instead of a +full program. + The code is licensed under an MIT license. diff --git a/src/javascript.grammar b/src/javascript.grammar index 432c741..1a2ec64 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -40,6 +40,8 @@ @top SingleExpression { expression } +@top SingleClassItem { classItem } + statement[@isGroup=Statement] { ExportDeclaration | ImportDeclaration | @@ -126,9 +128,9 @@ ClassDeclaration { ClassBody } -ClassBody { - "{" (MethodDeclaration | PropertyDeclaration | StaticBlock | ";")* "}" -} +classItem { MethodDeclaration | PropertyDeclaration | StaticBlock | ";" } + +ClassBody { "{" classItem* "}" } privacy { @extend[@name=Privacy,@dialect=ts] From 060b00206a999b853f417d26332c93da53530a1e Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 19 Dec 2022 18:28:30 +0100 Subject: [PATCH 049/133] Mark version 1.4.0 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01d1297..ff33543 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.4.0 (2022-12-19) + +### New features + +The new `"SingleClassItem"` top-level rule can be used to parse only a class item (method, property, or static block). + ## 1.3.2 (2022-12-14) ### Bug fixes diff --git a/package.json b/package.json index 7d50e0a..4ce15e9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.3.2", + "version": "1.4.0", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 9c8b965b923661a93f9d39ec35afb88e23e1dc18 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 21 Dec 2022 10:58:44 +0100 Subject: [PATCH 050/133] Make sure yield/await are chosen over other expression types FIX: Fix a bug where something like `yield [1]` (or `await`) was parsed as a member expression. FIX: Add support for `yield*` syntax. Closes https://github.com/lezer-parser/javascript/issues/18 --- src/javascript.grammar | 12 +++++++++++- test/expression.txt | 16 ++++++++++------ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 1a2ec64..378511e 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -279,6 +279,8 @@ expressionNoComma { ObjectExpression { "{" commaSep ~destructure "}" } | NewExpression { kw<"new"> expressionNoComma (!newArgs TypeArgList? ArgList)? } | UnaryExpression | + YieldExpression | + AwaitExpression | ParenthesizedExpression | ClassExpression | FunctionExpression | @@ -329,8 +331,16 @@ FunctionExpression { async? kw<"function"> Star? VariableDefinition? functionSignature Block } +YieldExpression[@dynamicPrecedence=1] { + !prefix ckw<"yield"> Star? expressionNoComma +} + +AwaitExpression[@dynamicPrecedence=1] { + !prefix ckw<"await"> expressionNoComma +} + UnaryExpression { - !prefix (ckw<"await"> | ckw<"yield"> | kw<"void"> | kw<"typeof"> | kw<"delete"> | + !prefix (kw<"void"> | kw<"typeof"> | kw<"delete"> | LogicOp<"!"> | BitOp<"~"> | incdec | incdecPrefix | ArithOp<"+" | "-">) expressionNoComma } diff --git a/test/expression.txt b/test/expression.txt index 491bfd5..06e75da 100644 --- a/test/expression.txt +++ b/test/expression.txt @@ -293,12 +293,16 @@ Script( # Yield expressions yield db.users.where('[endpoint+email]'); +yield* a; +yield [22]; ==> Script( - ExpressionStatement(UnaryExpression(yield, - CallExpression(MemberExpression(MemberExpression(VariableName,PropertyName),PropertyName),ArgList(String))))) + ExpressionStatement(YieldExpression(yield, + CallExpression(MemberExpression(MemberExpression(VariableName,PropertyName),PropertyName),ArgList(String)))), + ExpressionStatement(YieldExpression(yield,Star,VariableName)), + ExpressionStatement(YieldExpression(yield,ArrayExpression(Number)))) # Template strings @@ -405,7 +409,7 @@ Script(ExpressionStatement(ParenthesizedExpression(ObjectExpression( Property(get,PropertyDefinition,ParamList,Block(ReturnStatement(return,VariableName))), Property(set,PropertyDefinition,ParamList(VariableDefinition), Block(ExpressionStatement(AssignmentExpression(VariableName,Equals,VariableName)))), - Property(Star,PropertyDefinition,ParamList,Block(ExpressionStatement(UnaryExpression(yield,VariableName)))), + Property(Star,PropertyDefinition,ParamList,Block(ExpressionStatement(YieldExpression(yield,VariableName)))), Property(PropertyDefinition,ParamList,Block(ReturnStatement(return,Number))))))) # Keyword property names @@ -445,7 +449,7 @@ Script(ExpressionStatement(ArrayExpression( FunctionExpression(function,Star,ParamList,Block), FunctionExpression(function,Star,VariableDefinition,ParamList(VariableDefinition,VariableDefinition),Block( ExpressionStatement(VariableName), - ExpressionStatement(UnaryExpression(yield,VariableName))))))) + ExpressionStatement(YieldExpression(yield,VariableName))))))) # Member expressions @@ -520,8 +524,8 @@ await asyncPromise; ==> Script( - ExpressionStatement(UnaryExpression(await,CallExpression(VariableName,ArgList))), - ExpressionStatement(UnaryExpression(await,VariableName))) + ExpressionStatement(AwaitExpression(await,CallExpression(VariableName,ArgList))), + ExpressionStatement(AwaitExpression(await,VariableName))) # Numeric operators From 7b8d2ac285f19ab877ca28152261e5d8b0b3c093 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 9 Jan 2023 13:08:45 +0100 Subject: [PATCH 051/133] Use a local tokenizer for template string content --- package.json | 4 ++-- src/highlight.js | 1 + src/javascript.grammar | 23 +++++++++++++++-------- src/tokens.js | 33 +++------------------------------ test/expression.txt | 4 ++-- 5 files changed, 23 insertions(+), 42 deletions(-) diff --git a/package.json b/package.json index 4ce15e9..28ccdd9 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,8 @@ "@rollup/plugin-node-resolve": "^9.0.0" }, "dependencies": { - "@lezer/lr": "^1.0.0", - "@lezer/highlight": "^1.0.0" + "@lezer/lr": "^1.3.0", + "@lezer/highlight": "^1.1.3" }, "repository": { "type": "git", diff --git a/src/highlight.js b/src/highlight.js index e37ce29..f9a10e0 100644 --- a/src/highlight.js +++ b/src/highlight.js @@ -29,6 +29,7 @@ export const jsHighlight = styleTags({ BlockComment: t.blockComment, Number: t.number, String: t.string, + Escape: t.escape, ArithOp: t.arithmeticOperator, LogicOp: t.logicOperator, BitOp: t.bitwiseOperator, diff --git a/src/javascript.grammar b/src/javascript.grammar index 378511e..9d3ec7b 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -463,7 +463,7 @@ ParamTypeList[@name=ParamList] { @skip {} { TemplateString { - templateStart (templateContent | templateExpr)* templateEnd + templateStart (templateEscape | templateContent | templateExpr)* templateEnd } TemplateType { @@ -579,10 +579,11 @@ questionOp[@name=LogicOp] { "?" } incdecPrefix[@name=ArithOp] } -@external tokens template from "./tokens" { - templateContent, - InterpolationStart[closedBy=InterpolationEnd], - templateEnd +@local tokens { + InterpolationStart[closedBy=InterpolationEnd] { "${" } + templateEnd { "`" } + templateEscape[@name=Escape] { Escape } + @else templateContent } @tokens { @@ -618,20 +619,26 @@ questionOp[@name=LogicOp] { "?" } @precedence { spaces, newline, word } + hex { @digit | $[a-fA-F] } + Number { (@digit ("_" | @digit)* ("." ("_" | @digit)*)? | "." @digit ("_" | @digit)*) (("e" | "E") ("+" | "-")? ("_" | @digit)+)? | @digit ("_" | @digit)* "n" | - "0x" (@digit | $[a-fA-F] | "_")+ "n"? | + "0x" (hex | "_")+ "n"? | "0b" $[01_]+ "n"? | "0o" $[0-7_]+ "n"? } @precedence { Number "." } + Escape { + "\\" ("x" hex hex | "u" ("{" hex+ "}" | hex hex hex hex) | ![xu]) + } + String { - '"' (![\\\n"] | "\\" _)* '"'? | - "'" (![\\\n'] | "\\" _)* "'"? + '"' (![\\\n"] | Escape)* '"'? | + "'" (![\\\n'] | Escape)* "'"? } templateStart { "`" } diff --git a/src/tokens.js b/src/tokens.js index 42e83af..840ee02 100644 --- a/src/tokens.js +++ b/src/tokens.js @@ -2,15 +2,15 @@ expressed by lezer's built-in tokenizer. */ import {ExternalTokenizer, ContextTracker} from "@lezer/lr" -import {insertSemi, noSemi, incdec, incdecPrefix, templateContent, InterpolationStart, templateEnd, +import {insertSemi, noSemi, incdec, incdecPrefix, spaces, newline, BlockComment, LineComment, Dialect_ts} from "./parser.terms.js" const space = [9, 10, 11, 12, 13, 32, 133, 160, 5760, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8232, 8233, 8239, 8287, 12288] -const braceR = 125, braceL = 123, semicolon = 59, slash = 47, star = 42, - plus = 43, minus = 45, dollar = 36, backtick = 96, backslash = 92, +const braceR = 125, semicolon = 59, slash = 47, star = 42, + plus = 43, minus = 45, backslash = 92, angleL = 60, angleR = 62, period = 46 export const trackNewline = new ContextTracker({ @@ -46,30 +46,3 @@ export const incdecToken = new ExternalTokenizer((input, stack) => { } } }, {contextual: true}) - -export const template = new ExternalTokenizer(input => { - for (let afterDollar = false, i = 0;; i++) { - let {next} = input - if (next < 0) { - if (i) input.acceptToken(templateContent) - break - } else if (next == backtick) { - if (i) input.acceptToken(templateContent) - else input.acceptToken(templateEnd, 1) - break - } else if (next == braceL && afterDollar) { - if (i == 1) input.acceptToken(InterpolationStart, 1) - else input.acceptToken(templateContent, -1) - break - } else if (next == 10 /* "\n" */ && i) { - // Break up template strings on lines, to avoid huge tokens - input.advance() - input.acceptToken(templateContent) - break - } else if (next == backslash) { - input.advance() - } - afterDollar = next == dollar - input.advance() - } -}) diff --git a/test/expression.txt b/test/expression.txt index 06e75da..ad0638f 100644 --- a/test/expression.txt +++ b/test/expression.txt @@ -320,7 +320,7 @@ Script( `$`; `$$$$${ async }`; -`\\`; +`\\\``; `one${`two${`three`}`}`; @@ -337,7 +337,7 @@ Script( ExpressionStatement(TemplateString), ExpressionStatement(TemplateString), ExpressionStatement(TemplateString(Interpolation(InterpolationStart,VariableName,InterpolationEnd))), - ExpressionStatement(TemplateString), + ExpressionStatement(TemplateString(Escape,Escape)), ExpressionStatement(TemplateString(Interpolation(InterpolationStart,TemplateString( Interpolation(InterpolationStart,TemplateString,InterpolationEnd)),InterpolationEnd))), ExpressionStatement(TaggedTemplateExpression(VariableName,TemplateString( From 736036917fa3edf7ec0b0bd8b05fbd14c5bc4157 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 9 Jan 2023 13:19:41 +0100 Subject: [PATCH 052/133] Parse string escapes as separate tokens FIX: Escapes in strings are now parsed as their own tokens (and styled with the `escape` tag). --- src/javascript.grammar | 12 ++++++++---- test/expression.txt | 10 +++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 9d3ec7b..560fdbf 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -469,6 +469,11 @@ ParamTypeList[@name=ParamList] { TemplateType { templateStart (templateContent | templateType)* templateEnd } + + String { + '"' (stringContentDouble | Escape)* ('"' | "\n") | + "'" (stringContentSingle | Escape)* ("'" | "\n") + } } templateExpr[@name=Interpolation] { InterpolationStart expression InterpolationEnd } @@ -636,10 +641,9 @@ questionOp[@name=LogicOp] { "?" } "\\" ("x" hex hex | "u" ("{" hex+ "}" | hex hex hex hex) | ![xu]) } - String { - '"' (![\\\n"] | Escape)* '"'? | - "'" (![\\\n'] | Escape)* "'"? - } + stringContentSingle { ![\\\n']+ } + + stringContentDouble { ![\\\n"]+ } templateStart { "`" } diff --git a/test/expression.txt b/test/expression.txt index ad0638f..6c68d51 100644 --- a/test/expression.txt +++ b/test/expression.txt @@ -18,11 +18,11 @@ line'; ==> -Script(ExpressionStatement(String), - ExpressionStatement(String), - ExpressionStatement(String), - ExpressionStatement(String), - ExpressionStatement(String)) +Script(ExpressionStatement(String(Escape,Escape)), + ExpressionStatement(String(Escape,Escape)), + ExpressionStatement(String(Escape)), + ExpressionStatement(String(Escape)), + ExpressionStatement(String(Escape))) # Numbers From 4d6bd98e1ae60d40caa64067c02922b0ed80ad1b Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 9 Jan 2023 13:23:16 +0100 Subject: [PATCH 053/133] Parse block comment content as multiple tokens To improve the efficiency of incrementally parsing large comments --- src/javascript.grammar | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 560fdbf..4e7e53c 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -474,6 +474,8 @@ ParamTypeList[@name=ParamList] { '"' (stringContentDouble | Escape)* ('"' | "\n") | "'" (stringContentSingle | Escape)* ("'" | "\n") } + + BlockComment { "/*" (blockCommentContent | blockCommentNewline)* blockCommentEnd } } templateExpr[@name=Interpolation] { InterpolationStart expression InterpolationEnd } @@ -591,24 +593,23 @@ questionOp[@name=LogicOp] { "?" } @else templateContent } +@local tokens { + blockCommentEnd { "*/" } + blockCommentNewline { "\n" } + @else blockCommentContent +} + @tokens { spaces[@export] { $[\u0009 \u000b\u00a0\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]+ } newline[@export] { $[\r\n\u2028\u2029] } LineComment { "//" ![\n]* } - // FIXME split into multiple tokens - BlockComment { "/*" blockCommentRest } - - blockCommentRest { ![*] blockCommentRest | "*" blockCommentAfterStar } - - blockCommentAfterStar { "/" | "*" blockCommentAfterStar | ![/*] blockCommentRest } - divide[@name=ArithOp] { "/" } - @precedence { BlockComment, LineComment, divide } + @precedence { "/*", LineComment, divide } - @precedence { BlockComment, LineComment, RegExp } + @precedence { "/*", LineComment, RegExp } identifierChar { @asciiLetter | $[_$\u{a1}-\u{10ffff}] } From 48c2ecccd17a41d34ce49d8b1bfeb4e3461e4e4f Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 9 Jan 2023 14:13:53 +0100 Subject: [PATCH 054/133] Mark version 1.4.1 --- CHANGELOG.md | 10 ++++++++++ package.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff33543..a287805 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## 1.4.1 (2023-01-09) + +### Bug fixes + +Fix a bug where something like `yield [1]` (or `await`) was parsed as a member expression. + +Add support for `yield*` syntax. + +Escapes in strings are now parsed as their own tokens (and styled with the `escape` tag). + ## 1.4.0 (2022-12-19) ### New features diff --git a/package.json b/package.json index 28ccdd9..c61dcde 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.0", + "version": "1.4.1", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From adfcf834240981ae02c68f7a524022a2da846794 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 24 Jan 2023 08:28:48 +0100 Subject: [PATCH 055/133] Update maintainer email --- LICENSE | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index 30a86e3..c21df7e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (C) 2018 by Marijn Haverbeke and others +Copyright (C) 2018 by Marijn Haverbeke and others Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/package.json b/package.json index c61dcde..766f13a 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ }, "module": "dist/index.es.js", "types": "dist/index.d.ts", - "author": "Marijn Haverbeke ", + "author": "Marijn Haverbeke ", "license": "MIT", "devDependencies": { "@lezer/generator": "^1.0.0", From f3c453fd157c6404147b3c958ea118e6453e6bdd Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 29 Mar 2023 09:08:48 +0200 Subject: [PATCH 056/133] Add support for TypeScript declared properties FIX: Properly parse `declare` in front of class properties and methods in TypeScript. Closes https://github.com/codemirror/dev/issues/1121 --- src/javascript.grammar | 8 +++++--- test/typescript.txt | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 4e7e53c..b26d35f 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -118,7 +118,7 @@ declaration { } FunctionDeclaration { - async? !statement kw<"function"> Star? VariableDefinition? functionSignature Block + async? !statement kw<"function"> Star? VariableDefinition? functionSignature (Block | semi) } ClassDeclaration { @@ -142,6 +142,7 @@ privacyArg { MethodDeclaration[group=ClassItem] { Decorator* + tsPkwMod<"declare">? privacy? (pkwMod<"static"> | tsPkwMod<"abstract">)? tsPkwMod<"override">? @@ -149,7 +150,7 @@ MethodDeclaration[group=ClassItem] { (pkwMod<"get"> | pkwMod<"set"> | Star)? (propName | PrivatePropertyDefinition) functionSignature - Block + (Block | semi) } StaticBlock[group=ClassItem] { @@ -158,6 +159,7 @@ StaticBlock[group=ClassItem] { PropertyDeclaration[group=ClassItem] { Decorator* + tsPkwMod<"declare">? privacy? (pkwMod<"static"> | tsPkwMod<"abstract">)? tsPkwMod<"override">? @@ -204,7 +206,7 @@ AmbientDeclaration { ClassBody { "{" ( MethodDeclaration { privacy? (pkwMod<"static"> | tsPkwMod<"abstract">)? pkwMod<"async">? (pkwMod<"get"> | pkwMod<"set"> | Star)? - (PropertyDefinition | PrivatePropertyDefinition) TypeParamList? ParamList (TypeAnnotation | TypePredicate) semi + (PropertyDefinition | PrivatePropertyDefinition) TypeParamList? ParamList (TypeAnnotation | TypePredicate)? semi } | PropertyDeclaration | IndexSignature semi diff --git a/test/typescript.txt b/test/typescript.txt index cf6a104..77d23c7 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -238,3 +238,41 @@ class X extends class {} {} ==> Script(ClassDeclaration(class,VariableDefinition,extends,ClassExpression(class,ClassBody),ClassBody)) + +# Declare syntax {"dialect": "ts"} + +declare namespace myLib { + function makeGreeting(s: string): string; + let numberOfGreetings: number; +} + +declare function greet(setting: GreetingSettings): void; + +declare class Greeter { + constructor(greeting: string); + greeting: string; + showGreeting(): void; +} + +class X { + declare foo(); + declare bar: number; +} + +==> + + +Script( + AmbientDeclaration(declare,NamespaceDeclaration(namespace,VariableDefinition,Block( + FunctionDeclaration(function,VariableDefinition,ParamList(VariableDefinition,TypeAnnotation(TypeName)), + TypeAnnotation(TypeName)), + VariableDeclaration(let,VariableDefinition,TypeAnnotation(TypeName))))), + AmbientDeclaration(declare,AmbientFunctionDeclaration(function,VariableDefinition, + ParamList(VariableDefinition,TypeAnnotation(TypeName)),TypeAnnotation(VoidType(void)))), + AmbientDeclaration(declare,ClassDeclaration(class,VariableDefinition,ClassBody( + MethodDeclaration(PropertyDefinition,ParamList(VariableDefinition,TypeAnnotation(TypeName))), + PropertyDeclaration(PropertyDefinition,TypeAnnotation(TypeName)), + MethodDeclaration(PropertyDefinition,ParamList,TypeAnnotation(VoidType(void)))))), + ClassDeclaration(class,VariableDefinition,ClassBody( + MethodDeclaration(declare,PropertyDefinition,ParamList), + PropertyDeclaration(declare,PropertyDefinition,TypeAnnotation(TypeName))))) From e9641bc073bb627d18f9c8ca02dd13d589ecc450 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 29 Mar 2023 09:43:21 +0200 Subject: [PATCH 057/133] Mark version 1.4.2 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a287805..eec8e6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.4.2 (2023-03-29) + +### Bug fixes + +Properly parse `declare` in front of class properties and methods in TypeScript. + ## 1.4.1 (2023-01-09) ### Bug fixes diff --git a/package.json b/package.json index 766f13a..c09b978 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.1", + "version": "1.4.2", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 5caae029ab28ed3da9ed8f626c0553132991f98d Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 14 Apr 2023 16:29:24 +0200 Subject: [PATCH 058/133] Add test for generators --- test/statement.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/statement.txt b/test/statement.txt index 27ee868..a7dddc4 100644 --- a/test/statement.txt +++ b/test/statement.txt @@ -355,3 +355,22 @@ Script( PatternProperty(PropertyName,VariableDefinition,Equals,Number) ),Equals,VariableName), VariableDeclaration(let,ObjectPattern(PatternProperty(VariableName,VariableDefinition)),Equals,VariableName)) + +# Generators + +function* foo() { yield 1 } + +class B { + *method() {} +} + +({*x() {}}) + +==> + +Script( + FunctionDeclaration(function,Star,VariableDefinition,ParamList,Block( + ExpressionStatement(YieldExpression(yield,Number)))), + ClassDeclaration(class,VariableDefinition,ClassBody( + MethodDeclaration(Star,PropertyDefinition,ParamList,Block))), + ExpressionStatement(ParenthesizedExpression(ObjectExpression(Property(Star,PropertyDefinition,ParamList,Block))))) From 0bfdfe1b5ae611eefcba2744c14c2f11dac5bd1d Mon Sep 17 00:00:00 2001 From: Benedikt Meurer Date: Mon, 24 Apr 2023 11:16:51 +0200 Subject: [PATCH 059/133] Add support for `this` parameter declaration in TypeScript (#20) FIX: Properly parse `this: Type` within parameter lists for TypeScript. Bug: https://crbug.com/1436873 Closes https://github.com/lezer-parser/javascript/issues/19 --- src/javascript.grammar | 2 +- test/typescript.txt | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index b26d35f..f3743a5 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -246,7 +246,7 @@ patternAssignTyped { } ParamList { - "(" commaSep<"..." patternAssignTyped | Decorator* privacyArg? tskw<"readonly">? patternAssignTyped> ")" + "(" commaSep<"..." patternAssignTyped | Decorator* privacyArg? tskw<"readonly">? patternAssignTyped | kw<"this"> TypeAnnotation> ")" } Block { diff --git a/test/typescript.txt b/test/typescript.txt index 77d23c7..8e8a8fa 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -276,3 +276,11 @@ Script( ClassDeclaration(class,VariableDefinition,ClassBody( MethodDeclaration(declare,PropertyDefinition,ParamList), PropertyDeclaration(declare,PropertyDefinition,TypeAnnotation(TypeName))))) + +# Declare this in a Function {"dialect": "ts"} + +function foo(this: User) {} + +==> + +Script(FunctionDeclaration(function,VariableDefinition,ParamList(this,TypeAnnotation(TypeName)),Block)) From bc1b018b320d170b732fe99e0c4354718901be6f Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 24 Apr 2023 11:15:50 +0200 Subject: [PATCH 060/133] Simplify property modifier rules To greatly reduce the state space and speed up compilation --- src/javascript.grammar | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index f3743a5..692620e 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -140,12 +140,17 @@ privacyArg { @extend[@name=Privacy,@dialect=ts] } +propModifier { + Decorator | + tsPkwMod<"declare"> | + privacy | + pkwMod<"static"> | + tsPkwMod<"abstract"> | + tsPkwMod<"override"> +} + MethodDeclaration[group=ClassItem] { - Decorator* - tsPkwMod<"declare">? - privacy? - (pkwMod<"static"> | tsPkwMod<"abstract">)? - tsPkwMod<"override">? + propModifier* pkwMod<"async">? (pkwMod<"get"> | pkwMod<"set"> | Star)? (propName | PrivatePropertyDefinition) @@ -158,11 +163,7 @@ StaticBlock[group=ClassItem] { } PropertyDeclaration[group=ClassItem] { - Decorator* - tsPkwMod<"declare">? - privacy? - (pkwMod<"static"> | tsPkwMod<"abstract">)? - tsPkwMod<"override">? + propModifier* (tsPkwMod<"readonly"> | pkwMod<"accessor">)? (propName | PrivatePropertyDefinition) (Optional | LogicOp<"!">)? @@ -204,10 +205,7 @@ AmbientDeclaration { (kw<"extends"> expression)? (tskw<"implements"> commaSep1)? ClassBody { "{" ( - MethodDeclaration { - privacy? (pkwMod<"static"> | tsPkwMod<"abstract">)? pkwMod<"async">? (pkwMod<"get"> | pkwMod<"set"> | Star)? - (PropertyDefinition | PrivatePropertyDefinition) TypeParamList? ParamList (TypeAnnotation | TypePredicate)? semi - } | + MethodDeclaration | PropertyDeclaration | IndexSignature semi )* "}" } From cc8215e73ff53999ee979cc699b104bbced72658 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 24 Apr 2023 11:18:11 +0200 Subject: [PATCH 061/133] Mark version 1.4.3 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eec8e6d..1e7959c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.4.3 (2023-04-24) + +### Bug fixes + +Properly parse `this: Type` within parameter lists for TypeScript. + ## 1.4.2 (2023-03-29) ### Bug fixes diff --git a/package.json b/package.json index c09b978..375ac1e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.2", + "version": "1.4.3", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From ff991c902be206512f352a7c08cf6c331629600b Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 5 Jun 2023 14:26:44 +0200 Subject: [PATCH 062/133] Remove unused import --- src/tokens.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/tokens.js b/src/tokens.js index 840ee02..2976655 100644 --- a/src/tokens.js +++ b/src/tokens.js @@ -3,15 +3,12 @@ import {ExternalTokenizer, ContextTracker} from "@lezer/lr" import {insertSemi, noSemi, incdec, incdecPrefix, - spaces, newline, BlockComment, LineComment, - Dialect_ts} from "./parser.terms.js" + spaces, newline, BlockComment, LineComment} from "./parser.terms.js" const space = [9, 10, 11, 12, 13, 32, 133, 160, 5760, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8232, 8233, 8239, 8287, 12288] -const braceR = 125, semicolon = 59, slash = 47, star = 42, - plus = 43, minus = 45, backslash = 92, - angleL = 60, angleR = 62, period = 46 +const braceR = 125, semicolon = 59, slash = 47, star = 42, plus = 43, minus = 45 export const trackNewline = new ContextTracker({ start: false, From d5921e4f7cffaabbe8ffa473270f94af44cffa2f Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 12 Jun 2023 13:42:59 +0200 Subject: [PATCH 063/133] Remove unnecessary canShift tests --- src/tokens.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tokens.js b/src/tokens.js index 2976655..00ffaec 100644 --- a/src/tokens.js +++ b/src/tokens.js @@ -20,7 +20,7 @@ export const trackNewline = new ContextTracker({ export const insertSemicolon = new ExternalTokenizer((input, stack) => { let {next} = input - if ((next == braceR || next == -1 || stack.context) && stack.canShift(insertSemi)) + if (next == braceR || next == -1 || stack.context) input.acceptToken(insertSemi) }, {contextual: true, fallback: true}) @@ -28,7 +28,7 @@ export const noSemicolon = new ExternalTokenizer((input, stack) => { let {next} = input, after if (space.indexOf(next) > -1) return if (next == slash && ((after = input.peek(1)) == slash || after == star)) return - if (next != braceR && next != semicolon && next != -1 && !stack.context && stack.canShift(noSemi)) + if (next != braceR && next != semicolon && next != -1 && !stack.context) input.acceptToken(noSemi) }, {contextual: true}) From ede3ffc60145890ef64089a5db06cfa1229b5d71 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 15 Jun 2023 11:20:29 +0200 Subject: [PATCH 064/133] Fix code style of import --- test/test-javascript.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test-javascript.js b/test/test-javascript.js index bf7fcc1..ee3b5d5 100644 --- a/test/test-javascript.js +++ b/test/test-javascript.js @@ -3,7 +3,7 @@ import {fileTests} from "@lezer/generator/dist/test" import * as fs from "fs" import * as path from "path" -import { fileURLToPath } from 'url'; +import {fileURLToPath} from "url" let caseDir = path.dirname(fileURLToPath(import.meta.url)) for (let file of fs.readdirSync(caseDir)) { From 568d51c76ae930ea3ff7edd6699685824fb751b9 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 19 Jun 2023 18:23:39 +0200 Subject: [PATCH 065/133] Add using syntax FIX: Add support for `using` syntax. --- src/javascript.grammar | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 692620e..85c3903 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -98,7 +98,7 @@ ForSpec { forXSpec { "(" - ((kw<"let"> | kw<"var"> | kw<"const">) pattern | VariableName | MemberExpression | ArrayPattern | ObjectPattern) + (variableDeclarationKeyword pattern | VariableName | MemberExpression | ArrayPattern | ObjectPattern) !loop op expression ")" } @@ -172,8 +172,12 @@ PropertyDeclaration[group=ClassItem] { semi } +variableDeclarationKeyword { + kw<"let"> | kw<"var"> | kw<"const"> | ckw<"await">? ckw<"using"> +} + VariableDeclaration { - (kw<"let"> | kw<"var"> | kw<"const">) commaSep1 semi + variableDeclarationKeyword commaSep1 semi } TypeAliasDeclaration { From 2540cbedbf5f9ccb8169aae7992bf5376fd170e0 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 3 Jul 2023 10:47:29 +0200 Subject: [PATCH 066/133] Conform to expectation of recent TS versions FIX: Make the package work with new TS resolution styles. --- dist/index.d.cts | 3 +++ package.json | 4 ++-- rollup.config.js | 2 +- test/test-javascript.js | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 dist/index.d.cts diff --git a/dist/index.d.cts b/dist/index.d.cts new file mode 100644 index 0000000..b1518ec --- /dev/null +++ b/dist/index.d.cts @@ -0,0 +1,3 @@ +import {LRParser} from "@lezer/lr" + +export const parser: LRParser diff --git a/package.json b/package.json index 375ac1e..882d4f0 100644 --- a/package.json +++ b/package.json @@ -5,10 +5,10 @@ "main": "dist/index.cjs", "type": "module", "exports": { - "import": "./dist/index.es.js", + "import": "./dist/index.js", "require": "./dist/index.cjs" }, - "module": "dist/index.es.js", + "module": "dist/index.js", "types": "dist/index.d.ts", "author": "Marijn Haverbeke ", "license": "MIT", diff --git a/rollup.config.js b/rollup.config.js index 75a876c..35012b4 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -7,7 +7,7 @@ export default { file: "./dist/index.cjs" }, { format: "es", - file: "./dist/index.es.js" + file: "./dist/index.js" }], external(id) { return !/^[\.\/]/.test(id) }, plugins: [ diff --git a/test/test-javascript.js b/test/test-javascript.js index ee3b5d5..21ba880 100644 --- a/test/test-javascript.js +++ b/test/test-javascript.js @@ -1,4 +1,4 @@ -import {parser} from "../dist/index.es.js" +import {parser} from "../dist/index.js" import {fileTests} from "@lezer/generator/dist/test" import * as fs from "fs" From a104687c464d34ad770f87f470140ede4ac46d52 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 3 Jul 2023 10:48:16 +0200 Subject: [PATCH 067/133] Mark version 1.4.4 --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e7959c..c2ddbfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.4.4 (2023-07-03) + +### Bug fixes + +Add support for `using` syntax. + +Make the package work with new TS resolution styles. + ## 1.4.3 (2023-04-24) ### Bug fixes diff --git a/package.json b/package.json index 882d4f0..27ca992 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.3", + "version": "1.4.4", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 9d9f47c1c82c776b9de60212c94f3850cb605fa2 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 25 Jul 2023 21:54:40 +0200 Subject: [PATCH 068/133] Allow arbitrary types as indexes in indexed types FIX: Allow the index in a TypeScript indexed type to be any kind of type. Closes https://github.com/codemirror/dev/issues/1218 --- src/javascript.grammar | 2 +- test/typescript.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 85c3903..f24c87d 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -429,7 +429,7 @@ type[@isGroup=Type] { } IndexedType { - type !typeMember ("." TypeName | "[" (String | Number) "]")+ + type !typeMember ("." TypeName | "[" type "]")+ } ObjectType { diff --git a/test/typescript.txt b/test/typescript.txt index 8e8a8fa..a155397 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -92,7 +92,7 @@ let f: (x: number) => boolean Script( VariableDeclaration(let, VariableDefinition, TypeAnnotation( UnionType(UnionType(TypeofType(typeof, MemberExpression(VariableName, PropertyName)), LogicOp, - IntersectionType(KeyofType(keyof, TypeName), LogicOp, IndexedType(TypeName, String))), + IntersectionType(KeyofType(keyof, TypeName), LogicOp, IndexedType(TypeName, LiteralType(String)))), LogicOp, ParameterizedType(TypeName, TypeArgList(TypeName))))), VariableDeclaration(let, VariableDefinition, TypeAnnotation(TupleType(TypeName, TypeName))), VariableDeclaration(let, VariableDefinition, TypeAnnotation(FunctionSignature( From 0e77054cf19894892242f602d87e5df73e17b371 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 25 Jul 2023 21:54:49 +0200 Subject: [PATCH 069/133] Mark version 1.4.5 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2ddbfc..250805c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.4.5 (2023-07-25) + +### Bug fixes + +Allow the index in a TypeScript indexed type to be any kind of type. + ## 1.4.4 (2023-07-03) ### Bug fixes diff --git a/package.json b/package.json index 27ca992..2f09393 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.4", + "version": "1.4.5", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From f0d34d11afbbc8182bb2a9c939610dea4eeb32b9 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 17 Aug 2023 16:14:44 +0200 Subject: [PATCH 070/133] Upgrade Mocha --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2f09393..1299b13 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "license": "MIT", "devDependencies": { "@lezer/generator": "^1.0.0", - "mocha": "^9.0.1", + "mocha": "^10.2.0", "rollup": "^2.52.2", "@rollup/plugin-node-resolve": "^9.0.0" }, From 90a87c9529ca173299322f85539226fc0c7da648 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 22 Aug 2023 13:20:13 +0200 Subject: [PATCH 071/133] Give type argument lists a dynamic precedence FIX: Make sure that, in TypeScript, type argument lists are prefered over comparison operators when both produce valid parses. Closes https://github.com/codemirror/dev/issues/1233 --- src/javascript.grammar | 2 +- test/typescript.txt | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index f24c87d..3c51da1 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -384,7 +384,7 @@ ArrowFunction { async? (ParamList { VariableDefinition } | ParamList TypeAnnotation?) "=>" (Block | expressionNoComma) } -TypeArgList { +TypeArgList[@dynamicPrecedence=1] { @extend[@dialect=ts,@name="<"] commaSep ">" } diff --git a/test/typescript.txt b/test/typescript.txt index a155397..dd5dd95 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -261,7 +261,6 @@ class X { ==> - Script( AmbientDeclaration(declare,NamespaceDeclaration(namespace,VariableDefinition,Block( FunctionDeclaration(function,VariableDefinition,ParamList(VariableDefinition,TypeAnnotation(TypeName)), @@ -284,3 +283,15 @@ function foo(this: User) {} ==> Script(FunctionDeclaration(function,VariableDefinition,ParamList(this,TypeAnnotation(TypeName)),Block)) + +# Prefers type parameters to comparison operators {"dialect": "ts jsx"} + +let a = useState(1) +return 2 + +==> + +Script( + VariableDeclaration(let,VariableDefinition,Equals, + CallExpression(VariableName,TypeArgList(TypeName),ArgList(Number))), + ReturnStatement(return,Number)) From 6bfbf41624b0ba4db6bbe51ad9b7cb066ca706c6 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 22 Aug 2023 13:39:44 +0200 Subject: [PATCH 072/133] Mark version 1.4.6 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 250805c..333db0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.4.6 (2023-08-22) + +### Bug fixes + +Make sure that, in TypeScript, type argument lists are prefered over comparison operators when both produce valid parses. + ## 1.4.5 (2023-07-25) ### Bug fixes diff --git a/package.json b/package.json index 1299b13..73b1703 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.5", + "version": "1.4.6", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 7512c9554fe2d3cb45893f634bacf4c79731e959 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 23 Aug 2023 09:12:15 +0200 Subject: [PATCH 073/133] Support hashbang comments FIX: Properly parse hashbang comments. Closes https://github.com/codemirror/dev/issues/1236 --- src/highlight.js | 2 +- src/javascript.grammar | 4 +++- test/statement.txt | 9 +++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/highlight.js b/src/highlight.js index f9a10e0..33dc077 100644 --- a/src/highlight.js +++ b/src/highlight.js @@ -25,7 +25,7 @@ export const jsHighlight = styleTags({ PropertyDefinition: t.definition(t.propertyName), PrivatePropertyDefinition: t.definition(t.special(t.propertyName)), UpdateOp: t.updateOperator, - LineComment: t.lineComment, + "LineComment Hashbang": t.lineComment, BlockComment: t.blockComment, Number: t.number, String: t.string, diff --git a/src/javascript.grammar b/src/javascript.grammar index 3c51da1..0a39801 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -36,7 +36,7 @@ predicate } -@top Script { statement+ } +@top Script { Hashbang? statement+ } @top SingleExpression { expression } @@ -609,6 +609,8 @@ questionOp[@name=LogicOp] { "?" } LineComment { "//" ![\n]* } + Hashbang { "#!" ![\n]* } + divide[@name=ArithOp] { "/" } @precedence { "/*", LineComment, divide } diff --git a/test/statement.txt b/test/statement.txt index a7dddc4..a8313a7 100644 --- a/test/statement.txt +++ b/test/statement.txt @@ -374,3 +374,12 @@ Script( ClassDeclaration(class,VariableDefinition,ClassBody( MethodDeclaration(Star,PropertyDefinition,ParamList,Block))), ExpressionStatement(ParenthesizedExpression(ObjectExpression(Property(Star,PropertyDefinition,ParamList,Block))))) + +# Hashbang + +#!/bin/env node +foo() + +==> + +Script(Hashbang,ExpressionStatement(CallExpression(VariableName,ArgList))) From 22d17b08c1cae6a81b16a58819a5129651ffa8f8 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 23 Aug 2023 09:12:35 +0200 Subject: [PATCH 074/133] Mark version 1.4.7 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 333db0b..23e3ea2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.4.7 (2023-08-23) + +### Bug fixes + +Properly parse hashbang comments. + ## 1.4.6 (2023-08-22) ### Bug fixes diff --git a/package.json b/package.json index 73b1703..3199d2d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.6", + "version": "1.4.7", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From f19ee2979070e7716ec6cbe3f0e74cf6715b6e54 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 22 Sep 2023 16:17:31 +0200 Subject: [PATCH 075/133] Add highlighting for using keyword FIX: Properly highlight `using` as a keyword. Closes https://github.com/lezer-parser/javascript/issues/23 --- src/highlight.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/highlight.js b/src/highlight.js index 33dc077..212a408 100644 --- a/src/highlight.js +++ b/src/highlight.js @@ -4,7 +4,7 @@ export const jsHighlight = styleTags({ "get set async static": t.modifier, "for while do if else switch try catch finally return throw break continue default case": t.controlKeyword, "in of await yield void typeof delete instanceof": t.operatorKeyword, - "let var const function class extends": t.definitionKeyword, + "let var const using function class extends": t.definitionKeyword, "import export from": t.moduleKeyword, "with debugger as new": t.keyword, TemplateString: t.special(t.string), From 22ba574e5465bb1f4626fba6c844565da34eaac0 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 5 Oct 2023 17:03:51 +0200 Subject: [PATCH 076/133] Mark version 1.4.8 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23e3ea2..aab83d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.4.8 (2023-10-05) + +### Bug fixes + +Properly highlight `using` as a keyword. + ## 1.4.7 (2023-08-23) ### Bug fixes diff --git a/package.json b/package.json index 3199d2d..e28e979 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.7", + "version": "1.4.8", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From b9c9e0c270c99e2f78a00e7713eecaf923ff7036 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 30 Oct 2023 09:21:14 +0100 Subject: [PATCH 077/133] Support 'default' binding name in import/export groups FIX: Allow `default` to be used in `import`/`export` binding sets. Closes https://github.com/lezer-parser/javascript/issues/24 --- src/javascript.grammar | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 0a39801..22c2cab 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -77,7 +77,7 @@ ExportDeclaration { } ExportGroup { - "{" commaSep (VariableName { word } | String))?> "}" + "{" commaSep<(VariableName | String | kw<"default">) (ckw<"as"> (VariableName { word } | String | kw<"default">))?> "}" } ImportDeclaration { @@ -87,7 +87,7 @@ ImportDeclaration { } ImportGroup { - "{" commaSep? (VariableDefinition | (VariableName | String) ckw<"as"> VariableDefinition)> "}" + "{" commaSep? (VariableDefinition | (VariableName | String | kw<"default">) ckw<"as"> VariableDefinition)> "}" } ForSpec { From 67e0467b404adeb31f11d6c104828593d6d7aaa4 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 30 Oct 2023 12:38:30 +0100 Subject: [PATCH 078/133] Fix previous patch --- src/javascript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 22c2cab..8175097 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -77,7 +77,7 @@ ExportDeclaration { } ExportGroup { - "{" commaSep<(VariableName | String | kw<"default">) (ckw<"as"> (VariableName { word } | String | kw<"default">))?> "}" + "{" commaSep<(VariableName | String | kw<"default">) (ckw<"as"> (VariableName { word } | String))?> "}" } ImportDeclaration { From 99629d08065e68a2e41e5fdcc2688347b6c8e191 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 30 Oct 2023 12:38:35 +0100 Subject: [PATCH 079/133] Mark version 1.4.9 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aab83d4..fbd003a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.4.9 (2023-10-30) + +### Bug fixes + +Allow `default` to be used in `import`/`export` binding sets. + ## 1.4.8 (2023-10-05) ### Bug fixes diff --git a/package.json b/package.json index e28e979..d6f4fb0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.8", + "version": "1.4.9", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 7512058bd003bc3af12179bfb0ffcb63d96f3e16 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 6 Dec 2023 10:08:10 +0100 Subject: [PATCH 080/133] Support prefix | and & operators in TS types FIX: Support `|` and `&` as prefixes in TypeScript types. Closes https://github.com/lezer-parser/javascript/issues/25 --- src/javascript.grammar | 16 ++++++++++++++-- test/typescript.txt | 20 ++++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 8175097..c574143 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -4,7 +4,9 @@ typeargs, typeMember, typePrefix, + intersectionPrefixed @left, intersection @left, + unionPrefixed @left, union @left, typeExtends @right, else @right, @@ -421,8 +423,14 @@ type[@isGroup=Type] { ArrayType { type "[" "]" | type "[" "]" } | ReadonlyType { tskw<"readonly"> !readonly type } | ObjectType | - UnionType { type !union LogicOp { "|" } type } | - IntersectionType { type !intersection LogicOp { "&" } type } | + UnionType { + type (!union unionOp type)+ | + unionOp type (!unionPrefixed unionOp type)* + } | + IntersectionType { + type (!intersection intersectionOp type)+ | + intersectionOp type (!intersectionPrefixed intersectionOp type)* + } | ConditionalType { type !typeExtends kw<"extends"> type questionOp ~arrow type LogicOp<":"> type } | ParameterizedType { (TypeName | IndexedType) !typeargs TypeArgList } | TypeName @@ -579,6 +587,10 @@ Optional { "?" } questionOp[@name=LogicOp] { "?" } +unionOp[@name=LogicOp] { "|" } + +intersectionOp[@name=LogicOp] { "&" } + @skip { spaces | newline | LineComment | BlockComment } @context trackNewline from "./tokens.js" diff --git a/test/typescript.txt b/test/typescript.txt index dd5dd95..cef51fb 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -91,13 +91,29 @@ let f: (x: number) => boolean Script( VariableDeclaration(let, VariableDefinition, TypeAnnotation( - UnionType(UnionType(TypeofType(typeof, MemberExpression(VariableName, PropertyName)), LogicOp, - IntersectionType(KeyofType(keyof, TypeName), LogicOp, IndexedType(TypeName, LiteralType(String)))), + UnionType(TypeofType(typeof, MemberExpression(VariableName, PropertyName)), LogicOp, + IntersectionType(KeyofType(keyof, TypeName), LogicOp, IndexedType(TypeName, LiteralType(String))), LogicOp, ParameterizedType(TypeName, TypeArgList(TypeName))))), VariableDeclaration(let, VariableDefinition, TypeAnnotation(TupleType(TypeName, TypeName))), VariableDeclaration(let, VariableDefinition, TypeAnnotation(FunctionSignature( ParamList(VariableDefinition, TypeAnnotation(TypeName)), Arrow, TypeName)))) +# Prefix union/intersection + +let x: + | A + | B + | C +let y: & RegExp & (& Date) + +==> + +Script( + VariableDeclaration(let,VariableDefinition,TypeAnnotation( + UnionType(LogicOp,TypeName,LogicOp,TypeName,LogicOp,TypeName))), + VariableDeclaration(let,VariableDefinition,TypeAnnotation( + IntersectionType(LogicOp,TypeName,LogicOp,ParenthesizedType(IntersectionType(LogicOp,TypeName)))))) + # Prefix cast {"dialect": "ts"} foo From 4090f5dae55b30977f63e077d82c36930267c9a1 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 6 Dec 2023 10:08:31 +0100 Subject: [PATCH 081/133] Mark version 1.4.10 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbd003a..0b5b37c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.4.10 (2023-12-06) + +### Bug fixes + +Support `|` and `&` as prefixes in TypeScript types. + ## 1.4.9 (2023-10-30) ### Bug fixes diff --git a/package.json b/package.json index d6f4fb0..19e6600 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.9", + "version": "1.4.10", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 1a9e408ab0e4b565a3b16964c9ffc541eef8169e Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 18 Dec 2023 08:41:01 +0100 Subject: [PATCH 082/133] Use commas and 'extends' to disambiguate type parameter lists from JSX tags FIX: In TSX mode, parse `` or `` as type parameters, not JSX tags. See https://discuss.codemirror.net/t/syntax-highlighting-not-working-on-large-documents/7579 --- src/javascript.grammar | 6 ++---- src/tokens.js | 37 +++++++++++++++++++++++++++++++++++-- test/typescript.txt | 13 +++++++++++++ 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index c574143..eece57e 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -602,6 +602,8 @@ intersectionOp[@name=LogicOp] { "&" } incdecPrefix[@name=ArithOp] } +@external tokens jsx from "./tokens" { JSXStartTag } + @local tokens { InterpolationStart[closedBy=InterpolationEnd] { "${" } templateEnd { "`" } @@ -693,8 +695,6 @@ intersectionOp[@name=LogicOp] { "&" } JSXAttributeValue { '"' !["]* '"' | "'" ![']* "'" } - JSXStartTag[@dialect=jsx] { "<" } - JSXStartCloseTag { "" } @@ -704,8 +704,6 @@ intersectionOp[@name=LogicOp] { "&" } JSXText { ![<{]+ } tsAngleOpen[@dialect=ts] { "<" } - - @precedence { JSXStartTag, tsAngleOpen } } @external tokens insertSemicolon from "./tokens" { insertSemi } diff --git a/src/tokens.js b/src/tokens.js index 00ffaec..8c8a1d3 100644 --- a/src/tokens.js +++ b/src/tokens.js @@ -3,12 +3,13 @@ import {ExternalTokenizer, ContextTracker} from "@lezer/lr" import {insertSemi, noSemi, incdec, incdecPrefix, - spaces, newline, BlockComment, LineComment} from "./parser.terms.js" + spaces, newline, BlockComment, LineComment, + JSXStartTag, Dialect_jsx} from "./parser.terms.js" const space = [9, 10, 11, 12, 13, 32, 133, 160, 5760, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8232, 8233, 8239, 8287, 12288] -const braceR = 125, semicolon = 59, slash = 47, star = 42, plus = 43, minus = 45 +const braceR = 125, semicolon = 59, slash = 47, star = 42, plus = 43, minus = 45, lt = 60, comma = 44 export const trackNewline = new ContextTracker({ start: false, @@ -43,3 +44,35 @@ export const incdecToken = new ExternalTokenizer((input, stack) => { } } }, {contextual: true}) + +function identifierChar(ch, start) { + return ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || ch == 95 || ch >= 192 || + !start && ch >= 48 && ch <= 57 +} + +export const jsx = new ExternalTokenizer((input, stack) => { + if (input.next != lt || !stack.dialectEnabled(Dialect_jsx)) return + input.advance() + if (input.next == slash) return + // Scan for an identifier followed by a comma or 'extends', don't + // treat this as a start tag if present. + let back = 0 + while (space.indexOf(input.next) > -1) { input.advance(); back++ } + if (identifierChar(input.next, true)) { + input.advance() + back++ + while (identifierChar(input.next, false)) { input.advance(); back++ } + while (space.indexOf(input.next) > -1) { input.advance(); back++ } + if (input.next == comma) return + for (let i = 0;; i++) { + if (i == 7) { + if (!identifierChar(input.next, true)) return + break + } + if (input.next != "extends".charCodeAt(i)) break + input.advance() + back++ + } + } + input.acceptToken(JSXStartTag, -back) +}) diff --git a/test/typescript.txt b/test/typescript.txt index cef51fb..d56a0bc 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -311,3 +311,16 @@ Script( VariableDeclaration(let,VariableDefinition,Equals, CallExpression(VariableName,TypeArgList(TypeName),ArgList(Number))), ReturnStatement(return,Number)) + +# Type parameters vs JSX {"dialect": "jsx ts"} + +let a = (f) => null +let b = () => 1 + +==> + +Script( + VariableDeclaration(let,VariableDefinition,Equals,ArrowFunction( + TypeParamList(TypeDefinition,extends,TypeName),ParamList(VariableDefinition),Arrow,null)), + VariableDeclaration(let,VariableDefinition,Equals,ArrowFunction( + TypeParamList(TypeDefinition),ParamList,Arrow,Number))) From cefe3e5d535189bf352540cb04a68dd8e7006cfd Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 18 Dec 2023 08:42:22 +0100 Subject: [PATCH 083/133] Emit tokens for the opening < in a parameter list --- src/javascript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index eece57e..3c710ff 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -686,7 +686,7 @@ intersectionOp[@name=LogicOp] { "&" } "..."[@name=Spread] "=>"[@name=Arrow] - "(" ")" "[" "]" "{" "}" ">" + "(" ")" "[" "]" "{" "}" "<" ">" "?." "." "," ";" ":" "@" From 87124a3040967ef5146bc0316e5588062de5ce13 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 18 Dec 2023 08:42:27 +0100 Subject: [PATCH 084/133] Mark version 1.4.11 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b5b37c..dcc6d7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.4.11 (2023-12-18) + +### Bug fixes + +In TSX mode, parse `` or `` as type parameters, not JSX tags. + ## 1.4.10 (2023-12-06) ### Bug fixes diff --git a/package.json b/package.json index 19e6600..6d3fae5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.10", + "version": "1.4.11", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 946910e4708f963aad0d2416782aee24f188142f Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 4 Jan 2024 12:45:01 +0100 Subject: [PATCH 085/133] Add bidi isolate information FIX: Mark strings, comments, and interpolations as isolating for bidirectional text. --- src/javascript.grammar | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 3c710ff..e627d01 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -474,25 +474,25 @@ ParamTypeList[@name=ParamList] { } @skip {} { - TemplateString { + TemplateString[isolate] { templateStart (templateEscape | templateContent | templateExpr)* templateEnd } - TemplateType { + TemplateType[isolate] { templateStart (templateContent | templateType)* templateEnd } - String { + String[isolate] { '"' (stringContentDouble | Escape)* ('"' | "\n") | "'" (stringContentSingle | Escape)* ("'" | "\n") } - BlockComment { "/*" (blockCommentContent | blockCommentNewline)* blockCommentEnd } + BlockComment[isolate] { "/*" (blockCommentContent | blockCommentNewline)* blockCommentEnd } } -templateExpr[@name=Interpolation] { InterpolationStart expression InterpolationEnd } +templateExpr[@name=Interpolation,isolate] { InterpolationStart expression InterpolationEnd } -templateType[@name=Interpolation] { InterpolationStart type InterpolationEnd } +templateType[@name=Interpolation,isolate] { InterpolationStart type InterpolationEnd } @skip {} { JSXElement { @@ -621,7 +621,7 @@ intersectionOp[@name=LogicOp] { "&" } spaces[@export] { $[\u0009 \u000b\u00a0\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]+ } newline[@export] { $[\r\n\u2028\u2029] } - LineComment { "//" ![\n]* } + LineComment[isolate] { "//" ![\n]* } Hashbang { "#!" ![\n]* } @@ -678,7 +678,7 @@ intersectionOp[@name=LogicOp] { "&" } @precedence { "*", ArithOp } - RegExp { "/" (![/\\\n[] | "\\" ![\n] | "[" (![\n\\\]] | "\\" ![\n])* "]")+ ("/" $[gimsuy]*)? } + RegExp[isolate] { "/" (![/\\\n[] | "\\" ![\n] | "[" (![\n\\\]] | "\\" ![\n])* "]")+ ("/" $[gimsuy]*)? } LessThan[@name=CompareOp] { "<" } From 1a2c36d0fa24d70825542a2f611007e3519174d0 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 4 Jan 2024 12:45:05 +0100 Subject: [PATCH 086/133] Mark version 1.4.12 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dcc6d7b..82e21db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.4.12 (2024-01-04) + +### Bug fixes + +Mark strings, comments, and interpolations as isolating for bidirectional text. + ## 1.4.11 (2023-12-18) ### Bug fixes diff --git a/package.json b/package.json index 6d3fae5..c30c848 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.11", + "version": "1.4.12", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 658d372a414062b8fd41093ec80d4b22ebe0cfe6 Mon Sep 17 00:00:00 2001 From: Andy Edwards Date: Wed, 10 Jan 2024 02:51:33 -0600 Subject: [PATCH 087/133] Fix bitwise operator precedence FIX: Fix inverted relative precedence of `&`, `|`, and `^` bitwise operators. Closes #27 --- src/javascript.grammar | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index e627d01..2bacadb 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -26,9 +26,9 @@ rel @left, satisfies, equal @left, - bitOr @left, - bitXor @left, bitAnd @left, + bitXor @left, + bitOr @left, and @left, or @left, ternary @right, From d2d76dbe77482b02bb874d8c4d3556823e19e5be Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 16 Jan 2024 16:44:21 +0100 Subject: [PATCH 088/133] Add missing @lezer/common dependency FIX: Add an explicit dependency on @lezer/common ^1.2.0. Closes https://github.com/lezer-parser/javascript/issues/29 --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index c30c848..b3cfba5 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ }, "dependencies": { "@lezer/lr": "^1.3.0", + "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.1.3" }, "repository": { From e8bbd9d318b2982902efb4267b8fb3836d18d1ff Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 16 Jan 2024 16:44:28 +0100 Subject: [PATCH 089/133] Mark version 1.4.13 --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82e21db..f236a54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.4.13 (2024-01-16) + +### Bug fixes + +Fix inverted relative precedence of `&`, `|`, and `^` bitwise operators. + +Add an explicit dependency on @lezer/common ^1.2.0. + ## 1.4.12 (2024-01-04) ### Bug fixes diff --git a/package.json b/package.json index b3cfba5..ab45fac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.12", + "version": "1.4.13", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 0d864c6b6352ad7be9a3aab395ef2bc847253dd3 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 14 Feb 2024 16:12:46 +0100 Subject: [PATCH 090/133] Add a classPopName wrapper To reduce some combinatory explosions --- src/javascript.grammar | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 2bacadb..adb9b37 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -151,11 +151,13 @@ propModifier { tsPkwMod<"override"> } +classPropName { propName | PrivatePropertyDefinition } + MethodDeclaration[group=ClassItem] { propModifier* pkwMod<"async">? (pkwMod<"get"> | pkwMod<"set"> | Star)? - (propName | PrivatePropertyDefinition) + classPropName functionSignature (Block | semi) } @@ -167,7 +169,7 @@ StaticBlock[group=ClassItem] { PropertyDeclaration[group=ClassItem] { propModifier* (tsPkwMod<"readonly"> | pkwMod<"accessor">)? - (propName | PrivatePropertyDefinition) + classPropName (Optional | LogicOp<"!">)? TypeAnnotation? ("=" expressionNoComma)? From 392c6115647c9e55c147ac2d702f75be127a7b2d Mon Sep 17 00:00:00 2001 From: Alex Errant <109672176+AlexErrant@users.noreply.github.com> Date: Sat, 23 Mar 2024 02:14:11 -0500 Subject: [PATCH 091/133] Add more regex flags (#30) FIX: Recognize the `d` and `v` RegExp flags. --- src/javascript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index adb9b37..7a642ff 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -680,7 +680,7 @@ intersectionOp[@name=LogicOp] { "&" } @precedence { "*", ArithOp } - RegExp[isolate] { "/" (![/\\\n[] | "\\" ![\n] | "[" (![\n\\\]] | "\\" ![\n])* "]")+ ("/" $[gimsuy]*)? } + RegExp[isolate] { "/" (![/\\\n[] | "\\" ![\n] | "[" (![\n\\\]] | "\\" ![\n])* "]")+ ("/" $[dgimsuvy]*)? } LessThan[@name=CompareOp] { "<" } From 63d0fc2689cb8e1e437e7c29786b3aa39b36d560 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Sat, 30 Mar 2024 19:49:48 +0100 Subject: [PATCH 092/133] Support destructured parameters in function types FIX: Allow destructured parameters in function signature types. Closes https://github.com/codemirror/dev/issues/1364 --- src/javascript.grammar | 10 +++++----- test/typescript.txt | 11 +++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 7a642ff..c3aba6f 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -421,7 +421,7 @@ type[@isGroup=Type] { FunctionSignature { TypeParamList? ParamTypeList "=>" type } | NewSignature { kw<"new"> ParamTypeList "=>" type } | IndexedType | - TupleType { "[" commaSep<(Label ":")? type | "..." type> "]" } | + TupleType { "[" commaSep<(Label ":")? type | "..." type> ~destructure "]" } | ArrayType { type "[" "]" | type "[" "]" } | ReadonlyType { tskw<"readonly"> !readonly type } | ObjectType | @@ -450,7 +450,7 @@ ObjectType { CallSignature { ParamTypeList (TypeAnnotation | TypePredicate) } | NewSignature[@dynamicPrecedence=1] { @extend[@name=new] ParamTypeList TypeAnnotation }) ("," | semi) - )* "}" + )* ~destructure "}" } IndexSignature { @@ -472,7 +472,7 @@ PropertyType { } ParamTypeList[@name=ParamList] { - "(" commaSep<"..."? VariableDefinition ~arrow Optional? ~arrow TypeAnnotation?> ")" + "(" commaSep<"..."? pattern ~arrow Optional? ~arrow TypeAnnotation?> ")" } @skip {} { @@ -577,9 +577,9 @@ TypeName { identifier ~arrow } Label { identifier } -PropertyName { word } +PropertyName { word ~propName } -PropertyDefinition { word } +PropertyDefinition { word ~propName } PrivatePropertyName { privateIdentifier } diff --git a/test/typescript.txt b/test/typescript.txt index d56a0bc..a6f74de 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -324,3 +324,14 @@ Script( TypeParamList(TypeDefinition,extends,TypeName),ParamList(VariableDefinition),Arrow,null)), VariableDeclaration(let,VariableDefinition,Equals,ArrowFunction( TypeParamList(TypeDefinition),ParamList,Arrow,Number))) + +# Destructured parameters in function signature {"dialect": "ts"} + +type F = ([a, b]: [number, number]) => void + +==> + +Script(TypeAliasDeclaration(type,TypeDefinition,Equals,FunctionSignature( + ParamList(ArrayPattern(VariableDefinition,VariableDefinition),TypeAnnotation(TupleType(TypeName,TypeName))), + Arrow, + VoidType(void)))) From b7dd6f073dd06c965cbebc5987bd14a53f02c70f Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Sat, 30 Mar 2024 19:51:14 +0100 Subject: [PATCH 093/133] Mark version 1.4.14 --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f236a54..182db9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.4.14 (2024-03-30) + +### Bug fixes + +Recognize the `d` and `v` RegExp flags. Support destructured parameters in function types + +Allow destructured parameters in function signature types. + ## 1.4.13 (2024-01-16) ### Bug fixes diff --git a/package.json b/package.json index ab45fac..afda2e7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.13", + "version": "1.4.14", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 49aefe8f664a9ea62c5314a284a0891335504d5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Z=C3=BCnd?= Date: Tue, 23 Apr 2024 08:43:46 +0200 Subject: [PATCH 094/133] Support new.target FIX: Add support for `new.target` syntax. Issue https://github.com/lezer-parser/javascript/pull/32 --- src/javascript.grammar | 1 + test/statement.txt | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/javascript.grammar b/src/javascript.grammar index c3aba6f..bf225c9 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -285,6 +285,7 @@ expressionNoComma { RegExp | ArrayExpression | ObjectExpression { "{" commaSep ~destructure "}" } | + NewTarget { kw<"new"> "." PropertyName } | NewExpression { kw<"new"> expressionNoComma (!newArgs TypeArgList? ArgList)? } | UnaryExpression | YieldExpression | diff --git a/test/statement.txt b/test/statement.txt index a8313a7..9243488 100644 --- a/test/statement.txt +++ b/test/statement.txt @@ -383,3 +383,18 @@ foo() ==> Script(Hashbang,ExpressionStatement(CallExpression(VariableName,ArgList))) + +# new.target + +function MyObj() { + if (!new.target) { + throw new Error('Must construct MyObj with new'); + } +} + +==> + +Script( + FunctionDeclaration(function,VariableDefinition,ParamList,Block( + IfStatement(if,ParenthesizedExpression(UnaryExpression(LogicOp,NewTarget(new,PropertyName))), Block( + ThrowStatement(throw,NewExpression(new,VariableName,ArgList(String)))))))) From fca757bffc4f302241558a4d7c35062630af8487 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 23 Apr 2024 08:45:48 +0200 Subject: [PATCH 095/133] Mark version 1.4.15 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 182db9b..550bf37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.4.15 (2024-04-23) + +### Bug fixes + +Add support for `new.target` syntax. + ## 1.4.14 (2024-03-30) ### Bug fixes diff --git a/package.json b/package.json index afda2e7..21ed37e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.14", + "version": "1.4.15", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From d31ea1a7ac6fc36084a71828f235549ca9301e02 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 23 Apr 2024 11:17:43 +0200 Subject: [PATCH 096/133] Don't tokenizer ?. when followed by a digit FIX: Don't consume `?.` tokens when followed by a digit. Closes https://github.com/lezer-parser/javascript/issues/33 --- src/javascript.grammar | 15 ++++++++------- src/tokens.js | 11 ++++++++--- test/expression.txt | 8 ++++++++ 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index bf225c9..1d3d186 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -226,8 +226,8 @@ AmbientDeclaration { decoratorExpression { VariableName | - MemberExpression { decoratorExpression !member ("." | "?.") (PropertyName | PrivatePropertyName) } | - CallExpression { decoratorExpression !call TypeArgList? "?."? ArgList } | + MemberExpression { decoratorExpression !member ("." | questionDot) (PropertyName | PrivatePropertyName) } | + CallExpression { decoratorExpression !call TypeArgList? questionDot? ArgList } | ParenthesizedExpression } @@ -299,7 +299,7 @@ expressionNoComma { ConditionalExpression { expressionNoComma !ternary questionOp expressionNoComma LogicOp<":"> expressionNoComma } | AssignmentExpression | PostfixExpression { expressionNoComma !postfix (incdec | LogicOp<"!">) } | - CallExpression { expressionNoComma !call TypeArgList? "?."? ArgList } | + CallExpression { expressionNoComma !call TypeArgList? questionDot? ArgList } | TaggedTemplateExpression { expressionNoComma !taggedTemplate TemplateString } | DynamicImport { kw<"import"> "(" expressionNoComma ")" } | ImportMeta { kw<"import"> "." PropertyName } | @@ -378,7 +378,7 @@ AssignmentExpression { } MemberExpression { - expressionNoComma !member (("." | "?.") (PropertyName | PrivatePropertyName) | "?."? "[" expression "]") + expressionNoComma !member (("." | questionDot) (PropertyName | PrivatePropertyName) | questionDot? "[" expression "]") } ArgList { @@ -400,7 +400,7 @@ TypeParamList { typeParam { TypeDefinition ~tsAngle (kw<"extends"> type)? ("=" type)? } typeofMemberExpression[@name=MemberExpression] { - VariableName !member (("." | "?.") PropertyName | "[" expression "]") + VariableName !member (("." | questionDot) PropertyName | "[" expression "]") } type[@isGroup=Type] { @@ -600,9 +600,10 @@ intersectionOp[@name=LogicOp] { "&" } @external tokens noSemicolon from "./tokens" { noSemi } -@external tokens incdecToken from "./tokens" { +@external tokens operatorToken from "./tokens" { incdec[@name=ArithOp], incdecPrefix[@name=ArithOp] + questionDot[@name="?."] } @external tokens jsx from "./tokens" { JSXStartTag } @@ -691,7 +692,7 @@ intersectionOp[@name=LogicOp] { "&" } "(" ")" "[" "]" "{" "}" "<" ">" - "?." "." "," ";" ":" "@" + "." "," ";" ":" "@" JSXIdentifier { $[A-Z_$\u{a1}-\u{10ffff}] (identifierChar | @digit | "-")* } JSXLowerIdentifier[@name=JSXIdentifier] { $[a-z] (identifierChar | @digit | "-")* } diff --git a/src/tokens.js b/src/tokens.js index 8c8a1d3..8cab7b5 100644 --- a/src/tokens.js +++ b/src/tokens.js @@ -2,14 +2,15 @@ expressed by lezer's built-in tokenizer. */ import {ExternalTokenizer, ContextTracker} from "@lezer/lr" -import {insertSemi, noSemi, incdec, incdecPrefix, +import {insertSemi, noSemi, incdec, incdecPrefix, questionDot, spaces, newline, BlockComment, LineComment, JSXStartTag, Dialect_jsx} from "./parser.terms.js" const space = [9, 10, 11, 12, 13, 32, 133, 160, 5760, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8232, 8233, 8239, 8287, 12288] -const braceR = 125, semicolon = 59, slash = 47, star = 42, plus = 43, minus = 45, lt = 60, comma = 44 +const braceR = 125, semicolon = 59, slash = 47, star = 42, plus = 43, minus = 45, lt = 60, comma = 44, + question = 63, dot = 46 export const trackNewline = new ContextTracker({ start: false, @@ -33,7 +34,7 @@ export const noSemicolon = new ExternalTokenizer((input, stack) => { input.acceptToken(noSemi) }, {contextual: true}) -export const incdecToken = new ExternalTokenizer((input, stack) => { +export const operatorToken = new ExternalTokenizer((input, stack) => { let {next} = input if (next == plus || next == minus) { input.advance() @@ -42,6 +43,10 @@ export const incdecToken = new ExternalTokenizer((input, stack) => { let mayPostfix = !stack.context && stack.canShift(incdec) input.acceptToken(mayPostfix ? incdec : incdecPrefix) } + } else if (next == question && input.peek(1) == dot) { + input.advance(); input.advance() + if (input.next < 48 || input.next > 57) // No digit after + input.acceptToken(questionDot) } }, {contextual: true}) diff --git a/test/expression.txt b/test/expression.txt index 6c68d51..2666aa7 100644 --- a/test/expression.txt +++ b/test/expression.txt @@ -676,3 +676,11 @@ Script(ExpressionStatement(ConditionalExpression(Number,LogicOp,Number,⚠))) ==> Script(ExpressionStatement(TemplateString(⚠))) + +# Ternary with leading-dot number + +a?.2:.3 + +==> + +Script(ExpressionStatement(ConditionalExpression(VariableName,LogicOp,Number,LogicOp,Number))) From 034abc88382891bba7bc0369b541fd360ce91a4e Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Sat, 4 May 2024 06:42:09 +0200 Subject: [PATCH 097/133] Add support for stand-alone instantiated expressions FIX: Support type arguments on non-call expressions. Closes https://github.com/codemirror/dev/issues/1377 --- src/javascript.grammar | 14 +++++++++----- test/typescript.txt | 29 ++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 1d3d186..4e21a97 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -14,6 +14,7 @@ readonly, newArgs, call, + instantiate, taggedTemplate, prefix, postfix, @@ -286,7 +287,7 @@ expressionNoComma { ArrayExpression | ObjectExpression { "{" commaSep ~destructure "}" } | NewTarget { kw<"new"> "." PropertyName } | - NewExpression { kw<"new"> expressionNoComma (!newArgs TypeArgList? ArgList)? } | + NewExpression { kw<"new"> expressionNoComma (!newArgs ArgList)? } | UnaryExpression | YieldExpression | AwaitExpression | @@ -299,7 +300,8 @@ expressionNoComma { ConditionalExpression { expressionNoComma !ternary questionOp expressionNoComma LogicOp<":"> expressionNoComma } | AssignmentExpression | PostfixExpression { expressionNoComma !postfix (incdec | LogicOp<"!">) } | - CallExpression { expressionNoComma !call TypeArgList? questionDot? ArgList } | + CallExpression { expressionNoComma !call questionDot? ArgList } | + InstantiationExpression { (VariableName | MemberExpression) !instantiate TypeArgList } | TaggedTemplateExpression { expressionNoComma !taggedTemplate TemplateString } | DynamicImport { kw<"import"> "(" expressionNoComma ")" } | ImportMeta { kw<"import"> "." PropertyName } | @@ -399,8 +401,10 @@ TypeParamList { typeParam { TypeDefinition ~tsAngle (kw<"extends"> type)? ("=" type)? } -typeofMemberExpression[@name=MemberExpression] { - VariableName !member (("." | questionDot) PropertyName | "[" expression "]") +typeofExpression { + MemberExpression { typeofExpression !member (("." | questionDot) PropertyName | "[" expression "]") } | + InstantiationExpression { typeofExpression !instantiate TypeArgList } | + VariableName } type[@isGroup=Type] { @@ -413,7 +417,7 @@ type[@isGroup=Type] { TemplateType | NullType { kw<"null"> } | VoidType { kw<"void"> } | - TypeofType { kw<"typeof"> (VariableName | typeofMemberExpression) } | + TypeofType { kw<"typeof"> typeofExpression } | KeyofType { !typePrefix tskw<"keyof"> type } | UniqueType { !typePrefix tskw<"unique"> type } | ImportType { kw<"import"> "(" String ")" } | diff --git a/test/typescript.txt b/test/typescript.txt index a6f74de..f67404a 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -76,9 +76,9 @@ x < 10 > 5 Script( ExpressionStatement(BinaryExpression( - CallExpression(VariableName, TypeArgList(TypeName, TypeName), ArgList), + CallExpression(InstantiationExpression(VariableName, TypeArgList(TypeName, TypeName)), ArgList), ArithOp, - NewExpression(new, VariableName, TypeArgList(LiteralType(Number)), ArgList))), + NewExpression(new, InstantiationExpression(VariableName, TypeArgList(LiteralType(Number))), ArgList))), ExpressionStatement(BinaryExpression(BinaryExpression(VariableName, CompareOp, Number), CompareOp, Number))) # Advanced types {"dialect": "ts"} @@ -309,7 +309,7 @@ return 2 Script( VariableDeclaration(let,VariableDefinition,Equals, - CallExpression(VariableName,TypeArgList(TypeName),ArgList(Number))), + CallExpression(InstantiationExpression(VariableName,TypeArgList(TypeName)),ArgList(Number))), ReturnStatement(return,Number)) # Type parameters vs JSX {"dialect": "jsx ts"} @@ -335,3 +335,26 @@ Script(TypeAliasDeclaration(type,TypeDefinition,Equals,FunctionSignature( ParamList(ArrayPattern(VariableDefinition,VariableDefinition),TypeAnnotation(TupleType(TypeName,TypeName))), Arrow, VoidType(void)))) + +# Instantiated expression {"dialect": "ts"} + +let x = a; + +type Foo = Bar>>; + +==> + +Script( + VariableDeclaration(let,VariableDefinition,Equals,InstantiationExpression(VariableName,TypeArgList(TypeName))), + TypeAliasDeclaration(type,TypeDefinition,Equals,ParameterizedType(TypeName,TypeArgList( + TypeofType(typeof,InstantiationExpression(VariableName,TypeArgList( + ParameterizedType(TypeName,TypeArgList(TypeName))))))))) + +# Not instantiated {"dialect": "ts"} + +let x = ac + +==> + +Script(VariableDeclaration(let,VariableDefinition,Equals,BinaryExpression( + BinaryExpression(VariableName,CompareOp,VariableName),CompareOp,VariableName))) From b3775dc544f97b66cee02dc324c0cd6f5a532dea Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Sat, 4 May 2024 06:42:51 +0200 Subject: [PATCH 098/133] Mark version 1.4.16 --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 550bf37..c8e352c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.4.16 (2024-05-04) + +### Bug fixes + +Don't consume `?.` tokens when followed by a digit. + +Support type arguments on non-call expressions. + ## 1.4.15 (2024-04-23) ### Bug fixes diff --git a/package.json b/package.json index 21ed37e..399ced5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.15", + "version": "1.4.16", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 0f89f5b25d176b3a087951d5f5e3d41de01fd90b Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 11 Jun 2024 17:04:21 +0200 Subject: [PATCH 099/133] Support TS -readonly / -? syntax in mapped object types FIX: Add support for `{-readonly [K in T]-?: U}` TypeScript syntax. Closes https://github.com/lezer-parser/javascript/issues/36 --- src/javascript.grammar | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 4e21a97..32f594d 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -352,14 +352,14 @@ AwaitExpression[@dynamicPrecedence=1] { UnaryExpression { !prefix (kw<"void"> | kw<"typeof"> | kw<"delete"> | - LogicOp<"!"> | BitOp<"~"> | incdec | incdecPrefix | ArithOp<"+" | "-">) + LogicOp<"!"> | BitOp<"~"> | incdec | incdecPrefix | plusMin) expressionNoComma } BinaryExpression { expressionNoComma !exp ArithOp<"**"> expressionNoComma | expressionNoComma !times (divide | ArithOp<"%"> | ArithOp<"*">) expressionNoComma | - expressionNoComma !plus ArithOp<"+" | "-"> expressionNoComma | + expressionNoComma !plus plusMin expressionNoComma | expressionNoComma !shift BitOp<">>" ">"? | "<<"> expressionNoComma | expressionNoComma !rel (LessThan | CompareOp<"<=" | ">" "="?> | kw<"instanceof">) expressionNoComma | expressionNoComma !satisfies tskw<"satisfies"> type | @@ -410,7 +410,7 @@ typeofExpression { type[@isGroup=Type] { ThisType { kw<"this"> } | LiteralType { - ArithOp<"+" | "-">? Number | + plusMin? Number | boolean | String } | @@ -459,7 +459,10 @@ ObjectType { } IndexSignature { - tsPkwMod<"readonly">? "[" PropertyDefinition { identifier } (TypeAnnotation | ~tsIn kw<"in"> type) "]" TypeAnnotation + (plusMin? tsPkwMod<"readonly">)? + "[" PropertyDefinition { identifier } (TypeAnnotation | ~tsIn kw<"in"> type) "]" + (plusMin? Optional)? + TypeAnnotation } MethodType { @@ -470,9 +473,9 @@ MethodType { } PropertyType { - (ArithOp<"+" | "-">? tsPkwMod<"readonly">)? + (plusMin? tsPkwMod<"readonly">)? PropertyDefinition - (ArithOp<"+" | "-">? Optional)? + (plusMin? Optional)? TypeAnnotation } @@ -596,6 +599,8 @@ questionOp[@name=LogicOp] { "?" } unionOp[@name=LogicOp] { "|" } +plusMin { ArithOp<"+" | "-"> } + intersectionOp[@name=LogicOp] { "&" } @skip { spaces | newline | LineComment | BlockComment } From 2c20fdd8771129fffcb8a93591b26f8769a320ba Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 11 Jun 2024 17:04:29 +0200 Subject: [PATCH 100/133] Mark version 1.4.17 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8e352c..c5a025e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.4.17 (2024-06-11) + +### Bug fixes + +Add support for `{-readonly [K in T]-?: U}` TypeScript syntax. + ## 1.4.16 (2024-05-04) ### Bug fixes diff --git a/package.json b/package.json index 399ced5..1bd2bb7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.16", + "version": "1.4.17", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From be6eaf3695d6351d1848c4e1505bc0a3d3e5e5a6 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 17 Jun 2024 13:47:05 +0200 Subject: [PATCH 101/133] Add support for 'as' syntax in mapped types FIX: Support `as` syntax in mapped object types. --- src/javascript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 32f594d..0e85b91 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -460,7 +460,7 @@ ObjectType { IndexSignature { (plusMin? tsPkwMod<"readonly">)? - "[" PropertyDefinition { identifier } (TypeAnnotation | ~tsIn kw<"in"> type) "]" + "[" PropertyDefinition { identifier } (TypeAnnotation | ~tsIn kw<"in"> type (ckw<"as"> type)?) "]" (plusMin? Optional)? TypeAnnotation } From 04ede4af79777370cdb3fbf0751ee3f58d1c9af2 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 25 Jun 2024 08:13:53 +0200 Subject: [PATCH 102/133] Allow empty scripts --- src/javascript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 0e85b91..805e287 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -39,7 +39,7 @@ predicate } -@top Script { Hashbang? statement+ } +@top Script { Hashbang? statement* } @top SingleExpression { expression } From 224d9a66e6a5a33ccd5d382c1f82d2b0ea1c4a90 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 17 Sep 2024 07:57:50 +0200 Subject: [PATCH 103/133] Accept interpolations with missing expressions FIX: Make sure the parser doesn't get confused when a template interpolation is missing its expression. Closes https://github.com/codemirror/dev/issues/1441 --- src/javascript.grammar | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 805e287..bab4f3d 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -500,9 +500,9 @@ ParamTypeList[@name=ParamList] { BlockComment[isolate] { "/*" (blockCommentContent | blockCommentNewline)* blockCommentEnd } } -templateExpr[@name=Interpolation,isolate] { InterpolationStart expression InterpolationEnd } +templateExpr[@name=Interpolation,isolate] { InterpolationStart expression? InterpolationEnd } -templateType[@name=Interpolation,isolate] { InterpolationStart type InterpolationEnd } +templateType[@name=Interpolation,isolate] { InterpolationStart type? InterpolationEnd } @skip {} { JSXElement { From 34e5de4cb57fe3ef3d8d278c231a634b1f2bad9f Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 17 Sep 2024 07:58:00 +0200 Subject: [PATCH 104/133] Mark version 1.4.18 --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5a025e..cc79f04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.4.18 (2024-09-17) + +### Bug fixes + +Support `as` syntax in mapped object types. + +Make sure the parser doesn't get confused when a template interpolation is missing its expression. + ## 1.4.17 (2024-06-11) ### Bug fixes diff --git a/package.json b/package.json index 1bd2bb7..b71cd88 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.17", + "version": "1.4.18", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From ab896bd331df9f66432db72a39cb51e406f39b27 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 8 Oct 2024 15:44:49 +0200 Subject: [PATCH 105/133] Allow method types to have an optional marker FIX: Support question marks after method names in TypeScript object type notation. Closes https://github.com/lezer-parser/javascript/issues/37 --- src/javascript.grammar | 1 + 1 file changed, 1 insertion(+) diff --git a/src/javascript.grammar b/src/javascript.grammar index bab4f3d..20fae46 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -469,6 +469,7 @@ MethodType { pkwMod<"async">? (pkwMod<"get"> | pkwMod<"set"> | Star)? PropertyDefinition + (plusMin? Optional)? functionSignature } From aef4de7f7d2819d2405238eecdc3113fc1028d35 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 8 Oct 2024 16:16:37 +0200 Subject: [PATCH 106/133] Support computed property notation in object types FIX: Support bracketed property names in TypeScript object types. Closes https://github.com/lezer-parser/javascript/issues/38 --- src/javascript.grammar | 12 +++++++----- src/tokens.js | 8 ++++++-- test/typescript.txt | 14 ++++++++++++++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 20fae46..3fd49c8 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -318,7 +318,7 @@ ArrayExpression { "[" commaSep1<"..."? expressionNoComma | ""> ~destructure "]" } -propName { PropertyDefinition | "[" expression "]" | Number | String } +propName { PropertyDefinition | "[" expression "]" ~destructure | Number ~destructure | String ~destructure } Property { pkwMod<"async">? (pkwMod<"get"> | pkwMod<"set"> | Star)? propName functionSignature Block | @@ -427,7 +427,7 @@ type[@isGroup=Type] { NewSignature { kw<"new"> ParamTypeList "=>" type } | IndexedType | TupleType { "[" commaSep<(Label ":")? type | "..." type> ~destructure "]" } | - ArrayType { type "[" "]" | type "[" "]" } | + ArrayType { type noSemiType "[" "]" } | ReadonlyType { tskw<"readonly"> !readonly type } | ObjectType | UnionType { @@ -444,7 +444,7 @@ type[@isGroup=Type] { } IndexedType { - type !typeMember ("." TypeName | "[" type "]")+ + type !typeMember ("." TypeName | noSemiType "[" type "]")+ } ObjectType { @@ -468,14 +468,14 @@ IndexSignature { MethodType { pkwMod<"async">? (pkwMod<"get"> | pkwMod<"set"> | Star)? - PropertyDefinition + propName (plusMin? Optional)? functionSignature } PropertyType { (plusMin? tsPkwMod<"readonly">)? - PropertyDefinition + propName (plusMin? Optional)? TypeAnnotation } @@ -610,6 +610,8 @@ intersectionOp[@name=LogicOp] { "&" } @external tokens noSemicolon from "./tokens" { noSemi } +@external tokens noSemicolonType from "./tokens" { noSemiType } + @external tokens operatorToken from "./tokens" { incdec[@name=ArithOp], incdecPrefix[@name=ArithOp] diff --git a/src/tokens.js b/src/tokens.js index 8cab7b5..299102e 100644 --- a/src/tokens.js +++ b/src/tokens.js @@ -2,7 +2,7 @@ expressed by lezer's built-in tokenizer. */ import {ExternalTokenizer, ContextTracker} from "@lezer/lr" -import {insertSemi, noSemi, incdec, incdecPrefix, questionDot, +import {insertSemi, noSemi, noSemiType, incdec, incdecPrefix, questionDot, spaces, newline, BlockComment, LineComment, JSXStartTag, Dialect_jsx} from "./parser.terms.js" @@ -10,7 +10,7 @@ const space = [9, 10, 11, 12, 13, 32, 133, 160, 5760, 8192, 8193, 8194, 8195, 81 8201, 8202, 8232, 8233, 8239, 8287, 12288] const braceR = 125, semicolon = 59, slash = 47, star = 42, plus = 43, minus = 45, lt = 60, comma = 44, - question = 63, dot = 46 + question = 63, dot = 46, bracketL = 91 export const trackNewline = new ContextTracker({ start: false, @@ -34,6 +34,10 @@ export const noSemicolon = new ExternalTokenizer((input, stack) => { input.acceptToken(noSemi) }, {contextual: true}) +export const noSemicolonType = new ExternalTokenizer((input, stack) => { + if (input.next == bracketL && !stack.context) input.acceptToken(noSemiType) +}, {contextual: true}) + export const operatorToken = new ExternalTokenizer((input, stack) => { let {next} = input if (next == plus || next == minus) { diff --git a/test/typescript.txt b/test/typescript.txt index f67404a..f20e828 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -358,3 +358,17 @@ let x = ac Script(VariableDeclaration(let,VariableDefinition,Equals,BinaryExpression( BinaryExpression(VariableName,CompareOp,VariableName),CompareOp,VariableName))) + +# Allows computed properties in types {"dialect": "ts"} + +interface X { + [Symbol.iterator](): Iterator + [1]: string +} + +==> + +Script(InterfaceDeclaration(interface,TypeDefinition,ObjectType( + MethodType(MemberExpression(VariableName,PropertyName),ParamList, + TypeAnnotation(ParameterizedType(TypeName,TypeArgList(TypeName)))), + PropertyType(Number,TypeAnnotation(TypeName))))) From 075debcf14494e6dc54e73125c9c7a507ae1275f Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 8 Oct 2024 16:17:53 +0200 Subject: [PATCH 107/133] Allow interfaces to extend multiple types FIX: Allow TypeScript interface declarations to extend multiple types. Closes https://github.com/lezer-parser/javascript/issues/39 --- src/javascript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 3fd49c8..d75358e 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -190,7 +190,7 @@ TypeAliasDeclaration { } InterfaceDeclaration { - tskw<"interface"> TypeDefinition TypeParamList? (kw<"extends"> type)? ObjectType + tskw<"interface"> TypeDefinition TypeParamList? (kw<"extends"> commaSep1)? ObjectType } EnumDeclaration { From 04cf4a08c03172c119fe26b58452d7a04c238de7 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 8 Oct 2024 17:40:45 +0200 Subject: [PATCH 108/133] Mark version 1.4.19 --- CHANGELOG.md | 10 ++++++++++ package.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc79f04..6d92712 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## 1.4.19 (2024-10-08) + +### Bug fixes + +Support question marks after method names in TypeScript object type notation. + +Support bracketed property names in TypeScript object types. + +Allow TypeScript interface declarations to extend multiple types. + ## 1.4.18 (2024-09-17) ### Bug fixes diff --git a/package.json b/package.json index b71cd88..29db276 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.18", + "version": "1.4.19", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 609878a0279c1a2c4636f1dbeef9c4f697549506 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Sat, 23 Nov 2024 15:06:17 +0100 Subject: [PATCH 109/133] Style variables used with new as class names FIX: Use the `className` style tag for variable names used as constructors with `new`. See https://discuss.codemirror.net/t/javascript-highlighting-class-name-in-a-new-expression/8835 --- src/highlight.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/highlight.js b/src/highlight.js index 212a408..221edca 100644 --- a/src/highlight.js +++ b/src/highlight.js @@ -22,6 +22,7 @@ export const jsHighlight = styleTags({ "CallExpression/MemberExpression/PropertyName": t.function(t.propertyName), "FunctionDeclaration/VariableDefinition": t.function(t.definition(t.variableName)), "ClassDeclaration/VariableDefinition": t.definition(t.className), + "NewExpression/VariableName": t.className, PropertyDefinition: t.definition(t.propertyName), PrivatePropertyDefinition: t.definition(t.special(t.propertyName)), UpdateOp: t.updateOperator, From b142c2a50314a2f361c47d624d9d41f70f05f3a1 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 26 Nov 2024 08:54:07 +0100 Subject: [PATCH 110/133] Drop outdated ES version in readme Closes https://github.com/lezer-parser/javascript/issues/40 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d4e9fc..f979492 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This is a JavaScript grammar for the [lezer](https://lezer.codemirror.net/) parser system. -It parses ES2020, and supports a `"ts"` +It parses modern JavaScript, and supports a `"ts"` [dialect](https://lezer.codemirror.net/docs/guide/#dialects) to parse TypeScript, and a `"jsx"` dialect to parse JSX. From eb6fb1d21d7d56d09f2f43d68678f7839d44ea0f Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 2 Dec 2024 15:26:41 +0100 Subject: [PATCH 111/133] Support asserts TypeScript function signatures FIX: Add support for `asserts` syntax in function return types. Closes https://github.com/lezer-parser/javascript/issues/41 --- src/highlight.js | 2 +- src/javascript.grammar | 2 +- test/typescript.txt | 12 +++++++++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/highlight.js b/src/highlight.js index 221edca..71b03df 100644 --- a/src/highlight.js +++ b/src/highlight.js @@ -51,7 +51,7 @@ export const jsHighlight = styleTags({ TypeDefinition: t.definition(t.typeName), "type enum interface implements namespace module declare": t.definitionKeyword, "abstract global Privacy readonly override": t.modifier, - "is keyof unique infer": t.operatorKeyword, + "is keyof unique infer asserts": t.operatorKeyword, JSXAttributeValue: t.attributeValue, JSXText: t.content, diff --git a/src/javascript.grammar b/src/javascript.grammar index d75358e..dd74251 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -246,7 +246,7 @@ patternAssign { TypeAnnotation { ":" type } -TypePredicate { ":" (VariableName | kw<"this">) !predicate tskw<"is"> type } +TypePredicate { ":" tskw<"asserts">? (VariableName | kw<"this">) !predicate tskw<"is"> type } patternAssignTyped { pattern Optional? TypeAnnotation? ("=" expressionNoComma)? diff --git a/test/typescript.txt b/test/typescript.txt index f20e828..93c0d06 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -26,11 +26,17 @@ Script(FunctionDeclaration(function, VariableDefinition, ParamList( function isFoo(foo: any): foo is Foo { return true } +function assertFoo(foo: any): asserts foo is "string" { return true } + ==> -Script(FunctionDeclaration(function, VariableDefinition, ParamList( - VariableDefinition, TypeAnnotation(TypeName) -), TypePredicate(VariableName, is, TypeName), Block(ReturnStatement(return, BooleanLiteral)))) +Script( + FunctionDeclaration(function, VariableDefinition, ParamList( + VariableDefinition, TypeAnnotation(TypeName) + ), TypePredicate(VariableName, is, TypeName), Block(ReturnStatement(return, BooleanLiteral))), + FunctionDeclaration(function,VariableDefinition,ParamList( + VariableDefinition,TypeAnnotation(TypeName) + ),TypePredicate(asserts,VariableName,is,LiteralType(String)),Block(ReturnStatement(return,BooleanLiteral)))) # Type alias {"dialect": "ts"} From 4bce3bff438538a0af2651765d3c142b43cadee1 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 2 Dec 2024 15:26:54 +0100 Subject: [PATCH 112/133] Mark version 1.4.20 --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d92712..7a5b3a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.4.20 (2024-12-02) + +### Bug fixes + +Use the `className` style tag for variable names used as constructors with `new`. + +Add support for `asserts` syntax in function return types. + ## 1.4.19 (2024-10-08) ### Bug fixes diff --git a/package.json b/package.json index 29db276..6288549 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.19", + "version": "1.4.20", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 002c1669e43dc1a5cb9393db624a653a0d7ee860 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 2 Dec 2024 15:42:54 +0100 Subject: [PATCH 113/133] Support const modifier on type parameters FIX: Add support for `const` modifiers on TypeScript type parameters. Closes https://github.com/lezer-parser/javascript/issues/42 --- src/javascript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index dd74251..a1105ad 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -399,7 +399,7 @@ TypeParamList { "<" commaSep ">" } -typeParam { TypeDefinition ~tsAngle (kw<"extends"> type)? ("=" type)? } +typeParam { kw<"const">? TypeDefinition ~tsAngle (kw<"extends"> type)? ("=" type)? } typeofExpression { MemberExpression { typeofExpression !member (("." | questionDot) PropertyName | "[" expression "]") } | From eb9561878b2f272e5f7e70cfa596a490aa0a30d9 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 3 Dec 2024 12:57:04 +0100 Subject: [PATCH 114/133] Support asserts syntax without predicate FIX: Allow TypeScript syntax, where the condition is just a variable. Issue https://github.com/lezer-parser/javascript/issues/41 --- src/javascript.grammar | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index a1105ad..b4e5423 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -246,7 +246,12 @@ patternAssign { TypeAnnotation { ":" type } -TypePredicate { ":" tskw<"asserts">? (VariableName | kw<"this">) !predicate tskw<"is"> type } +TypePredicate { + ":" ( + tskw<"asserts">? (VariableName | kw<"this">) (tskw<"is"> type)? | + (VariableName | kw<"this">) !predicate tskw<"is"> type + ) +} patternAssignTyped { pattern Optional? TypeAnnotation? ("=" expressionNoComma)? From 30f42b3479311e90e6ffd798fe5de592eb1fa5b9 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 3 Dec 2024 13:00:08 +0100 Subject: [PATCH 115/133] Solve conflict caused by previous patch --- src/javascript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index b4e5423..b6c2b1f 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -248,7 +248,7 @@ TypeAnnotation { ":" type } TypePredicate { ":" ( - tskw<"asserts">? (VariableName | kw<"this">) (tskw<"is"> type)? | + tskw<"asserts">? (VariableName | kw<"this">) !predicate (tskw<"is"> type)? | (VariableName | kw<"this">) !predicate tskw<"is"> type ) } From d10ec797ca5b1fca0d84ee08149164558b2d36dc Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 3 Dec 2024 13:00:46 +0100 Subject: [PATCH 116/133] Give the tsAngleOpen token a name FIX: Fix a bug where some TypeScript `<` tokens didn't appear in the syntax tree. Closes https://github.com/lezer-parser/javascript/issues/43 --- src/javascript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index b6c2b1f..93d774d 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -724,7 +724,7 @@ intersectionOp[@name=LogicOp] { "&" } JSXText { ![<{]+ } - tsAngleOpen[@dialect=ts] { "<" } + tsAngleOpen[@dialect=ts,@name="<"] { "<" } } @external tokens insertSemicolon from "./tokens" { insertSemi } From 2f52d819542d5705c6033ab78f4e5b3a1d1bd979 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 3 Dec 2024 14:19:38 +0100 Subject: [PATCH 117/133] Mark version 1.4.21 --- CHANGELOG.md | 10 ++++++++++ package.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a5b3a2..bd425a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## 1.4.21 (2024-12-03) + +### Bug fixes + +Add support for `const` modifiers on TypeScript type parameters. + +Allow TypeScript syntax, where the condition is just a variable. + +Fix a bug where some TypeScript `<` tokens didn't appear in the syntax tree. + ## 1.4.20 (2024-12-02) ### Bug fixes diff --git a/package.json b/package.json index 6288549..e416b36 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.20", + "version": "1.4.21", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 52f0592f3ef77bb9bcadc8af9c45865c3cf1039a Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 6 Feb 2025 11:48:07 +0100 Subject: [PATCH 118/133] Fix ambiguity between type predicates and type annotations --- src/javascript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 93d774d..26659c2 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -248,7 +248,7 @@ TypeAnnotation { ":" type } TypePredicate { ":" ( - tskw<"asserts">? (VariableName | kw<"this">) !predicate (tskw<"is"> type)? | + tskw<"asserts"> (VariableName | kw<"this">) !predicate (tskw<"is"> type)? | (VariableName | kw<"this">) !predicate tskw<"is"> type ) } From 17e896d07b300576447ccf91e9f7e261a9f90a14 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 6 Feb 2025 11:48:36 +0100 Subject: [PATCH 119/133] Add support for in/out type parameter annotations FIX: Support `in`/`out` modifiers on TypeScript type parameters. --- src/javascript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 26659c2..2be263b 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -404,7 +404,7 @@ TypeParamList { "<" commaSep ">" } -typeParam { kw<"const">? TypeDefinition ~tsAngle (kw<"extends"> type)? ("=" type)? } +typeParam { (kw<"in"> | tskw<"out"> | kw<"const">)? TypeDefinition ~tsAngle (kw<"extends"> type)? ("=" type)? } typeofExpression { MemberExpression { typeofExpression !member (("." | questionDot) PropertyName | "[" expression "]") } | From 3f819cd39048a053190871fcfd71a49466a83d9a Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 17 Apr 2025 08:08:17 +0200 Subject: [PATCH 120/133] Add support for TS satisfies operator FEATURE: Support the TypeScript `satisfies` operator. Closes https://github.com/lezer-parser/javascript/issues/45 --- src/javascript.grammar | 1 + test/typescript.txt | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/src/javascript.grammar b/src/javascript.grammar index 2be263b..f33ebba 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -370,6 +370,7 @@ BinaryExpression { expressionNoComma !satisfies tskw<"satisfies"> type | (expressionNoComma | PrivatePropertyName) !rel ~tsIn kw<"in"> expressionNoComma | expressionNoComma !rel ckw<"as"> (kw<"const"> | type) | + expressionNoComma !rel tskw<"satisfies"> type | expressionNoComma !equal CompareOp<"==" "="? | "!=" "="?> expressionNoComma | expressionNoComma !bitOr BitOp { "|" } expressionNoComma | expressionNoComma !bitXor BitOp<"^"> expressionNoComma | diff --git a/test/typescript.txt b/test/typescript.txt index 93c0d06..b5d772f 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -378,3 +378,13 @@ Script(InterfaceDeclaration(interface,TypeDefinition,ObjectType( MethodType(MemberExpression(VariableName,PropertyName),ParamList, TypeAnnotation(ParameterizedType(TypeName,TypeArgList(TypeName)))), PropertyType(Number,TypeAnnotation(TypeName))))) + +# Binary type operators {"dialect": "ts"} + +log(foo as number, {} satisfies AbstractObjectFactory) + +==> + +Script(ExpressionStatement(CallExpression(VariableName,ArgList( + BinaryExpression(VariableName,as,TypeName), + BinaryExpression(ObjectExpression,satisfies,ParameterizedType(TypeName,TypeArgList(TypeName))))))) From a25d6f9bb88b574dc1ef5870f1024bc7fc64796e Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 17 Apr 2025 08:08:48 +0200 Subject: [PATCH 121/133] Mark version 1.5.0 --- CHANGELOG.md | 10 ++++++++++ package.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd425a5..c35dda8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## 1.5.0 (2025-04-17) + +### Bug fixes + +Support `in`/`out` modifiers on TypeScript type parameters. + +### New features + +Support the TypeScript `satisfies` operator. + ## 1.4.21 (2024-12-03) ### Bug fixes diff --git a/package.json b/package.json index e416b36..c57cd94 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.4.21", + "version": "1.5.0", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 005fd9e2d1534c5442ea20affc976010720210a0 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 18 Apr 2025 17:46:38 +0200 Subject: [PATCH 122/133] Add highlighting for the satisfies op FIX: Properly highlight `satisfies` as a keyword. Issue https://github.com/lezer-parser/javascript/issues/45 --- src/highlight.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/highlight.js b/src/highlight.js index 71b03df..25c912b 100644 --- a/src/highlight.js +++ b/src/highlight.js @@ -3,10 +3,10 @@ import {styleTags, tags as t} from "@lezer/highlight" export const jsHighlight = styleTags({ "get set async static": t.modifier, "for while do if else switch try catch finally return throw break continue default case": t.controlKeyword, - "in of await yield void typeof delete instanceof": t.operatorKeyword, + "in of await yield void typeof delete instanceof as satisfies": t.operatorKeyword, "let var const using function class extends": t.definitionKeyword, "import export from": t.moduleKeyword, - "with debugger as new": t.keyword, + "with debugger new": t.keyword, TemplateString: t.special(t.string), super: t.atom, BooleanLiteral: t.bool, From d0770ec1bb8fd600c9d9cd118075524d446be7fd Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 18 Apr 2025 17:48:24 +0200 Subject: [PATCH 123/133] Mark version 1.5.1 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c35dda8..f2c1e65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.5.1 (2025-04-18) + +### Bug fixes + +Properly highlight `satisfies` as a keyword. + ## 1.5.0 (2025-04-17) ### Bug fixes diff --git a/package.json b/package.json index c57cd94..2a50ace 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.5.0", + "version": "1.5.1", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 40b30e6fe4d6cd475201c0f10ecd853040245e24 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 12 May 2025 16:01:54 +0200 Subject: [PATCH 124/133] Bump @lezer/generator dependency to one that can handle local tokens --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2a50ace..d9b1981 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "author": "Marijn Haverbeke ", "license": "MIT", "devDependencies": { - "@lezer/generator": "^1.0.0", + "@lezer/generator": "^1.7.0", "mocha": "^10.2.0", "rollup": "^2.52.2", "@rollup/plugin-node-resolve": "^9.0.0" From f2fc878a1f03d8515613be3bfe0abe241a503f14 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 15 Jul 2025 14:46:11 +0200 Subject: [PATCH 125/133] Allow const types with angle-bracket prefix syntax FIX: Allow `const` casts with old angle-bracket cast syntax. Closes https://github.com/lezer-parser/javascript/issues/46 --- src/javascript.grammar | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index f33ebba..2f6f79e 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -311,7 +311,7 @@ expressionNoComma { DynamicImport { kw<"import"> "(" expressionNoComma ")" } | ImportMeta { kw<"import"> "." PropertyName } | JSXElement | - PrefixCast { tsAngleOpen type ~tsAngle ">" expressionNoComma } | + PrefixCast { tsAngleOpen (type | kw<"const">) ~tsAngle ">" expressionNoComma } | ArrowFunction[@dynamicPrecedence=1] { TypeParamList { tsAngleOpen commaSep ">" } ParamList TypeAnnotation? "=>" (Block | expressionNoComma) } From 0b9b9b8226040cb5d21e3274a2f7969ed69650bd Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 3 Sep 2025 11:41:08 +0200 Subject: [PATCH 126/133] Add support for import defer FIX: Add support for `import defer` syntax. Closes https://github.com/lezer-parser/javascript/issues/47 --- src/javascript.grammar | 4 ++-- test/statement.txt | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 2f6f79e..8997273 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -84,9 +84,9 @@ ExportGroup { } ImportDeclaration { - kw<"import"> tskw<"type">? (Star ckw<"as"> VariableDefinition | commaSep) + kw<"import"> ckw<"defer">? tskw<"type">? (Star ckw<"as"> VariableDefinition | commaSep) ckw<"from"> String semi | - kw<"import"> String semi + kw<"import"> ckw<"defer">? String semi } ImportGroup { diff --git a/test/statement.txt b/test/statement.txt index 9243488..4bf28d8 100644 --- a/test/statement.txt +++ b/test/statement.txt @@ -238,6 +238,8 @@ import { member } from "module-name"; import { member1, member2 as alias2 } from "module-name"; import defaultMember, { member1, member2 as alias2, } from "module-name"; import "module-name"; +import defer x from "y"; +import defer from "y"; ==> @@ -247,7 +249,9 @@ Script( ImportDeclaration(import,ImportGroup(VariableDefinition),from,String), ImportDeclaration(import,ImportGroup(VariableDefinition,VariableName,as,VariableDefinition),from,String), ImportDeclaration(import,VariableDefinition,ImportGroup(VariableDefinition,VariableName,as,VariableDefinition),from,String), - ImportDeclaration(import,String)) + ImportDeclaration(import,String), + ImportDeclaration(import,defer,VariableDefinition,from,String), + ImportDeclaration(import,VariableDefinition,from,String)) # Exports From 8fc1866393fd5795aeaebde42d06b6511dfc23d8 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 4 Sep 2025 11:22:40 +0200 Subject: [PATCH 127/133] Mark version 1.5.2 --- CHANGELOG.md | 8 ++++++++ package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2c1e65..09b4113 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.5.2 (2025-09-04) + +### Bug fixes + +Allow `const` casts with old angle-bracket cast syntax. + +Add support for `import defer` syntax. + ## 1.5.1 (2025-04-18) ### Bug fixes diff --git a/package.json b/package.json index d9b1981..88942e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.5.1", + "version": "1.5.2", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From 349b4931825b1ce68d772c4ba8aa0888ccfb6375 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 9 Sep 2025 11:41:25 +0200 Subject: [PATCH 128/133] Add highlighting for defer keyword FIX: Fix missing highlight tag for `defer` contextual keyword. Issue https://github.com/lezer-parser/javascript/issues/47 --- src/highlight.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/highlight.js b/src/highlight.js index 25c912b..385f4c4 100644 --- a/src/highlight.js +++ b/src/highlight.js @@ -2,7 +2,7 @@ import {styleTags, tags as t} from "@lezer/highlight" export const jsHighlight = styleTags({ "get set async static": t.modifier, - "for while do if else switch try catch finally return throw break continue default case": t.controlKeyword, + "for while do if else switch try catch finally return throw break continue default case defer": t.controlKeyword, "in of await yield void typeof delete instanceof as satisfies": t.operatorKeyword, "let var const using function class extends": t.definitionKeyword, "import export from": t.moduleKeyword, From 9450f7efa94d6597c1cb4fc5fbdf3bc2bd3f755b Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 9 Sep 2025 12:36:13 +0200 Subject: [PATCH 129/133] Mark version 1.5.3 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09b4113..ad387b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.5.3 (2025-09-09) + +### Bug fixes + +Fix missing highlight tag for `defer` contextual keyword. + ## 1.5.2 (2025-09-04) ### Bug fixes diff --git a/package.json b/package.json index 88942e8..b58dcfc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.5.2", + "version": "1.5.3", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From a129dc39f360f04b0e5e8e14b130cef1ab0c3891 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 18 Sep 2025 13:50:24 +0200 Subject: [PATCH 130/133] Support this parameter types in TypeScript function types FIX: Support `this` parameters in function types. Issue https://github.com/lezer-parser/javascript/issues/48 --- src/javascript.grammar | 2 +- test/typescript.txt | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/javascript.grammar b/src/javascript.grammar index 8997273..c148f11 100644 --- a/src/javascript.grammar +++ b/src/javascript.grammar @@ -487,7 +487,7 @@ PropertyType { } ParamTypeList[@name=ParamList] { - "(" commaSep<"..."? pattern ~arrow Optional? ~arrow TypeAnnotation?> ")" + "(" commaSep<"..."? pattern ~arrow Optional? ~arrow TypeAnnotation? | kw<"this"> TypeAnnotation> ")" } @skip {} { diff --git a/test/typescript.txt b/test/typescript.txt index b5d772f..3a740a7 100644 --- a/test/typescript.txt +++ b/test/typescript.txt @@ -388,3 +388,14 @@ log(foo as number, {} satisfies AbstractObjectFactory) Script(ExpressionStatement(CallExpression(VariableName,ArgList( BinaryExpression(VariableName,as,TypeName), BinaryExpression(ObjectExpression,satisfies,ParameterizedType(TypeName,TypeArgList(TypeName))))))) + +# Allows this parameters in function types {"dialect": "ts"} + +let x: (this: X, expression: string) => Promise + +==> + +Script(VariableDeclaration(let,VariableDefinition,TypeAnnotation(FunctionSignature( + ParamList(this,TypeAnnotation(TypeName),VariableDefinition,TypeAnnotation(TypeName)), + Arrow, + ParameterizedType(TypeName,TypeArgList(ArrayType(TypeName))))))) From 371ae0e0659c18414a8e079c1eaa4586d400d9f0 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 18 Sep 2025 14:15:28 +0200 Subject: [PATCH 131/133] Mark version 1.5.4 --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad387b7..6c02a5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.5.4 (2025-09-18) + +### Bug fixes + +Support `this` parameters in function types. + ## 1.5.3 (2025-09-09) ### Bug fixes diff --git a/package.json b/package.json index b58dcfc..8c40f10 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lezer/javascript", - "version": "1.5.3", + "version": "1.5.4", "description": "lezer-based JavaScript grammar", "main": "dist/index.cjs", "type": "module", From d28558ab1d686fcf54ca14dfa2d3cb20b41be7ae Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Tue, 14 Apr 2026 17:24:26 +0200 Subject: [PATCH 132/133] Update github links --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8c40f10..1a12121 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/lezer-parser/javascript.git" + "url": "git+https://code.haverbeke.berlin/lezer/javascript.git" }, "scripts": { "build": "lezer-generator src/javascript.grammar -o src/parser && rollup -c", From 5575a6bf84ffc388c18b363e2ded91cf77c2c292 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 15 Apr 2026 08:43:36 +0200 Subject: [PATCH 133/133] Add forwarding link --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f979492..6ebba94 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +**This repository has moved to https://code.haverbeke.berlin/lezer/javascript** + # @lezer/javascript This is a JavaScript grammar for the