@@ -126,6 +126,8 @@ struct AstSerialize : public Luau::AstVisitor
126126
127127 // absolute index for the table where we're storing locals
128128 int localTableIndex;
129+ // reference to previously serialized token
130+ int lastTokenRef = LUA_NOREF;
129131
130132 AstSerialize (lua_State* L, std::string_view source, Luau::CstNodeMap cstNodeMap, std::vector<Luau::Comment> commentLocations)
131133 : L(L)
@@ -255,6 +257,26 @@ struct AstSerialize : public Luau::AstVisitor
255257 return result;
256258 }
257259
260+ // Splits a list of trivia into trailing trivia for the previos token, and leading trivia for the next token
261+ // The trailing trivia consists of all trivia up to and including the first '\n' character seen
262+ static std::pair<std::vector<Trivia>, std::vector<Trivia>> splitTrivia (std::vector<Trivia> trivia)
263+ {
264+ size_t i = 0 ;
265+ for (i = 0 ; i < trivia.size (); i++)
266+ {
267+ if (trivia[i].kind == Trivia::Whitespace && trivia[i].text .find (' \n ' ) != std::string::npos)
268+ break ;
269+ }
270+
271+ if (i == trivia.size ())
272+ return {trivia, {}};
273+
274+ auto middleIter (trivia.begin ());
275+ std::advance (middleIter, i + 1 );
276+
277+ return {std::vector<Trivia>(trivia.begin (), middleIter), std::vector<Trivia>(middleIter, trivia.end ())};
278+ }
279+
258280 void serialize (Luau::Position position)
259281 {
260282 lua_rawcheckstack (L, 2 );
@@ -409,9 +431,27 @@ struct AstSerialize : public Luau::AstVisitor
409431 lua_rawcheckstack (L, 2 );
410432 lua_createtable (L, 0 , nrec + 3 );
411433
412- // TODO: split up into leading / trailing trivia
413- const auto leadingTrivia = extractTrivia (position);
414- serializeTrivia (leadingTrivia);
434+ const auto trivia = extractTrivia (position);
435+ if (lastTokenRef != LUA_NOREF)
436+ {
437+ const auto [trailingTrivia, leadingTrivia] = splitTrivia (trivia);
438+
439+ lua_getref (L, lastTokenRef);
440+ LUAU_ASSERT (lua_istable (L, -1 ));
441+
442+ serializeTrivia (trailingTrivia);
443+ lua_setfield (L, -2 , " trailingTrivia" );
444+ lua_pop (L, 1 );
445+ lua_unref (L, lastTokenRef);
446+ lastTokenRef = LUA_NOREF;
447+
448+ serializeTrivia (leadingTrivia);
449+ }
450+ else
451+ {
452+ serializeTrivia (trivia);
453+ }
454+ LUAU_ASSERT (lua_istable (L, -2 ));
415455 lua_setfield (L, -2 , " leadingTrivia" );
416456
417457 serialize (position);
@@ -424,6 +464,8 @@ struct AstSerialize : public Luau::AstVisitor
424464 lua_rawcheckstack (L, 2 );
425465 lua_createtable (L, 0 , 0 );
426466 lua_setfield (L, -2 , " trailingTrivia" );
467+
468+ lastTokenRef = lua_ref (L, -1 );
427469 }
428470
429471 void serializeLocals (Luau::AstArray<Luau::AstLocal*>& locals, size_t nrec = 0 )
0 commit comments