mirror of
https://github.com/luau-lang/luau.git
synced 2025-05-04 10:33:46 +01:00
Fix string interpolation autocomplete
This commit is contained in:
parent
c32cdd5c42
commit
eb53fa5bec
5 changed files with 36 additions and 37 deletions
|
@ -1,6 +1,7 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#include "Luau/AstQuery.h"
|
||||
|
||||
#include "Luau/Ast.h"
|
||||
#include "Luau/Module.h"
|
||||
#include "Luau/Scope.h"
|
||||
#include "Luau/TypeInfer.h"
|
||||
|
|
|
@ -1227,11 +1227,8 @@ static bool stringPartOfInterpString(const AstNode* node, Position position)
|
|||
return false;
|
||||
}
|
||||
|
||||
printf("expressions.count: %ld\n", interpString->expressions.size);
|
||||
|
||||
for (const AstExpr* expression : interpString->expressions)
|
||||
{
|
||||
printf("%s <= %s <= %s -- expression = %d\n", toString(expression->location.begin).c_str(), toString(position).c_str(), toString(expression->location.end).c_str(), expression->classIndex);
|
||||
if (expression->location.containsClosed(position))
|
||||
{
|
||||
return false;
|
||||
|
@ -1239,7 +1236,6 @@ static bool stringPartOfInterpString(const AstNode* node, Position position)
|
|||
}
|
||||
|
||||
return true;
|
||||
// return node->is<AstExprInterpString>();
|
||||
}
|
||||
|
||||
static std::optional<AutocompleteEntryMap> autocompleteStringParams(const SourceModule& sourceModule, const ModulePtr& module,
|
||||
|
|
|
@ -22,7 +22,7 @@ bool lua_telemetry_parsed_named_non_function_type = false;
|
|||
LUAU_FASTFLAGVARIABLE(LuauErrorDoubleHexPrefix, false)
|
||||
LUAU_DYNAMIC_FASTFLAGVARIABLE(LuaReportParseIntegerIssues, false)
|
||||
|
||||
LUAU_FASTFLAGVARIABLE(LuauInterpolatedStringBaseSupport, false)
|
||||
LUAU_FASTFLAGVARIABLE(LuauInterpolatedStringBaseSupport, true)
|
||||
|
||||
LUAU_FASTFLAGVARIABLE(LuauCommaParenWarnings, false)
|
||||
LUAU_FASTFLAGVARIABLE(LuauTableConstructorRecovery, false)
|
||||
|
@ -2661,6 +2661,7 @@ AstExpr* Parser::parseInterpString()
|
|||
TempVector<AstExpr*> expressions(scratchExpr);
|
||||
|
||||
Location startLocation = lexer.current().location;
|
||||
Location endLocation;
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -2668,17 +2669,16 @@ AstExpr* Parser::parseInterpString()
|
|||
LUAU_ASSERT(currentLexeme.type == Lexeme::InterpStringBegin || currentLexeme.type == Lexeme::InterpStringMid ||
|
||||
currentLexeme.type == Lexeme::InterpStringEnd || currentLexeme.type == Lexeme::InterpStringSimple);
|
||||
|
||||
Location location = currentLexeme.location;
|
||||
endLocation = currentLexeme.location;
|
||||
|
||||
Location startOfBrace = Location(location.end, 1);
|
||||
Location startOfBrace = Location(endLocation.end, 1);
|
||||
|
||||
scratchData.assign(currentLexeme.data, currentLexeme.length);
|
||||
|
||||
if (!Lexer::fixupQuotedString(scratchData))
|
||||
{
|
||||
nextLexeme();
|
||||
printf("FIXUP QUOTED STRING FAIL\n");
|
||||
return reportExprError(startLocation, {}, "Interpolated string literal contains malformed escape sequence");
|
||||
return reportExprError(Location{startLocation, endLocation}, {}, "Interpolated string literal contains malformed escape sequence");
|
||||
}
|
||||
|
||||
AstArray<char> chars = copy(scratchData);
|
||||
|
@ -2689,10 +2689,7 @@ AstExpr* Parser::parseInterpString()
|
|||
|
||||
if (currentLexeme.type == Lexeme::InterpStringEnd || currentLexeme.type == Lexeme::InterpStringSimple)
|
||||
{
|
||||
AstArray<AstArray<char>> stringsArray = copy(strings);
|
||||
AstArray<AstExpr*> expressionsArray = copy(expressions);
|
||||
|
||||
return allocator.alloc<AstExprInterpString>(startLocation, stringsArray, expressionsArray);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (lexer.current().type)
|
||||
|
@ -2701,20 +2698,14 @@ AstExpr* Parser::parseInterpString()
|
|||
case Lexeme::InterpStringEnd:
|
||||
{
|
||||
nextLexeme();
|
||||
expressions.push_back(reportExprError(location, {}, "Malformed interpolated string, expected expression inside '{}'"));
|
||||
AstArray<AstArray<char>> stringsArray = copy(strings);
|
||||
AstArray<AstExpr*> expressionsArray = copy(expressions);
|
||||
|
||||
return allocator.alloc<AstExprInterpString>(startLocation, stringsArray, expressionsArray);
|
||||
expressions.push_back(reportExprError(endLocation, {}, "Malformed interpolated string, expected expression inside '{}'"));
|
||||
break;
|
||||
}
|
||||
case Lexeme::BrokenString:
|
||||
{
|
||||
nextLexeme();
|
||||
expressions.push_back(reportExprError(location, {}, "Malformed interpolated string, did you forget to add a '`'?"));
|
||||
AstArray<AstArray<char>> stringsArray = copy(strings);
|
||||
AstArray<AstExpr*> expressionsArray = copy(expressions);
|
||||
|
||||
return allocator.alloc<AstExprInterpString>(startLocation, stringsArray, expressionsArray);
|
||||
expressions.push_back(reportExprError(endLocation, {}, "Malformed interpolated string, did you forget to add a '`'?"));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
expressions.push_back(parseExpr());
|
||||
|
@ -2728,17 +2719,18 @@ AstExpr* Parser::parseInterpString()
|
|||
break;
|
||||
case Lexeme::BrokenInterpDoubleBrace:
|
||||
nextLexeme();
|
||||
printf("BROKEN INTERP DOUBLE BRACE\n");
|
||||
return reportExprError(location, {}, ERROR_INVALID_INTERP_DOUBLE_BRACE);
|
||||
return reportExprError(endLocation, {}, ERROR_INVALID_INTERP_DOUBLE_BRACE);
|
||||
case Lexeme::BrokenString:
|
||||
nextLexeme();
|
||||
printf("BROKEN STRING\n");
|
||||
return reportExprError(location, {}, "Malformed interpolated string, did you forget to add a '}'?");
|
||||
return reportExprError(endLocation, {}, "Malformed interpolated string, did you forget to add a '}'?");
|
||||
default:
|
||||
printf("DEFAULT: %s\n", lexer.current().toString().c_str());
|
||||
return reportExprError(location, {}, "Malformed interpolated string, got %s", lexer.current().toString().c_str());
|
||||
return reportExprError(endLocation, {}, "Malformed interpolated string, got %s", lexer.current().toString().c_str());
|
||||
}
|
||||
} while (true);
|
||||
|
||||
AstArray<AstArray<char>> stringsArray = copy(strings);
|
||||
AstArray<AstExpr*> expressionsArray = copy(expressions);
|
||||
return allocator.alloc<AstExprInterpString>(Location{startLocation, endLocation}, stringsArray, expressionsArray);
|
||||
}
|
||||
|
||||
AstExpr* Parser::parseNumber()
|
||||
|
|
|
@ -183,7 +183,7 @@ TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprInterpString")
|
|||
AstStat* statement = expectParseStatement("local a = `var = {x}`");
|
||||
|
||||
std::string_view expected =
|
||||
R"({"type":"AstStatLocal","location":"0,0 - 0,18","vars":[{"luauType":null,"name":"a","type":"AstLocal","location":"0,6 - 0,7"}],"values":[{"type":"AstExprInterpString","location":"0,10 - 0,18","strings":["var = ",""],"expressions":[{"type":"AstExprGlobal","location":"0,18 - 0,19","global":"x"}]}]})";
|
||||
R"({"type":"AstStatLocal","location":"0,0 - 0,21","vars":[{"luauType":null,"name":"a","type":"AstLocal","location":"0,6 - 0,7"}],"values":[{"type":"AstExprInterpString","location":"0,10 - 0,21","strings":["var = ",""],"expressions":[{"type":"AstExprGlobal","location":"0,18 - 0,19","global":"x"}]}]})";
|
||||
|
||||
CHECK(toJson(statement) == expected);
|
||||
}
|
||||
|
|
|
@ -2712,15 +2712,24 @@ a = if temp then even else abc@3
|
|||
TEST_CASE_FIXTURE(ACFixture, "autocomplete_interpolated_string_constant")
|
||||
{
|
||||
ScopedFastFlag sff{"LuauInterpolatedStringBaseSupport", true};
|
||||
printf("======= autocomplete_interpolated_string_constant =======\n");
|
||||
|
||||
// check(R"(f(`@1`))");
|
||||
// auto ac = autocomplete('1');
|
||||
// CHECK(ac.entryMap.empty());
|
||||
// CHECK_EQ(ac.context, AutocompleteContext::String);
|
||||
check(R"(f(`@1`))");
|
||||
auto ac = autocomplete('1');
|
||||
CHECK(ac.entryMap.empty());
|
||||
CHECK_EQ(ac.context, AutocompleteContext::String);
|
||||
|
||||
check(R"(f(`@1 {"a"}`))");
|
||||
ac = autocomplete('1');
|
||||
CHECK(ac.entryMap.empty());
|
||||
CHECK_EQ(ac.context, AutocompleteContext::String);
|
||||
|
||||
check(R"(f(`{"a"} @1`))");
|
||||
auto ac = autocomplete('1');
|
||||
ac = autocomplete('1');
|
||||
CHECK(ac.entryMap.empty());
|
||||
CHECK_EQ(ac.context, AutocompleteContext::String);
|
||||
|
||||
check(R"(f(`{"a"} @1 {"b"}`))");
|
||||
ac = autocomplete('1');
|
||||
CHECK(ac.entryMap.empty());
|
||||
CHECK_EQ(ac.context, AutocompleteContext::String);
|
||||
}
|
||||
|
@ -2745,8 +2754,9 @@ TEST_CASE_FIXTURE(ACFixture, "autocomplete_interpolated_string_expression_with_c
|
|||
CHECK(ac.entryMap.count("table"));
|
||||
CHECK_EQ(ac.context, AutocompleteContext::Expression);
|
||||
|
||||
check(R"(f(`expression = {@1--[[ bla bla bla ]]`))");
|
||||
check(R"(f(`expression = {@1 --[[ bla bla bla ]]`))");
|
||||
ac = autocomplete('1');
|
||||
CHECK(!ac.entryMap.empty());
|
||||
CHECK(ac.entryMap.count("table"));
|
||||
CHECK_EQ(ac.context, AutocompleteContext::Expression);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue