From aa91f478432c771799ef76ef74d595e0d282ed97 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Wed, 7 Feb 2024 16:34:35 +0100 Subject: [PATCH 1/2] latest version of parser --- .../tests/src/expected/CompletionJsx.res.txt | 22 ++-- analysis/vendor/res_syntax/jsx_ppx.ml | 22 ++-- analysis/vendor/res_syntax/jsx_v4.ml | 67 +++-------- analysis/vendor/res_syntax/res_core.ml | 113 +++++++++++------- .../vendor/res_syntax/res_parsetree_viewer.ml | 16 +++ .../res_syntax/res_parsetree_viewer.mli | 6 + analysis/vendor/res_syntax/res_printer.ml | 68 ++++++++++- analysis/vendor/res_syntax/res_scanner.ml | 7 +- 8 files changed, 207 insertions(+), 114 deletions(-) diff --git a/analysis/tests/src/expected/CompletionJsx.res.txt b/analysis/tests/src/expected/CompletionJsx.res.txt index 9410655bd..4b357a531 100644 --- a/analysis/tests/src/expected/CompletionJsx.res.txt +++ b/analysis/tests/src/expected/CompletionJsx.res.txt @@ -429,17 +429,17 @@ posCursor:[30:12] posNoWhite:[30:11] Found expr:[11:4->32:10] posCursor:[30:12] posNoWhite:[30:11] Found expr:[12:4->32:10] posCursor:[30:12] posNoWhite:[30:11] Found expr:[15:5->32:10] JSX 15:8] > _children:15:8 -posCursor:[30:12] posNoWhite:[30:11] Found expr:[15:8->32:4] -Pexp_construct :::[16:7->32:4] [16:7->32:4] -posCursor:[30:12] posNoWhite:[30:11] Found expr:[16:7->32:4] -posCursor:[30:12] posNoWhite:[30:11] Found expr:[17:7->32:4] -Pexp_construct :::[17:7->32:4] [17:7->32:4] -posCursor:[30:12] posNoWhite:[30:11] Found expr:[17:7->32:4] -posCursor:[30:12] posNoWhite:[30:11] Found expr:[30:10->32:4] -Pexp_construct :::[30:10->32:4] [30:10->32:4] -posCursor:[30:12] posNoWhite:[30:11] Found expr:[30:10->32:4] -posCursor:[30:12] posNoWhite:[30:11] Found expr:[30:10->30:12] -JSX 30:12] > _children:None +posCursor:[30:12] posNoWhite:[30:11] Found expr:[15:8->33:2] +Pexp_construct :::[16:7->33:2] [16:7->33:2] +posCursor:[30:12] posNoWhite:[30:11] Found expr:[16:7->33:2] +posCursor:[30:12] posNoWhite:[30:11] Found expr:[17:7->33:2] +Pexp_construct :::[17:7->33:2] [17:7->33:2] +posCursor:[30:12] posNoWhite:[30:11] Found expr:[17:7->33:2] +posCursor:[30:12] posNoWhite:[30:11] Found expr:[30:10->33:2] +Pexp_construct :::[30:10->33:2] [30:10->33:2] +posCursor:[30:12] posNoWhite:[30:11] Found expr:[30:10->33:2] +posCursor:[30:12] posNoWhite:[30:11] Found expr:[30:10->32:10] +JSX 30:12] div[32:6->32:9]=...[32:6->32:9]> _children:32:9 Completable: ChtmlElement getJsxConfigByKey ~key ~type_:String let updateConfig config payload = let fields = getPayloadFields payload in - (match getInt ~key:"version" fields with - | None -> () - | Some i -> config.Jsx_common.version <- i); - (match getString ~key:"module_" fields with + let moduleRaw = getString ~key:"module_" fields in + let isGeneric = + match moduleRaw |> Option.map (fun m -> String.lowercase_ascii m) with + | Some "react" | None -> false + | Some _ -> true + in + (match (isGeneric, getInt ~key:"version" fields) with + | true, _ -> config.Jsx_common.version <- 4 + | false, Some i -> config.Jsx_common.version <- i + | _ -> ()); + (match moduleRaw with | None -> () | Some s -> config.module_ <- s); - match getString ~key:"mode" fields with - | None -> () - | Some s -> config.mode <- s + match (isGeneric, getString ~key:"mode" fields) with + | true, _ -> config.mode <- "automatic" + | false, Some s -> config.mode <- s + | _ -> () let isJsxConfigAttr ((loc, _) : attribute) = loc.txt = "jsxConfig" diff --git a/analysis/vendor/res_syntax/jsx_v4.ml b/analysis/vendor/res_syntax/jsx_v4.ml index 5246bbd31..4524ca459 100644 --- a/analysis/vendor/res_syntax/jsx_v4.ml +++ b/analysis/vendor/res_syntax/jsx_v4.ml @@ -4,7 +4,9 @@ open Asttypes open Parsetree open Longident -let moduleAccessName config = String.capitalize_ascii config.Jsx_common.module_ +let moduleAccessName config value = + String.capitalize_ascii config.Jsx_common.module_ ^ "." ^ value + |> Longident.parse let nolabel = Nolabel @@ -384,10 +386,7 @@ let transformUppercaseCall3 ~config modulePath mapper jsxExprLoc callExprLoc ( labelled "children", Exp.apply (Exp.ident - { - txt = Ldot (Lident (moduleAccessName config), "array"); - loc = Location.none; - }) + {txt = moduleAccessName config "array"; loc = Location.none}) [(Nolabel, expression)] ); ] | _ -> @@ -431,31 +430,17 @@ let transformUppercaseCall3 ~config modulePath mapper jsxExprLoc callExprLoc match (!childrenArg, keyProp) with | None, key :: _ -> ( Exp.ident - { - loc = Location.none; - txt = Ldot (Lident (moduleAccessName config), "jsxKeyed"); - }, + {loc = Location.none; txt = moduleAccessName config "jsxKeyed"}, [key; (nolabel, unitExpr ~loc:Location.none)] ) | None, [] -> - ( Exp.ident - { - loc = Location.none; - txt = Ldot (Lident (moduleAccessName config), "jsx"); - }, + ( Exp.ident {loc = Location.none; txt = moduleAccessName config "jsx"}, [] ) | Some _, key :: _ -> ( Exp.ident - { - loc = Location.none; - txt = Ldot (Lident (moduleAccessName config), "jsxsKeyed"); - }, + {loc = Location.none; txt = moduleAccessName config "jsxsKeyed"}, [key; (nolabel, unitExpr ~loc:Location.none)] ) | Some _, [] -> - ( Exp.ident - { - loc = Location.none; - txt = Ldot (Lident (moduleAccessName config), "jsxs"); - }, + ( Exp.ident {loc = Location.none; txt = moduleAccessName config "jsxs"}, [] ) in Exp.apply ~loc:jsxExprLoc ~attrs jsxExpr @@ -500,9 +485,9 @@ let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs (* the new jsx transform *) | "automatic" -> let elementBinding = - match moduleAccessName config with - | "React" -> Lident "ReactDOM" - | generic -> Ldot (Lident generic, "DOM") + match config.module_ |> String.lowercase_ascii with + | "react" -> Lident "ReactDOM" + | _generic -> moduleAccessName config "Elements" in let children, nonChildrenProps = @@ -539,10 +524,7 @@ let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs ( labelled "children", Exp.apply (Exp.ident - { - txt = Ldot (Lident (moduleAccessName config), "array"); - loc = Location.none; - }) + {txt = moduleAccessName config "array"; loc = Location.none}) [(Nolabel, expression)] ); ] in @@ -1203,10 +1185,7 @@ let transformStructureItem ~config item = (* can't be an arrow because it will defensively uncurry *) let newExternalType = Ptyp_constr - ( { - loc = pstr_loc; - txt = Ldot (Lident (moduleAccessName config), "componentLike"); - }, + ( {loc = pstr_loc; txt = moduleAccessName config "componentLike"}, [retPropsType; innerType] ) in let newStructure = @@ -1321,10 +1300,7 @@ let transformSignatureItem ~config item = (* can't be an arrow because it will defensively uncurry *) let newExternalType = Ptyp_constr - ( { - loc = psig_loc; - txt = Ldot (Lident (moduleAccessName config), "componentLike"); - }, + ( {loc = psig_loc; txt = moduleAccessName config "componentLike"}, [retPropsType; innerType] ) in let newStructure = @@ -1419,8 +1395,7 @@ let expr ~config mapper expression = let fragment = match config.mode with | "automatic" -> - Exp.ident ~loc - {loc; txt = Ldot (Lident (moduleAccessName config), "jsxFragment")} + Exp.ident ~loc {loc; txt = moduleAccessName config "jsxFragment"} | "classic" | _ -> Exp.ident ~loc {loc; txt = Ldot (Lident "React", "fragment")} in @@ -1431,10 +1406,7 @@ let expr ~config mapper expression = let applyJsxArray expr = Exp.apply (Exp.ident - { - txt = Ldot (Lident (moduleAccessName config), "array"); - loc = Location.none; - }) + {txt = moduleAccessName config "array"; loc = Location.none}) [(Nolabel, expr)] in let countOfChildren = function @@ -1472,11 +1444,8 @@ let expr ~config mapper expression = (match config.mode with | "automatic" -> if countOfChildren childrenExpr > 1 then - Exp.ident ~loc - {loc; txt = Ldot (Lident (moduleAccessName config), "jsxs")} - else - Exp.ident ~loc - {loc; txt = Ldot (Lident (moduleAccessName config), "jsx")} + Exp.ident ~loc {loc; txt = moduleAccessName config "jsxs"} + else Exp.ident ~loc {loc; txt = moduleAccessName config "jsx"} | "classic" | _ -> if countOfChildren childrenExpr > 1 then Exp.ident ~loc diff --git a/analysis/vendor/res_syntax/res_core.ml b/analysis/vendor/res_syntax/res_core.ml index d4fb3c428..eb4463840 100644 --- a/analysis/vendor/res_syntax/res_core.ml +++ b/analysis/vendor/res_syntax/res_core.ml @@ -78,10 +78,6 @@ module ErrorMessages = struct + Array size check + `get` checks on the current pattern. If it's to \ obtain a subarray, use `Array.sub` or `Belt.Array.slice`." - let arrayExprSpread = - "Arrays can't use the `...` spread currently. Please use `concat` or other \ - Array helpers." - let recordExprSpread = "Records can only have one `...` spread, at the beginning.\n\ Explanation: since records have a known, fixed shape, a spread like `{a, \ @@ -2621,10 +2617,11 @@ and parseJsxOpeningOrSelfClosingElement ~startPos p = | GreaterThan -> ( (* bar *) let childrenStartPos = p.Parser.startPos in - Scanner.setJsxMode p.scanner; Parser.next p; let spread, children = parseJsxChildren p in let childrenEndPos = p.Parser.startPos in + Scanner.popMode p.scanner Jsx; + Scanner.setJsxMode p.scanner; let () = match p.token with | LessThanSlash -> Parser.next p @@ -2689,6 +2686,8 @@ and parseJsxOpeningOrSelfClosingElement ~startPos p = * jsx-children ::= primary-expr* * => 0 or more *) and parseJsx p = + Scanner.popMode p.scanner Jsx; + Scanner.setJsxMode p.Parser.scanner; Parser.leaveBreadcrumb p Grammar.Jsx; let startPos = p.Parser.startPos in Parser.expect LessThan p; @@ -2700,6 +2699,7 @@ and parseJsx p = parseJsxFragment p | _ -> parseJsxName p in + Scanner.popMode p.scanner Jsx; Parser.eatBreadcrumb p; {jsxExpr with pexp_attributes = [jsxAttr]} @@ -2710,12 +2710,12 @@ and parseJsx p = *) and parseJsxFragment p = let childrenStartPos = p.Parser.startPos in - Scanner.setJsxMode p.scanner; Parser.expect GreaterThan p; let _spread, children = parseJsxChildren p in let childrenEndPos = p.Parser.startPos in Parser.expect LessThanSlash p; Parser.expect GreaterThan p; + Scanner.popMode p.scanner Jsx; let loc = mkLoc childrenStartPos childrenEndPos in makeListExpression loc children None @@ -2747,6 +2747,7 @@ and parseJsxProp p = Parser.next p; (* no punning *) let optional = Parser.optional p Question in + Scanner.popMode p.scanner Jsx; let attrExpr = let e = parsePrimaryExpr ~operand:(parseAtomicExpr p) p in {e with pexp_attributes = propLocAttr :: e.pexp_attributes} @@ -2769,6 +2770,7 @@ and parseJsxProp p = Parser.next p; match p.Parser.token with | DotDotDot -> ( + Scanner.popMode p.scanner Jsx; Parser.next p; let loc = mkLoc p.Parser.startPos p.prevEndPos in let propLocAttr = @@ -2794,9 +2796,7 @@ and parseJsxProps p = and parseJsxChildren p = let rec loop p children = match p.Parser.token with - | Token.Eof | LessThanSlash -> - Scanner.popMode p.scanner Jsx; - List.rev children + | Token.Eof | LessThanSlash -> children | LessThan -> (* Imagine:
< * is `<` the start of a jsx-child?
let () = Scanner.popMode p.scanner Jsx in let child = parsePrimaryExpr ~operand:(parseAtomicExpr p) ~noCall:true p in loop p (child :: children) - | _ -> - Scanner.popMode p.scanner Jsx; - List.rev children + | _ -> children in match p.Parser.token with | DotDotDot -> Parser.next p; (true, [parsePrimaryExpr ~operand:(parseAtomicExpr p) ~noCall:true p]) - | _ -> (false, loop p []) + | _ -> + let children = List.rev (loop p []) in + Scanner.popMode p.scanner Jsx; + (false, children) and parseBracedOrRecordExpr p = let startPos = p.Parser.startPos in @@ -3920,36 +3920,60 @@ and parseListExpr ~startPos p = loc)) [(Asttypes.Nolabel, Ast_helper.Exp.array ~loc listExprs)] -(* Overparse ... and give a nice error message *) -and parseNonSpreadExp ~msg p = - let () = - match p.Parser.token with - | DotDotDot -> - Parser.err p (Diagnostics.message msg); - Parser.next p - | _ -> () - in - match p.Parser.token with - | token when Grammar.isExprStart token -> ( - let expr = parseExpr p in - match p.Parser.token with - | Colon -> - Parser.next p; - let typ = parseTypExpr p in - let loc = mkLoc expr.pexp_loc.loc_start typ.ptyp_loc.loc_end in - Some (Ast_helper.Exp.constraint_ ~loc expr typ) - | _ -> Some expr) - | _ -> None - and parseArrayExp p = let startPos = p.Parser.startPos in Parser.expect Lbracket p; - let exprs = - parseCommaDelimitedRegion p ~grammar:Grammar.ExprList ~closing:Rbracket - ~f:(parseNonSpreadExp ~msg:ErrorMessages.arrayExprSpread) + let split_by_spread exprs = + List.fold_left + (fun acc curr -> + match (curr, acc) with + | (true, expr, startPos, endPos), _ -> + (* find a spread expression, prepend a new sublist *) + ([], Some expr, startPos, endPos) :: acc + | ( (false, expr, startPos, _endPos), + (no_spreads, spread, _accStartPos, accEndPos) :: acc ) -> + (* find a non-spread expression, and the accumulated is not empty, + * prepend to the first sublist, and update the loc of the first sublist *) + (expr :: no_spreads, spread, startPos, accEndPos) :: acc + | (false, expr, startPos, endPos), [] -> + (* find a non-spread expression, and the accumulated is empty *) + [([expr], None, startPos, endPos)]) + [] exprs + in + let listExprsRev = + parseCommaDelimitedReversedList p ~grammar:Grammar.ExprList + ~closing:Rbracket ~f:parseSpreadExprRegionWithLoc in Parser.expect Rbracket p; - Ast_helper.Exp.array ~loc:(mkLoc startPos p.prevEndPos) exprs + let loc = mkLoc startPos p.prevEndPos in + let collectExprs = function + | [], Some spread, _startPos, _endPos -> [spread] + | exprs, Some spread, _startPos, _endPos -> + let els = Ast_helper.Exp.array ~loc exprs in + [els; spread] + | exprs, None, _startPos, _endPos -> + let els = Ast_helper.Exp.array ~loc exprs in + [els] + in + match split_by_spread listExprsRev with + | [] -> Ast_helper.Exp.array ~loc:(mkLoc startPos p.prevEndPos) [] + | [(exprs, None, _, _)] -> + Ast_helper.Exp.array ~loc:(mkLoc startPos p.prevEndPos) exprs + | exprs -> + let xs = List.map collectExprs exprs in + let listExprs = + List.fold_right + (fun exprs1 acc -> + List.fold_right (fun expr1 acc1 -> expr1 :: acc1) exprs1 acc) + xs [] + in + Ast_helper.Exp.apply ~loc + (Ast_helper.Exp.ident ~loc ~attrs:[spreadAttr] + (Location.mkloc + (Longident.Ldot + (Longident.Ldot (Longident.Lident "Belt", "Array"), "concatMany")) + loc)) + [(Asttypes.Nolabel, Ast_helper.Exp.array ~loc listExprs)] (* TODO: check attributes in the case of poly type vars, * might be context dependend: parseFieldDeclaration (see ocaml) *) @@ -6008,7 +6032,14 @@ and parseModuleBindingBody p = and parseModuleBindings ~attrs ~startPos p = let rec loop p acc = let startPos = p.Parser.startPos in - let attrs = parseAttributesAndBinding p in + let docAttr : Parsetree.attributes = + match p.Parser.token with + | DocComment (loc, s) -> + Parser.next p; + [docCommentToAttribute loc s] + | _ -> [] + in + let attrs = docAttr @ parseAttributesAndBinding p in match p.Parser.token with | And -> Parser.next p; diff --git a/analysis/vendor/res_syntax/res_parsetree_viewer.ml b/analysis/vendor/res_syntax/res_parsetree_viewer.ml index 8142ae33b..0186a7352 100644 --- a/analysis/vendor/res_syntax/res_parsetree_viewer.ml +++ b/analysis/vendor/res_syntax/res_parsetree_viewer.ml @@ -104,6 +104,11 @@ let hasAwaitAttribute attrs = | _ -> false) attrs +let collectArrayExpressions expr = + match expr.pexp_desc with + | Pexp_array exprs -> (exprs, None) + | _ -> ([], Some expr) + let collectListExpressions expr = let rec collect acc expr = match expr.pexp_desc with @@ -678,6 +683,17 @@ let isSpreadBeltListConcat expr = hasSpreadAttr expr.pexp_attributes | _ -> false +let isSpreadBeltArrayConcat expr = + match expr.pexp_desc with + | Pexp_ident + { + txt = + Longident.Ldot + (Longident.Ldot (Longident.Lident "Belt", "Array"), "concatMany"); + } -> + hasSpreadAttr expr.pexp_attributes + | _ -> false + (* Blue | Red | Green -> [Blue; Red; Green] *) let collectOrPatternChain pat = let rec loop pattern chain = diff --git a/analysis/vendor/res_syntax/res_parsetree_viewer.mli b/analysis/vendor/res_syntax/res_parsetree_viewer.mli index 493b6e851..954638c06 100644 --- a/analysis/vendor/res_syntax/res_parsetree_viewer.mli +++ b/analysis/vendor/res_syntax/res_parsetree_viewer.mli @@ -46,6 +46,10 @@ val collectIfExpressions : (Location.t * ifConditionKind * Parsetree.expression) list * Parsetree.expression option +val collectArrayExpressions : + Parsetree.expression -> + Parsetree.expression list * Parsetree.expression option + val collectListExpressions : Parsetree.expression -> Parsetree.expression list * Parsetree.expression option @@ -142,6 +146,8 @@ val hasTemplateLiteralAttr : Parsetree.attributes -> bool val isSpreadBeltListConcat : Parsetree.expression -> bool +val isSpreadBeltArrayConcat : Parsetree.expression -> bool + val collectOrPatternChain : Parsetree.pattern -> Parsetree.pattern list val processBracesAttr : diff --git a/analysis/vendor/res_syntax/res_printer.ml b/analysis/vendor/res_syntax/res_printer.ml index 3b546e051..9c2ef4b66 100644 --- a/analysis/vendor/res_syntax/res_printer.ml +++ b/analysis/vendor/res_syntax/res_printer.ml @@ -421,7 +421,7 @@ let printLongident = function type identifierStyle = ExoticIdent | NormalIdent -let classifyIdentContent ?(allowUident = false) txt = +let classifyIdentContent ?(allowUident = false) ?(allowHyphen = false) txt = if Token.isKeywordTxt txt then ExoticIdent else let len = String.length txt in @@ -431,16 +431,18 @@ let classifyIdentContent ?(allowUident = false) txt = match String.unsafe_get txt i with | 'A' .. 'Z' when allowUident -> loop (i + 1) | 'a' .. 'z' | '_' -> loop (i + 1) + | '-' when allowHyphen -> loop (i + 1) | _ -> ExoticIdent else match String.unsafe_get txt i with | 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '\'' | '_' -> loop (i + 1) + | '-' when allowHyphen -> loop (i + 1) | _ -> ExoticIdent in loop 0 -let printIdentLike ?allowUident txt = - match classifyIdentContent ?allowUident txt with +let printIdentLike ?allowUident ?allowHyphen txt = + match classifyIdentContent ?allowUident ?allowHyphen txt with | ExoticIdent -> Doc.concat [Doc.text "\\\""; Doc.text txt; Doc.text "\""] | NormalIdent -> Doc.text txt @@ -3046,6 +3048,9 @@ and printExpression ~state (e : Parsetree.expression) cmtTbl = Doc.rbrace; ]) | extension -> printExtension ~state ~atModuleLvl:false extension cmtTbl) + | Pexp_apply (e, [(Nolabel, {pexp_desc = Pexp_array subLists})]) + when ParsetreeViewer.isSpreadBeltArrayConcat e -> + printBeltArrayConcatApply ~state subLists cmtTbl | Pexp_apply (e, [(Nolabel, {pexp_desc = Pexp_array subLists})]) when ParsetreeViewer.isSpreadBeltListConcat e -> printBeltListConcatApply ~state subLists cmtTbl @@ -3813,6 +3818,61 @@ and printBinaryExpression ~state (expr : Parsetree.expression) cmtTbl = ]) | _ -> Doc.nil +and printBeltArrayConcatApply ~state subLists cmtTbl = + let makeSpreadDoc commaBeforeSpread = function + | Some expr -> + Doc.concat + [ + commaBeforeSpread; + Doc.dotdotdot; + (let doc = printExpressionWithComments ~state expr cmtTbl in + match Parens.expr expr with + | Parens.Parenthesized -> addParens doc + | Braced braces -> printBraces doc expr braces + | Nothing -> doc); + ] + | None -> Doc.nil + in + let makeSubListDoc (expressions, spread) = + let commaBeforeSpread = + match expressions with + | [] -> Doc.nil + | _ -> Doc.concat [Doc.text ","; Doc.line] + in + let spreadDoc = makeSpreadDoc commaBeforeSpread spread in + Doc.concat + [ + Doc.join + ~sep:(Doc.concat [Doc.text ","; Doc.line]) + (List.map + (fun expr -> + let doc = printExpressionWithComments ~state expr cmtTbl in + match Parens.expr expr with + | Parens.Parenthesized -> addParens doc + | Braced braces -> printBraces doc expr braces + | Nothing -> doc) + expressions); + spreadDoc; + ] + in + Doc.group + (Doc.concat + [ + Doc.lbracket; + Doc.indent + (Doc.concat + [ + Doc.softLine; + Doc.join + ~sep:(Doc.concat [Doc.text ","; Doc.line]) + (List.map makeSubListDoc + (List.map ParsetreeViewer.collectArrayExpressions subLists)); + ]); + Doc.trailingComma; + Doc.softLine; + Doc.rbracket; + ]) + and printBeltListConcatApply ~state subLists cmtTbl = let makeSpreadDoc commaBeforeSpread = function | Some expr -> @@ -4404,7 +4464,7 @@ and printJsxProp ~state arg cmtTbl = * Navabar.createElement -> Navbar * Staff.Users.createElement -> Staff.Users *) and printJsxName {txt = lident} = - let printIdent = printIdentLike ~allowUident:true in + let printIdent = printIdentLike ~allowUident:true ~allowHyphen:true in let rec flatten acc lident = match lident with | Longident.Lident txt -> printIdent txt :: acc diff --git a/analysis/vendor/res_syntax/res_scanner.ml b/analysis/vendor/res_syntax/res_scanner.ml index afcd4b9f3..b16904103 100644 --- a/analysis/vendor/res_syntax/res_scanner.ml +++ b/analysis/vendor/res_syntax/res_scanner.ml @@ -182,8 +182,11 @@ let digitValue ch = let scanIdentifier scanner = let startOff = scanner.offset in let rec skipGoodChars scanner = - match scanner.ch with - | 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' | '\'' -> + match (scanner.ch, inJsxMode scanner) with + | ('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' | '\''), false -> + next scanner; + skipGoodChars scanner + | ('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' | '\'' | '-'), true -> next scanner; skipGoodChars scanner | _ -> () From 043dd725bd8ff19d75df8119d9ca9e70d5ff7cfe Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Wed, 7 Feb 2024 16:36:24 +0100 Subject: [PATCH 2/2] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea65f9f4b..d2a112cd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ - Completion for import attributes in `@module`. https://github.com/rescript-lang/rescript-vscode/pull/913 - Relax filter for what local files that come up in from and regular string completion in `@module`. https://github.com/rescript-lang/rescript-vscode/pull/918 - Make from completion trigger for expr hole so we get a nice experience when completing {from: } in `@module`. https://github.com/rescript-lang/rescript-vscode/pull/918 +- Latest parser for newest syntax features. https://github.com/rescript-lang/rescript-vscode/pull/917 ## 1.38.0