@@ -54,12 +54,13 @@ EChar <- 'a' -> ea
5454 / ([0-9] [0-9]? [0-9]?) -> Char10
5555 / ('u{' {X16*} '}') -> CharUtf8
5656Symbol <- ({} {
57- [:|,;<>()?+#{}]
57+ [:|,;<>()?+#{}* ]
5858 / '[]'
5959 / '...'
6060 / '['
6161 / ']'
6262 / '-' !'-'
63+ / '.' !'..'
6364 } {})
6465 -> Symbol
6566]] , {
@@ -71,7 +72,7 @@ Symbol <- ({} {
7172 er = ' \r ' ,
7273 et = ' \t ' ,
7374 ev = ' \v ' ,
74- name = (m .R (' az' , ' AZ' , ' 09' , ' \x80\xff ' ) + m .S (' _' )) * (m .R (' az' , ' AZ' , ' __ ' , ' 09' , ' \x80\xff ' ) + m .S (' _.*-' ))^ 0 ,
75+ name = (m .R (' az' , ' AZ' , ' 09' , ' \x80\xff ' ) + m .S (' _' )) * (m .R (' az' , ' AZ' , ' 09' , ' \x80\xff ' ) + m .S (' _.*-' ))^ 0 ,
7576 Char10 = function (char )
7677 --- @type integer ?
7778 char = tonumber (char )
@@ -720,57 +721,62 @@ local function parseString(parent)
720721 return str
721722end
722723
723- local function parseCode (parent )
724- local tp , content = peekToken ()
725- if not tp or tp ~= ' code' then
726- return nil
727- end
728- nextToken ()
729- local code = {
730- type = ' doc.type.code' ,
731- start = getStart (),
732- finish = getFinish (),
733- parent = parent ,
734- [1 ] = content ,
735- }
736- return code
737- end
738-
739724local function parseCodePattern (parent )
740725 local tp , pattern = peekToken ()
741- if not tp or tp ~= ' name' then
726+ if not tp or ( tp ~= ' name' and tp ~= ' code ' ) then
742727 return nil
743728 end
744729 local codeOffset
745- local finishOffset
746730 local content
747- for i = 2 , 8 do
748- local next , nextContent = peekToken (i )
749- if not next or TokenFinishs [Ci + i - 1 ] + 1 ~= TokenStarts [Ci + i ] then
750- if codeOffset then
751- finishOffset = i
752- break
753- end
731+ local i = 1
732+ if tp == ' code' then
733+ codeOffset = i
734+ content = pattern
735+ pattern = ' %s'
736+ end
737+ while true do
738+ i = i + 1
739+ local nextTp , nextContent = peekToken (i )
740+ if not nextTp or TokenFinishs [Ci + i - 1 ] + 1 ~= TokenStarts [Ci + i ] then
754741 --- 不连续的name,无效的
755- return nil
742+ break
756743 end
757- if next == ' code' then
758- if codeOffset and content ~= nextContent then
744+ if nextTp == ' name' then
745+ pattern = pattern .. nextContent
746+ elseif nextTp == ' code' then
747+ if codeOffset then
759748 -- 暂时不支持多generic
760- return nil
749+ break
761750 end
762751 codeOffset = i
763- pattern = pattern .. " %s "
752+ pattern = pattern .. ' %s '
764753 content = nextContent
765- elseif next ~= ' name' then
766- return nil
754+ elseif codeOffset then
755+ -- should be match with Parser "name" mask
756+ if nextTp == ' integer' then
757+ pattern = pattern .. nextContent
758+ elseif nextTp == ' symbol' and (nextContent == ' .' or nextContent == ' *' or nextContent == ' -' ) then
759+ pattern = pattern .. nextContent
760+ else
761+ break
762+ end
767763 else
768- pattern = pattern .. nextContent
764+ break
769765 end
770766 end
767+ if not codeOffset then
768+ return nil
769+ end
770+ nextToken ()
771771 local start = getStart ()
772- for _ = 2 , finishOffset do
773- nextToken ()
772+ local finishOffset = i - 1
773+ if finishOffset == 1 then
774+ -- code only, no pattern
775+ pattern = nil
776+ else
777+ for _ = 2 , finishOffset do
778+ nextToken ()
779+ end
774780 end
775781 local code = {
776782 type = ' doc.type.code' ,
@@ -834,7 +840,6 @@ function parseTypeUnit(parent)
834840 or parseTable (parent )
835841 or parseTuple (parent )
836842 or parseString (parent )
837- or parseCode (parent )
838843 or parseInteger (parent )
839844 or parseBoolean (parent )
840845 or parseParen (parent )
@@ -926,7 +931,7 @@ function parseType(parent)
926931 local function pushResume ()
927932 local comments
928933 for i = 0 , 100 do
929- local nextComm = NextComment (i ,' peek ' )
934+ local nextComm = NextComment (i , true )
930935 if not nextComm then
931936 return false
932937 end
@@ -1707,10 +1712,9 @@ local function trimTailComment(text)
17071712end
17081713
17091714local function buildLuaDoc (comment )
1710- local text = comment .text
1711- local startPos = (comment .type == ' comment.short' and text :match ' ^%-%s*@()' )
1712- or (comment .type == ' comment.long' and text :match ' ^@()' )
1713- if not startPos then
1715+ local headPos = (comment .type == ' comment.short' and comment .text :match ' ^%-%s*@()' )
1716+ or (comment .type == ' comment.long' and comment .text :match ' ^%s*@()' )
1717+ if not headPos then
17141718 return {
17151719 type = ' doc.comment' ,
17161720 start = comment .start ,
@@ -1719,42 +1723,47 @@ local function buildLuaDoc(comment)
17191723 comment = comment ,
17201724 }
17211725 end
1722- local startOffset = comment .start
1726+ -- absolute position of `@` symbol
1727+ local startOffset = comment .start + headPos
17231728 if comment .type == ' comment.long' then
1724- startOffset = startOffset + # comment .mark - 2
1729+ startOffset = comment . start + headPos + # comment .mark - 2
17251730 end
17261731
1727- local doc = text :sub (startPos )
1732+ local doc = comment . text :sub (headPos )
17281733
1729- parseTokens (doc , startOffset + startPos )
1734+ parseTokens (doc , startOffset )
17301735 local result , rests = convertTokens (doc )
17311736 if result then
17321737 result .range = math.max (comment .finish , result .finish )
17331738 local finish = result .firstFinish or result .finish
17341739 if rests then
17351740 for _ , rest in ipairs (rests ) do
1736- rest .range = comment .finish
1737- finish = rest .firstFinish or result .finish
1741+ rest .range = math.max ( comment .finish , rest . finish )
1742+ finish = rest .firstFinish or rest .finish
17381743 end
17391744 end
1740- local cstart = text :find (' %S' , finish - comment .start )
1741- if cstart and cstart < comment .finish then
1745+
1746+ -- `result` can be a multiline annotation or an alias, while `doc` is the first line, so we can't parse comment
1747+ if finish >= comment .finish then
1748+ return result , rests
1749+ end
1750+
1751+ local cstart = doc :find (' %S' , finish - startOffset )
1752+ if cstart then
17421753 result .comment = {
17431754 type = ' doc.tailcomment' ,
1744- start = cstart + comment . start ,
1755+ start = startOffset + cstart ,
17451756 finish = comment .finish ,
17461757 parent = result ,
1747- text = trimTailComment (text :sub (cstart )),
1758+ text = trimTailComment (doc :sub (cstart )),
17481759 }
17491760 if rests then
17501761 for _ , rest in ipairs (rests ) do
17511762 rest .comment = result .comment
17521763 end
17531764 end
17541765 end
1755- end
17561766
1757- if result then
17581767 return result , rests
17591768 end
17601769
@@ -2172,7 +2181,7 @@ local function bindDocs(state)
21722181 if doc .specialBindGroup then
21732182 bindDocWithSources (sources , doc .specialBindGroup )
21742183 binded = nil
2175- elseif isTailComment (text , doc ) and doc .type ~= " doc.class " and doc . type ~= " doc. field" then
2184+ elseif isTailComment (text , doc ) and doc .type ~= " doc.field" then
21762185 bindDocWithSources (sources , binded )
21772186 binded = nil
21782187 else
0 commit comments