Skip to content

Commit fbd8ad4

Browse files
committed
add support for detecting lapis routes
1 parent 524d64f commit fbd8ad4

File tree

1 file changed

+54
-7
lines changed

1 file changed

+54
-7
lines changed

bin/moon-tags

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ argparse = require "argparse"
1717
parser = argparse "moon-tags", "Generate ctags style tags file for MoonScript files"
1818
parser\argument("files", "MoonScript files to generate tags for")\args "+"
1919
parser\flag "--include-line", "Include line number field for each tag"
20+
parser\flag "--lapis", "Support extracting lapis routes"
2021

2122
args = parser\parse [v for _, v in ipairs _G.arg]
2223

2324
TAGS = {} -- the final output of tags
2425

2526
literals = require "moonscript.parse.literals"
26-
import Indent from require "moonscript.parse.util"
27+
import Indent, simple_string from require "moonscript.parse.util"
2728

2829
import P, S, C, Cc, Cg, Cb, Ct, Cs, V from require "lpeg"
2930

@@ -32,18 +33,20 @@ until_end = (1 - literals.Stop)^0
3233
whitespace = S"\t " -- not including newline
3334
ignore_line = Ct until_end -- tag it for empty line
3435

36+
-- NOTE: we disable interpolation parsing since we don't have full grammar
37+
SingleString = simple_string "'", false
38+
DoubleString = simple_string '"', false
39+
String = SingleString + DoubleString
40+
3541
-- we have to do this double Ct to capture both the full line and the grouped captures
3642
Type = (name) -> Cg Cc(name), "type"
3743
Line = (type_name, p) -> Ct C Ct Cg(Indent, "indent") * p * Type type_name
3844

39-
class_line = Line "class", P"class" * whitespace^1 * Cg(literals.Name, "tag") * until_end
40-
41-
-- TODO: support lapis style routes
42-
-- class_property = Line P("@")^-1 * Cg(literals.Name, "tag") * P":" * until_end * Type "property"
43-
4445
method = P { P"=>" + P(1 - literals.Stop) * V(1) }
4546
func = P { P"->" + P"=>" + P(1 - literals.Stop) * V(1) }
4647

48+
self_prefix = Cg(P("@") * Cc(true), "self")
49+
4750
-- this matches end-of-file return table convention for module files to figure
4851
-- out what names are exported
4952
export_list = Ct P"{" * P {
@@ -52,17 +55,37 @@ export_list = Ct P"{" * P {
5255

5356
eof_exports = P { export_list * S(" \t\r\n")^0 * P(-1) + P(1) * V(1) }
5457

58+
class_line = Line "class", P"class" * whitespace^1 * Cg(literals.Name, "tag") * until_end
59+
class_property = Line "property", self_prefix^-1 * Cg(literals.Name, "tag") * P":" * whitespace^0 * Cg(String, "value")^0 * until_end
5560
class_method = Line("method", P("@")^-1 * Cg(literals.Name, "tag") * P":" * method) * until_end
5661
function_def = Line("function", Cg(literals.Name, "tag") * whitespace^0 * P"=" * func) * until_end
62+
lapis_route = Line "lapis-route", P"[" * Cg(literals.Name, "tag") * P":" * whitespace^0 * Cg(String, "route") * whitespace^0 * P("]:") * until_end
63+
64+
line_types = class_line + class_method + class_property + function_def
65+
66+
if args.lapis
67+
line_types += lapis_route
5768

5869
parse_lines = Ct P {
59-
(class_line + class_method + function_def + ignore_line) * (P(-1) + literals.Break * V(1))
70+
(line_types + ignore_line) * (P(-1) + literals.Break * V(1))
6071
}
6172

6273
escape_tagaddress = (line_text) ->
6374
replacements = S([[\/.$^]]) / [[\%0]]+ P("\t") / [[\t]] + P("\r") / [[\r]] + P("\n") / [[\n]]
6475
Cs((replacements + 1)^0)\match line_text
6576

77+
import types from require "tableshape"
78+
79+
class_field = types.partial {
80+
"self": true
81+
tag: types.string\tag "name"
82+
value: types.partial {
83+
"string"
84+
types.string
85+
types.string\tag "value" -- TODO: will need to un-escape this
86+
}
87+
}
88+
6689
for fname in *args.files
6790
file = assert io.open fname
6891
contents = assert file\read "*a"
@@ -109,6 +132,30 @@ for fname in *args.files
109132
table.insert fields, 1, "line:#{line_no}"
110133

111134
switch properties.type
135+
when "lapis-route"
136+
if cls = find_class properties
137+
prefix = if cls.fields
138+
cls.fields.name
139+
140+
table.insert TAGS, {
141+
"#{prefix or ""}#{properties.tag}"
142+
fname
143+
"/^#{escape_tagaddress line_text}/;\""
144+
"f"
145+
table.concat fields, " "
146+
}
147+
148+
when "property"
149+
-- this is necessary to register the correct indent level for the class
150+
cls = find_class properties
151+
152+
-- record the fields into the class object so they can be referenced by
153+
-- other tags. Note this is code-order dependent
154+
if cls and args.lapis
155+
if field = class_field properties
156+
cls.fields or= {}
157+
cls.fields[field.name] = field.value
158+
112159
when "function"
113160
if exports[properties.tag] and properties.indent == 0
114161
table.insert TAGS, {

0 commit comments

Comments
 (0)