diff --git a/Luau.YAML-tmLanguage b/Luau.YAML-tmLanguage index fcc6017..4006755 100644 --- a/Luau.YAML-tmLanguage +++ b/Luau.YAML-tmLanguage @@ -12,8 +12,15 @@ fileTypes: [luau] variables: matchingParentheses: (\(([^\(\)]|(\(([^\(\)]|\([^\(\)]*\))*\)))*\)) - lookAheadEndOfType: '(?=[),}\]](?!\s*[&|]))|(?=\s*;)|(?=\s*\b(?:break|const|continue|do|else|elseif|end|for|function|if|in|local|repeat|return|then|until|while)\b)|(?=^\s*$)|(?=^\s*(?:@|\b(?:export\s+)?type\b))|(?=^\s*{{identifier}}(?:\.{{identifier}})*\s*(?:(?:[+\-*/%^]|\.\.)?=(?!=)|\(|\[|:))' identifier: "[a-zA-Z_][a-zA-Z0-9_]*" + # Arithmetic/comparison operators that are valid in expressions but cannot appear at the + # top level of a Luau type expression, so their presence signals the end of a type. + # Exclusions: -> (function return type arrow), -- (comment), ... (variadic pack) + nonTypeOperators: '[*+%^]|\/\/?|(?`])|~=|==' + # Keywords that are valid outside a type expression (as binary operators or statement + # starters) but cannot appear within one, so their presence signals the end of a type. + nonTypeKeywords: 'and|or|break|const|continue|do|else|elseif|end|for|function|if|in|local|repeat|return|then|until|while' + lookAheadEndOfType: '(?=[),}\]](?!\s*[&|]))|(?=\s*;)|(?=\s*(?:{{nonTypeOperators}}))|(?=\s*\b(?:{{nonTypeKeywords}})\b)|(?=^\s*$)|(?=^\s*(?:@|\b(?:export\s+)?type\b))|(?=^\s*{{identifier}}(?:\.{{identifier}})*\s*(?:(?:[+\-*/%^]|\.\.)?=(?!=)|\(|\[|:))' patterns: - include: "#function-definition" diff --git a/Luau.tmLanguage b/Luau.tmLanguage index 8f71ba7..6d799da 100644 --- a/Luau.tmLanguage +++ b/Luau.tmLanguage @@ -1114,7 +1114,7 @@ begin (?<![^.]\.|:)\b(?:(export)\s+)?(type)\b(?=\s+(?!function\b)[a-zA-Z_][a-zA-Z0-9_]*) end - (?=[),}\]](?!\s*[&|]))|(?=\s*;)|(?=\s*\b(?:break|const|continue|do|else|elseif|end|for|function|if|in|local|repeat|return|then|until|while)\b)|(?=^\s*$)|(?=^\s*(?:@|\b(?:export\s+)?type\b))|(?=^\s*[a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)*\s*(?:(?:[+\-*/%^]|\.\.)?=(?!=)|\(|\[|:)) + (?=[),}\]](?!\s*[&|]))|(?=\s*;)|(?=\s*(?:[*+%^]|\/\/?|(?<!\.)\.\.(?!\.)|-(?![->`])|~=|==))|(?=\s*\b(?:and|or|break|const|continue|do|else|elseif|end|for|function|if|in|local|repeat|return|then|until|while)\b)|(?=^\s*$)|(?=^\s*(?:@|\b(?:export\s+)?type\b))|(?=^\s*[a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)*\s*(?:(?:[+\-*/%^]|\.\.)?=(?!=)|\(|\[|:)) beginCaptures 1 @@ -1173,7 +1173,7 @@ end - (?=[),}\]](?!\s*[&|]))|(?=\s*;)|(?=\s*\b(?:break|const|continue|do|else|elseif|end|for|function|if|in|local|repeat|return|then|until|while)\b)|(?=^\s*$)|(?=^\s*(?:@|\b(?:export\s+)?type\b))|(?=^\s*[a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)*\s*(?:(?:[+\-*/%^]|\.\.)?=(?!=)|\(|\[|:)) + (?=[),}\]](?!\s*[&|]))|(?=\s*;)|(?=\s*(?:[*+%^]|\/\/?|(?<!\.)\.\.(?!\.)|-(?![->`])|~=|==))|(?=\s*\b(?:and|or|break|const|continue|do|else|elseif|end|for|function|if|in|local|repeat|return|then|until|while)\b)|(?=^\s*$)|(?=^\s*(?:@|\b(?:export\s+)?type\b))|(?=^\s*[a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)*\s*(?:(?:[+\-*/%^]|\.\.)?=(?!=)|\(|\[|:)) patterns diff --git a/Luau.tmLanguage.json b/Luau.tmLanguage.json index 50db9fb..5c00a84 100644 --- a/Luau.tmLanguage.json +++ b/Luau.tmLanguage.json @@ -733,7 +733,7 @@ }, "type-alias-declaration": { "begin": "(?`])|~=|==))|(?=\\s*\\b(?:and|or|break|const|continue|do|else|elseif|end|for|function|if|in|local|repeat|return|then|until|while)\\b)|(?=^\\s*$)|(?=^\\s*(?:@|\\b(?:export\\s+)?type\\b))|(?=^\\s*[a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*)*\\s*(?:(?:[+\\-*/%^]|\\.\\.)?=(?!=)|\\(|\\[|:))", "beginCaptures": { "1": { "name": "storage.modifier.visibility.luau" @@ -771,7 +771,7 @@ "name": "keyword.operator.typecast.luau" } }, - "end": "(?=[),}\\]](?!\\s*[&|]))|(?=\\s*;)|(?=\\s*\\b(?:break|const|continue|do|else|elseif|end|for|function|if|in|local|repeat|return|then|until|while)\\b)|(?=^\\s*$)|(?=^\\s*(?:@|\\b(?:export\\s+)?type\\b))|(?=^\\s*[a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*)*\\s*(?:(?:[+\\-*/%^]|\\.\\.)?=(?!=)|\\(|\\[|:))", + "end": "(?=[),}\\]](?!\\s*[&|]))|(?=\\s*;)|(?=\\s*(?:[*+%^]|\\/\\/?|(?`])|~=|==))|(?=\\s*\\b(?:and|or|break|const|continue|do|else|elseif|end|for|function|if|in|local|repeat|return|then|until|while)\\b)|(?=^\\s*$)|(?=^\\s*(?:@|\\b(?:export\\s+)?type\\b))|(?=^\\s*[a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*)*\\s*(?:(?:[+\\-*/%^]|\\.\\.)?=(?!=)|\\(|\\[|:))", "patterns": [ { "include": "#type_literal" diff --git a/tests/baselines/issue-24.baseline.txt b/tests/baselines/issue-24.baseline.txt new file mode 100644 index 0000000..3346961 --- /dev/null +++ b/tests/baselines/issue-24.baseline.txt @@ -0,0 +1,46 @@ +original file +----------------------------------- +local a = tonumber("1")::number * 1000 + +----------------------------------- + +>local a = tonumber("1")::number * 1000 + ^^^^^ + source.luau storage.modifier.local.luau + ^ + source.luau + ^ + source.luau variable.other.readwrite.luau + ^ + source.luau + ^ + source.luau keyword.operator.assignment.luau + ^ + source.luau + ^^^^^^^^ + source.luau support.function.luau + ^ + source.luau punctuation.arguments.begin.luau + ^ + source.luau string.quoted.double.luau + ^ + source.luau string.quoted.double.luau + ^ + source.luau string.quoted.double.luau + ^ + source.luau punctuation.arguments.end.luau + ^^ + source.luau keyword.operator.typecast.luau + ^^^^^^ + source.luau support.type.primitive.luau + ^ + source.luau + ^ + source.luau keyword.operator.arithmetic.luau + ^ + source.luau + ^^^^ + source.luau constant.numeric.decimal.luau +> + ^ + source.luau \ No newline at end of file diff --git a/tests/baselines/stylua-luau-assignment-hang-1.lua.baseline.txt b/tests/baselines/stylua-luau-assignment-hang-1.lua.baseline.txt index d04a4cf..d0fc0e6 100644 --- a/tests/baselines/stylua-luau-assignment-hang-1.lua.baseline.txt +++ b/tests/baselines/stylua-luau-assignment-hang-1.lua.baseline.txt @@ -450,10 +450,14 @@ exports.separateDisplayNameAndHOCs = source.luau ^^^ source.luau support.type.primitive.luau - ^^^^ + ^ source.luau + ^^ + source.luau keyword.operator.comparison.luau + ^ + source.luau ^^^ - source.luau support.type.primitive.luau + source.luau constant.language.nil.luau ^ source.luau ^^ diff --git a/tests/cases/issue-24.luau b/tests/cases/issue-24.luau new file mode 100644 index 0000000..62bb75d --- /dev/null +++ b/tests/cases/issue-24.luau @@ -0,0 +1 @@ +local a = tonumber("1")::number * 1000