Compound member access syntax. (#1233)

Implement initial support for `A.(B)` syntax, per #989. Specifically, this supports:

* `object.(Type.member)` for instance members,
* `object.(Interface.member)` for instance and non-instance members,
* `object.(Type.(Interface.member))` for instance members,
* `Type.(Interface.member)` for non-instance members.

Three new AST nodes are introduced:

* `CompoundFieldAccessExpression` represents the `A.(B)` syntax.
* `MemberName` is a `Value` that represents the result of evaluating an expression such as `Type.member` or `Interface.member` or `Type.(Interface.member)`.
* `TypeOfMemberName` is the type of a `MemberName` value.

In order to handle members of classes and interfaces which have corresponding declarations and may need substitution into their types, and members of structs which don't have declarations but also don't need substitution, a class `Member` is introduced that can refer to either of these kinds of member.

Co-authored-by: Geoff Romer <gromer@google.com>
Co-authored-by: Jon Meow <jperkins@google.com>
This commit is contained in:
Richard Smith
2022-05-13 16:52:41 -07:00
committed by GitHub
co-authored by Geoff Romer Jon Meow
parent 20728dbd3a
commit 235cb88a8e
28 changed files with 940 additions and 41 deletions
+6
View File
@@ -95,6 +95,11 @@ void Expression::Print(llvm::raw_ostream& out) const {
out << access.aggregate() << "." << access.field();
break;
}
case ExpressionKind::CompoundFieldAccessExpression: {
const auto& access = cast<CompoundFieldAccessExpression>(*this);
out << access.object() << ".(" << access.path() << ")";
break;
}
case ExpressionKind::TupleLiteral: {
out << "(";
llvm::ListSeparator sep;
@@ -233,6 +238,7 @@ void Expression::PrintID(llvm::raw_ostream& out) const {
break;
case ExpressionKind::IndexExpression:
case ExpressionKind::FieldAccessExpression:
case ExpressionKind::CompoundFieldAccessExpression:
case ExpressionKind::IfExpression:
case ExpressionKind::TupleLiteral:
case ExpressionKind::StructLiteral: