16 case Node::NK_ExprVar:
17 case Node::NK_ExprInt:
18 case Node::NK_ExprFloat:
19 case Node::NK_ExprSPath:
20 case Node::NK_ExprString:
21 case Node::NK_ExprPath:
22 case Node::NK_ExprParen:
23 case Node::NK_ExprAttrs:
24 case Node::NK_ExprList:
32bool mayProducedBySimple(
const Expr *E) {
35 return mayProducedBySimple(E->
kind());
42 auto LParen = std::make_shared<Misc>(L.
range());
43 assert(L.
kind() == tok_l_paren);
45 auto Sync = withSync(tok_r_paren);
46 assert(LastToken &&
"LastToken should be set after consume()");
50 if (ExpectResult ER = expect(tok_r_paren); ER.ok()) {
52 auto RParen = std::make_shared<Misc>(ER.tok().range());
53 if (mayProducedBySimple(
Expr.get())) {
55 Diags.emplace_back(Diagnostic::DK_RedundantParen, LParen->range());
57 Fix &F = D.
fix(
"remove ( and )");
61 return std::make_shared<ExprParen>(
63 std::move(LParen), std::move(RParen));
65 ER.diag().note(Note::NK_ToMachThis, L.
range())
67 if (mayProducedBySimple(
Expr.get())) {
69 Diags.emplace_back(Diagnostic::DK_RedundantParen, LParen->range());
71 Fix &F = D.
fix(
"remove (");
74 return std::make_shared<ExprParen>(
83 if (Tok.
kind() != tok_l_bracket)
86 auto Sync = withSync(tok_r_bracket);
87 assert(LastToken &&
"LastToken should be set after consume()");
89 std::vector<std::shared_ptr<Expr>> Exprs;
91 if (
Token Tok = peek(); Tok.
kind() == tok_r_bracket)
96 Exprs.emplace_back(std::move(
Expr));
98 if (ExpectResult ER = expect(tok_r_bracket); ER.ok())
101 ER.diag().note(Note::NK_ToMachThis, Tok.
range())
103 return std::make_shared<ExprList>(
LexerCursorRange{Begin, LastToken->rCur()},
109 switch (Tok.
kind()) {
113 auto Literal = std::string(Tok.
view());
115 auto Parts = std::make_shared<InterpolatedParts>(
116 Tok.
range(), std::vector<InterpolablePart>{
117 InterpolablePart{std::move(Literal)},
119 auto Str = std::make_shared<ExprString>(Tok.
range(), std::move(Parts));
122 Diags.emplace_back(Diagnostic::DK_DeprecatedURL, Tok.
range());
123 Fix &F = D.
fix(
"convert it to string");
132 std::make_shared<Identifier>(Tok.
range(), std::string(Tok.
view()));
133 return std::make_shared<ExprVar>(Tok.
range(), std::move(ID));
138 auto [Ptr, Errc] = std::from_chars(Tok.
view().begin(), Tok.
view().end(), N);
139 if (Errc != std::errc()) {
141 assert(Errc == std::errc::result_out_of_range);
143 Diags.emplace_back(Diagnostic::DK_IntTooBig, Tok.
range());
145 return std::make_shared<ExprInt>(Tok.
range(), N);
150 NixFloat N = std::strtof(std::string(Tok.
view()).c_str(),
nullptr);
151 return std::make_shared<ExprFloat>(Tok.
range(), N);
155 return std::make_shared<ExprSPath>(
156 Tok.
range(), std::string(Tok.
view().substr(1, Tok.
view().size() - 2)));
162 case tok_path_fragment:
Fix & fix(std::string Message)
Fix & edit(TextEdit Edit)
A point in the source file.
std::shared_ptr< ExprParen > parseExprParen()
std::shared_ptr< Expr > parseExpr()
std::shared_ptr< ExprString > parseString(bool IsIndented)
std::shared_ptr< Expr > parseExprSelect()
std::shared_ptr< Expr > parseExprPath()
Parse paths.
std::shared_ptr< Expr > parseExprSimple()
std::shared_ptr< ExprList > parseExprList()
std::shared_ptr< ExprAttrs > parseExprAttrs()
void tag(DiagnosticTag Tag)
static TextEdit mkRemoval(LexerCursorRange RemovingRange)
static TextEdit mkInsertion(LexerCursor P, std::string NewText)
A token. With it's kind, and the range in source code.
tok::TokenKind kind() const
LexerCursorRange range() const
std::string_view view() const
Diagnostic & diagNullExpr(std::vector< Diagnostic > &Diags, LexerCursor Loc, std::string As)
constexpr std::string_view spelling(TokenKind Kind)
Parser for the Nix expression language.