mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-01 22:02:45 +01:00
Explorer: Support class extension (#1946)
Support class extension with `extends` Relates to #1881 Add support for: * Class extension with `extends` * Using base class methods and members
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "common/check.h"
|
||||
#include "explorer/ast/declaration.h"
|
||||
#include "explorer/common/arena.h"
|
||||
#include "explorer/common/error_builders.h"
|
||||
#include "explorer/interpreter/action.h"
|
||||
@@ -98,7 +99,7 @@ static auto GetMember(Nonnull<Arena*> arena, Nonnull<const Value*> v,
|
||||
// Look for a method in the object's class
|
||||
const auto& class_type = cast<NominalClassType>(object.type());
|
||||
std::optional<Nonnull<const FunctionValue*>> func =
|
||||
class_type.FindFunction(f);
|
||||
FindFunctionWithParents(f, class_type.declaration());
|
||||
if (!func) {
|
||||
return ProgramError(source_loc) << "member " << f << " not in " << *v
|
||||
<< " or its " << class_type;
|
||||
@@ -127,7 +128,7 @@ static auto GetMember(Nonnull<Arena*> arena, Nonnull<const Value*> v,
|
||||
// Access a class function.
|
||||
const auto& class_type = cast<NominalClassType>(*v);
|
||||
std::optional<Nonnull<const FunctionValue*>> fun =
|
||||
class_type.FindFunction(f);
|
||||
FindFunctionWithParents(f, class_type.declaration());
|
||||
if (fun == std::nullopt) {
|
||||
return ProgramError(source_loc)
|
||||
<< "class function " << f << " not in " << *v;
|
||||
@@ -979,9 +980,10 @@ auto ChoiceType::FindAlternative(std::string_view name) const
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto NominalClassType::FindFunction(std::string_view name) const
|
||||
auto FindFunction(std::string_view name,
|
||||
llvm::ArrayRef<Nonnull<Declaration*>> members)
|
||||
-> std::optional<Nonnull<const FunctionValue*>> {
|
||||
for (const auto& member : declaration().members()) {
|
||||
for (const auto& member : members) {
|
||||
switch (member->kind()) {
|
||||
case DeclarationKind::MixDeclaration: {
|
||||
const auto& mix_decl = cast<MixDeclaration>(*member);
|
||||
@@ -1034,6 +1036,18 @@ auto MixinPseudoType::FindFunction(const std::string_view& name) const
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto FindFunctionWithParents(std::string_view name,
|
||||
const ClassDeclaration& class_decl)
|
||||
-> std::optional<Nonnull<const FunctionValue*>> {
|
||||
if (auto fun = FindFunction(name, class_decl.members()); fun.has_value()) {
|
||||
return fun;
|
||||
}
|
||||
if (class_decl.base().has_value()) {
|
||||
return FindFunctionWithParents(name, *class_decl.base().value());
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto FindMember(std::string_view name,
|
||||
llvm::ArrayRef<Nonnull<Declaration*>> members)
|
||||
-> std::optional<Nonnull<const Declaration*>> {
|
||||
|
||||
Reference in New Issue
Block a user