@@ -4855,9 +4855,14 @@ pub const PositionContext = union(enum) {
48554855const StackState = struct {
48564856 ctx : PositionContext ,
48574857 stack_id : StackId ,
4858+
4859+ /// Indicates whether the current context is an ErrorSet definition, ie `error{...}`
4860+ pub fn isErrSetDef (self : StackState ) bool {
4861+ return (self .stack_id == .brace and self .ctx == .global_error_set );
4862+ }
48584863};
48594864
4860- const StackId = enum { paren , bracket , global };
4865+ const StackId = enum { paren , bracket , brace , global };
48614866
48624867fn peek (allocator : std.mem.Allocator , arr : * std .ArrayList (StackState )) ! * StackState {
48634868 if (arr .items .len == 0 ) {
@@ -4917,6 +4922,25 @@ pub fn getPositionContext(
49174922 break ;
49184923 }
49194924
4925+ // Check if the previous line ends with a ',', ie a continuation - targets multiline ErrorSet definitions
4926+ var lloc = line_loc ;
4927+ while (true ) {
4928+ while (lloc .start > 0 ) {
4929+ if (tree .source [lloc .start ] != '\n ' ) lloc .start -= 1 else break ;
4930+ } else break ;
4931+ while (lloc .start > 0 and tree .source [lloc .start ] == '\n ' ) lloc .start -= 1 ;
4932+ if (lloc .start == 0 ) break ;
4933+ lloc = offsets .lineLocAtIndex (tree .source , lloc .start );
4934+ // Check if it's a comment first
4935+ while (lloc .start > 0 and std .mem .startsWith (u8 , std .mem .trimStart (u8 , offsets .locToSlice (tree .source , lloc ), " \t " ), "//" )) {
4936+ const prev_line_loc = offsets .lineLocAtIndex (tree .source , lloc .start - 1 ); // `- 1` => prev line's `\n`
4937+ lloc = prev_line_loc ;
4938+ }
4939+ if (std .mem .endsWith (u8 , std .mem .trimEnd (u8 , offsets .locToSlice (tree .source , lloc ), " \t \r \n " ), "," )) continue ;
4940+ line_loc .start = lloc .start ;
4941+ break ;
4942+ }
4943+
49204944 var stack : std .ArrayList (StackState ) = try .initCapacity (allocator , 8 );
49214945 defer stack .deinit (allocator );
49224946 var should_do_lookahead = lookahead ;
@@ -5013,7 +5037,9 @@ pub fn getPositionContext(
50135037 }
50145038 }
50155039 },
5016- .identifier = > switch (curr_ctx .ctx ) {
5040+ .identifier = > if (curr_ctx .isErrSetDef ()) {
5041+ // Intent is to skip everything between the `error{...}` braces
5042+ } else switch (curr_ctx .ctx ) {
50175043 .enum_literal = > curr_ctx .ctx = .{ .enum_literal = tokenLocAppend (curr_ctx .ctx .loc (tree ).? , tok ) },
50185044 .field_access = > curr_ctx .ctx = .{ .field_access = tokenLocAppend (curr_ctx .ctx .loc (tree ).? , tok ) },
50195045 .label_access = > | loc | curr_ctx .ctx = if (loc .start == loc .end )
@@ -5061,21 +5087,29 @@ pub fn getPositionContext(
50615087 };
50625088 try stack .append (allocator , .{ .ctx = .empty , .stack_id = stack_id });
50635089 },
5064- .l_bracket = > try stack .append (allocator , .{ .ctx = .empty , .stack_id = .bracket }),
50655090 .r_paren = > {
50665091 // Do this manually, as .pop() sets `stack.items[stack.items.len - 1]` to `undefined` which currently curr_ctx points to
50675092 if (stack .items .len != 0 ) stack .items .len -= 1 ;
50685093 if (curr_ctx .stack_id != .paren ) {
50695094 (try peek (allocator , & stack )).ctx = .empty ;
50705095 }
50715096 },
5097+ .l_bracket = > try stack .append (allocator , .{ .ctx = .empty , .stack_id = .bracket }),
50725098 .r_bracket = > {
50735099 // Do this manually, as .pop() sets `stack.items[stack.items.len - 1]` to `undefined` which currently curr_ctx points to
50745100 if (stack .items .len != 0 ) stack .items .len -= 1 ;
50755101 if (curr_ctx .stack_id != .bracket ) {
50765102 (try peek (allocator , & stack )).ctx = .empty ;
50775103 }
50785104 },
5105+ .l_brace = > try stack .append (allocator , .{ .ctx = if (curr_ctx .ctx == .global_error_set ) curr_ctx .ctx else .empty , .stack_id = .brace }),
5106+ .r_brace = > {
5107+ // Do this manually, as .pop() sets `stack.items[stack.items.len - 1]` to `undefined` which currently curr_ctx points to
5108+ if (stack .items .len != 0 ) stack .items .len -= 1 ;
5109+ if (curr_ctx .stack_id != .brace ) {
5110+ (try peek (allocator , & stack )).ctx = .empty ;
5111+ }
5112+ },
50795113 .keyword_error = > curr_ctx .ctx = .global_error_set ,
50805114 .number_literal = > {
50815115 if (tok .loc .start <= source_index and tok .loc .end >= source_index ) {
@@ -5099,7 +5133,13 @@ pub fn getPositionContext(
50995133 std .debug .assert (tree .tokenTag (current_token ) == tag );
51005134 curr_ctx .ctx = .{ .keyword = current_token };
51015135 },
5102- .doc_comment , .container_doc_comment = > curr_ctx .ctx = .comment ,
5136+ .container_doc_comment = > curr_ctx .ctx = .comment ,
5137+ .doc_comment = > {
5138+ if (! curr_ctx .isErrSetDef ()) curr_ctx .ctx = .comment ; // Intent is to skip everything between the `error{...}` braces
5139+ },
5140+ .comma = > {
5141+ if (! curr_ctx .isErrSetDef ()) curr_ctx .ctx = .empty ; // Intent is to skip everything between the `error{...}` braces
5142+ },
51035143 else = > curr_ctx .ctx = .empty ,
51045144 }
51055145
0 commit comments