mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:57:35 +00:00
LibJS: Implement private identifiers in optional chains
This commit is contained in:
parent
4c8090a45d
commit
2d48529073
3 changed files with 35 additions and 2 deletions
|
@ -2704,6 +2704,11 @@ void OptionalChain::dump(int indent) const
|
||||||
print_indent(indent + 1);
|
print_indent(indent + 1);
|
||||||
outln("MemberReference({})", ref.mode == Mode::Optional ? "Optional" : "Not Optional");
|
outln("MemberReference({})", ref.mode == Mode::Optional ? "Optional" : "Not Optional");
|
||||||
ref.identifier->dump(indent + 2);
|
ref.identifier->dump(indent + 2);
|
||||||
|
},
|
||||||
|
[&](PrivateMemberReference const& ref) {
|
||||||
|
print_indent(indent + 1);
|
||||||
|
outln("PrivateMemberReference({})", ref.mode == Mode::Optional ? "Optional" : "Not Optional");
|
||||||
|
ref.private_identifier->dump(indent + 2);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2738,6 +2743,12 @@ Optional<OptionalChain::ReferenceAndValue> OptionalChain::to_reference_and_value
|
||||||
create_ast_node<SyntheticReferenceExpression>(source_range(), *base_reference, base),
|
create_ast_node<SyntheticReferenceExpression>(source_range(), *base_reference, base),
|
||||||
ref.identifier,
|
ref.identifier,
|
||||||
false);
|
false);
|
||||||
|
},
|
||||||
|
[&](PrivateMemberReference const& ref) -> NonnullRefPtr<Expression> {
|
||||||
|
return create_ast_node<MemberExpression>(source_range(),
|
||||||
|
create_ast_node<SyntheticReferenceExpression>(source_range(), *base_reference, base),
|
||||||
|
ref.private_identifier,
|
||||||
|
false);
|
||||||
});
|
});
|
||||||
if (is<CallExpression>(*expression)) {
|
if (is<CallExpression>(*expression)) {
|
||||||
base_reference = JS::Reference {};
|
base_reference = JS::Reference {};
|
||||||
|
|
|
@ -1590,8 +1590,12 @@ public:
|
||||||
NonnullRefPtr<Identifier> identifier;
|
NonnullRefPtr<Identifier> identifier;
|
||||||
Mode mode;
|
Mode mode;
|
||||||
};
|
};
|
||||||
|
struct PrivateMemberReference {
|
||||||
|
NonnullRefPtr<PrivateIdentifier> private_identifier;
|
||||||
|
Mode mode;
|
||||||
|
};
|
||||||
|
|
||||||
using Reference = Variant<Call, ComputedReference, MemberReference>;
|
using Reference = Variant<Call, ComputedReference, MemberReference, PrivateMemberReference>;
|
||||||
|
|
||||||
OptionalChain(SourceRange source_range, NonnullRefPtr<Expression> base, Vector<Reference> references)
|
OptionalChain(SourceRange source_range, NonnullRefPtr<Expression> base, Vector<Reference> references)
|
||||||
: Expression(source_range)
|
: Expression(source_range)
|
||||||
|
|
|
@ -2696,6 +2696,17 @@ NonnullRefPtr<OptionalChain> Parser::parse_optional_chain(NonnullRefPtr<Expressi
|
||||||
chain.append(OptionalChain::ComputedReference { parse_expression(0), OptionalChain::Mode::Optional });
|
chain.append(OptionalChain::ComputedReference { parse_expression(0), OptionalChain::Mode::Optional });
|
||||||
consume(TokenType::BracketClose);
|
consume(TokenType::BracketClose);
|
||||||
break;
|
break;
|
||||||
|
case TokenType::PrivateIdentifier: {
|
||||||
|
if (!is_private_identifier_valid())
|
||||||
|
syntax_error(String::formatted("Reference to undeclared private field or method '{}'", m_state.current_token.value()));
|
||||||
|
|
||||||
|
auto start = position();
|
||||||
|
auto private_identifier = consume();
|
||||||
|
chain.append(OptionalChain::PrivateMemberReference {
|
||||||
|
create_ast_node<PrivateIdentifier>({ m_state.current_token.filename(), start, position() }, private_identifier.value()),
|
||||||
|
OptionalChain::Mode::Optional });
|
||||||
|
break;
|
||||||
|
}
|
||||||
case TokenType::TemplateLiteralStart:
|
case TokenType::TemplateLiteralStart:
|
||||||
// 13.3.1.1 - Static Semantics: Early Errors
|
// 13.3.1.1 - Static Semantics: Early Errors
|
||||||
// OptionalChain :
|
// OptionalChain :
|
||||||
|
@ -2721,7 +2732,14 @@ NonnullRefPtr<OptionalChain> Parser::parse_optional_chain(NonnullRefPtr<Expressi
|
||||||
chain.append(OptionalChain::Call { parse_arguments(), OptionalChain::Mode::NotOptional });
|
chain.append(OptionalChain::Call { parse_arguments(), OptionalChain::Mode::NotOptional });
|
||||||
} else if (match(TokenType::Period)) {
|
} else if (match(TokenType::Period)) {
|
||||||
consume();
|
consume();
|
||||||
if (match_identifier_name()) {
|
if (match(TokenType::PrivateIdentifier)) {
|
||||||
|
auto start = position();
|
||||||
|
auto private_identifier = consume();
|
||||||
|
chain.append(OptionalChain::PrivateMemberReference {
|
||||||
|
create_ast_node<PrivateIdentifier>({ m_state.current_token.filename(), start, position() }, private_identifier.value()),
|
||||||
|
OptionalChain::Mode::NotOptional,
|
||||||
|
});
|
||||||
|
} else if (match_identifier_name()) {
|
||||||
auto start = position();
|
auto start = position();
|
||||||
auto identifier = consume();
|
auto identifier = consume();
|
||||||
chain.append(OptionalChain::MemberReference {
|
chain.append(OptionalChain::MemberReference {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue