Skip to content

Commit 689327d

Browse files
ok
1 parent 84d97a0 commit 689327d

File tree

4 files changed

+1204768
-835578
lines changed

4 files changed

+1204768
-835578
lines changed

crates/pgls_treesitter_grammar/grammar.js

Lines changed: 143 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,28 @@ module.exports = grammar({
759759
choice(
760760
$._ddl_statement,
761761
$._dml_write,
762-
optional_parenthesis($._dml_read)
762+
optional_parenthesis($._dml_read),
763+
oneOfKeywords([
764+
"alter",
765+
"comment",
766+
"copy",
767+
"create",
768+
"delete",
769+
"drop",
770+
"grant",
771+
"insert",
772+
"merge",
773+
"reset",
774+
"revoke",
775+
"select",
776+
"set",
777+
"show",
778+
"truncate",
779+
"unload",
780+
"update",
781+
"vacuum",
782+
"with",
783+
])
763784
)
764785
),
765786

@@ -1003,7 +1024,25 @@ module.exports = grammar({
10031024
$.create_extension,
10041025
$.create_trigger,
10051026
$.create_policy,
1006-
prec.left(seq($.create_schema, repeat($._create_statement)))
1027+
prec.left(seq($.create_schema, repeat($._create_statement))),
1028+
seq(
1029+
completableKeyword($, "create", { minLength: 2 }),
1030+
oneOfKeywords([
1031+
"database",
1032+
"extension",
1033+
"function",
1034+
"index",
1035+
"materialized",
1036+
"policy",
1037+
"role",
1038+
"schema",
1039+
"sequence",
1040+
"table",
1041+
"trigger",
1042+
"type",
1043+
"view",
1044+
])
1045+
)
10071046
)
10081047
),
10091048

@@ -1708,7 +1747,21 @@ module.exports = grammar({
17081747
$.alter_database,
17091748
$.alter_role,
17101749
$.alter_sequence,
1711-
$.alter_policy
1750+
$.alter_policy,
1751+
seq(
1752+
completableKeyword($, "alter", { minLength: 2 }),
1753+
oneOfKeywords([
1754+
"database",
1755+
"index",
1756+
"policy",
1757+
"role",
1758+
"schema",
1759+
"sequence",
1760+
"table",
1761+
"type",
1762+
"view",
1763+
])
1764+
)
17121765
)
17131766
),
17141767

@@ -2082,7 +2135,23 @@ module.exports = grammar({
20822135
$.drop_sequence,
20832136
$.drop_extension,
20842137
$.drop_function,
2085-
$.drop_policy
2138+
$.drop_policy,
2139+
seq(
2140+
completableKeyword($, "drop", { minLength: 2 }),
2141+
oneOfKeywords([
2142+
"database",
2143+
"extension",
2144+
"function",
2145+
"index",
2146+
"policy",
2147+
"role",
2148+
"schema",
2149+
"sequence",
2150+
"table",
2151+
"type",
2152+
"view",
2153+
])
2154+
)
20862155
)
20872156
),
20882157

@@ -2265,7 +2334,8 @@ module.exports = grammar({
22652334
choice(
22662335
seq($.keyword_default, $.keyword_values),
22672336
$.insert_values,
2268-
$._select_statement
2337+
$._select_statement,
2338+
oneOfKeywords(["default", "on", "select", "values"])
22692339
),
22702340
optional($._on_conflict)
22712341
),
@@ -2402,7 +2472,7 @@ module.exports = grammar({
24022472
$.relation,
24032473
$._set_values,
24042474
// optional($.from),
2405-
optional($.where)
2475+
optional(choice($.where, oneOfKeywords(["from", "returning", "where"])))
24062476
),
24072477

24082478
storage_location: ($) =>
@@ -2866,7 +2936,29 @@ module.exports = grammar({
28662936
comma_list($.relation, true),
28672937
optional($.index_hint),
28682938
repeat(
2869-
choice($.join, $.cross_join, $.lateral_join, $.lateral_cross_join)
2939+
choice(
2940+
$.join,
2941+
$.cross_join,
2942+
$.lateral_join,
2943+
$.lateral_cross_join,
2944+
oneOfKeywords([
2945+
"cross",
2946+
"full",
2947+
"group",
2948+
"having",
2949+
"inner",
2950+
"join",
2951+
"lateral",
2952+
"left",
2953+
"limit",
2954+
"natural",
2955+
"offset",
2956+
"order",
2957+
"right",
2958+
"where",
2959+
"window",
2960+
])
2961+
)
28702962
),
28712963
optional($.where),
28722964
optional($.group_by),
@@ -3718,22 +3810,54 @@ function completableKeyword($, keyword, opts = {}) {
37183810
}
37193811

37203812
/**
3721-
* Provides an alternative node before we match any other keyword.
3722-
* The LSP will be able to infer the possible keywords from the node kind.
3813+
* Provides alternatives for ambiguous keyword prefixes.
3814+
* For each prefix that matches multiple keywords, creates an alias like:
3815+
* any_keyword:select:set (for "se" which matches both)
37233816
*
37243817
* @param {string[]} keywords
37253818
*/
37263819
function oneOfKeywords(keywords) {
3727-
const kwAlias = `any_keyword:${keywords.join(":")}`;
3820+
const allKwAlias = `any_keyword:${keywords.join(":")}`;
3821+
3822+
// find all ambiguous prefixes and group keywords by prefix
3823+
const prefixToKeywords = new Map();
3824+
3825+
for (const kw of keywords) {
3826+
for (let len = 1; len < kw.length; len++) {
3827+
const prefix = kw.substring(0, len);
3828+
if (!prefixToKeywords.has(prefix)) {
3829+
prefixToKeywords.set(prefix, []);
3830+
}
3831+
prefixToKeywords.get(prefix).push(kw);
3832+
}
3833+
}
37283834

3729-
const anything = new RegExp("[a-z]", "i");
3835+
// build choices for ambiguous prefixes (those matching 2+ keywords)
3836+
const choices = [];
3837+
3838+
// group ambiguous prefixes by their matching keyword set
3839+
const keywordSetToPrefix = new Map();
3840+
for (const [prefix, matchingKws] of prefixToKeywords) {
3841+
if (matchingKws.length >= 2) {
3842+
const key = matchingKws.sort().join(":");
3843+
if (!keywordSetToPrefix.has(key)) {
3844+
keywordSetToPrefix.set(key, []);
3845+
}
3846+
keywordSetToPrefix.get(key).push(prefix);
3847+
}
3848+
}
37303849

3731-
return prec(
3732-
-10, // low precedence, since this should serve as a fallback
3733-
choice(
3734-
alias(anything, kwAlias),
3735-
alias(new RegExp("REPLACED_TOKEN", "i"), kwAlias),
3736-
alias(new RegExp("REPLACED_TOKEN_WITH_QUOTE", "i"), kwAlias)
3737-
)
3738-
);
3850+
// create a regex for each unique keyword set
3851+
for (const [keySet, prefixes] of keywordSetToPrefix) {
3852+
const sortedPrefixes = prefixes.sort((a, b) => b.length - a.length);
3853+
const pattern = sortedPrefixes.join("|");
3854+
const alias_name = `any_keyword:${keySet}`;
3855+
choices.push(alias(new RegExp(pattern, "i"), alias_name));
3856+
}
3857+
3858+
// always include REPLACED_TOKEN with all keywords
3859+
choices.push(alias(new RegExp("REPLACED_TOKEN", "i"), allKwAlias));
3860+
choices.push(alias(new RegExp("REPLACED_TOKEN_WITH_QUOTE", "i"), allKwAlias));
3861+
3862+
return prec(-10, choice(...choices));
37393863
}

0 commit comments

Comments
 (0)