@@ -124,6 +124,8 @@ struct AstSerialize : public Luau::AstVisitor
124124
125125 // absolute index for the table where we're storing locals
126126 int localTableIndex;
127+ // reference to previously serialized token
128+ int lastTokenRef = LUA_NOREF;
127129
128130 AstSerialize (lua_State* L, std::string_view source, Luau::CstNodeMap cstNodeMap, std::vector<Luau::Comment> commentLocations)
129131 : L(L)
@@ -253,6 +255,26 @@ struct AstSerialize : public Luau::AstVisitor
253255 return result;
254256 }
255257
258+ // Splits a list of trivia into trailing trivia for the previos token, and leading trivia for the next token
259+ // The trailing trivia consists of all trivia up to and including the first '\n' character seen
260+ static std::pair<std::vector<Trivia>, std::vector<Trivia>> splitTrivia (std::vector<Trivia> trivia)
261+ {
262+ size_t i = 0 ;
263+ for (i = 0 ; i < trivia.size (); i++)
264+ {
265+ if (trivia[i].kind == Trivia::Whitespace && trivia[i].text .find (' \n ' ) != std::string::npos)
266+ break ;
267+ }
268+
269+ if (i == trivia.size ())
270+ return {trivia, {}};
271+
272+ auto middleIter (trivia.begin ());
273+ std::advance (middleIter, i + 1 );
274+
275+ return {std::vector<Trivia>(trivia.begin (), middleIter), std::vector<Trivia>(middleIter, trivia.end ())};
276+ }
277+
256278 void serialize (Luau::Position position)
257279 {
258280 lua_rawcheckstack (L, 2 );
@@ -407,9 +429,27 @@ struct AstSerialize : public Luau::AstVisitor
407429 lua_rawcheckstack (L, 2 );
408430 lua_createtable (L, 0 , nrec + 3 );
409431
410- // TODO: split up into leading / trailing trivia
411- const auto leadingTrivia = extractTrivia (position);
412- serializeTrivia (leadingTrivia);
432+ const auto trivia = extractTrivia (position);
433+ if (lastTokenRef != LUA_NOREF)
434+ {
435+ const auto [trailingTrivia, leadingTrivia] = splitTrivia (trivia);
436+
437+ lua_getref (L, lastTokenRef);
438+ LUAU_ASSERT (lua_istable (L, -1 ));
439+
440+ serializeTrivia (trailingTrivia);
441+ lua_setfield (L, -2 , " trailingTrivia" );
442+ lua_pop (L, 1 );
443+ lua_unref (L, lastTokenRef);
444+ lastTokenRef = LUA_NOREF;
445+
446+ serializeTrivia (leadingTrivia);
447+ }
448+ else
449+ {
450+ serializeTrivia (trivia);
451+ }
452+ LUAU_ASSERT (lua_istable (L, -2 ));
413453 lua_setfield (L, -2 , " leadingTrivia" );
414454
415455 serialize (position);
@@ -422,6 +462,8 @@ struct AstSerialize : public Luau::AstVisitor
422462 lua_rawcheckstack (L, 2 );
423463 lua_createtable (L, 0 , 0 );
424464 lua_setfield (L, -2 , " trailingTrivia" );
465+
466+ lastTokenRef = lua_ref (L, -1 );
425467 }
426468
427469 void serializeLocals (Luau::AstArray<Luau::AstLocal*>& locals, size_t nrec = 0 )
0 commit comments