Skip to content

Commit

Permalink
Fix embedded types not counting towards getters and setters for inter…
Browse files Browse the repository at this point in the history
…faces
  • Loading branch information
Victorious3 committed May 27, 2024
1 parent ffd6249 commit d288928
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 12 deletions.
6 changes: 5 additions & 1 deletion src/compiler.pr
Original file line number Diff line number Diff line change
Expand Up @@ -6957,7 +6957,7 @@ def defer_unroll(node: &parser::Node, state: &State) {
}

export def insert_function(module: &toolchain::Module, function: &Function, overwrite: bool = false) {
if not function.name { return }
if not function or not function.name { return }
if module.result.functions.contains(function.name) and not overwrite { return }

module.result.functions(function.name) = function
Expand Down Expand Up @@ -7749,6 +7749,10 @@ export def walk_TypeDecl(node: &parser::Node, state: &State) {
let tpe = n.tpe
if not tpe { continue }

if n.kind == parser::NodeKind::IDENTIFIER {
tpe.name = parser::identifier_to_str(n)
}

let current_variable = state.current_variable
if node.parent.kind == parser::NodeKind::PROGRAM {
state.current_variable = n.svalue
Expand Down
1 change: 1 addition & 0 deletions src/debug.pr
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,7 @@ def tc_args_to_string(tpe: &typechecking::Type, full_name: bool) -> Str {
export def type_to_str(tpe: &typechecking::Type, full_name: bool = false) -> Str {
if not tpe { return "(none)" }
if tpe.tc_tpe { return tc_args_to_string(tpe, full_name) }
if not full_name and tpe.name { return tpe.name }
switch tpe.kind !int {
case typechecking::TypeKind::BOX
return "Box<" + type_to_str(tpe.wk, full_name) + ">"
Expand Down
33 changes: 22 additions & 11 deletions src/typechecking.pr
Original file line number Diff line number Diff line change
Expand Up @@ -1293,14 +1293,15 @@ def has_function(entry: &TypeEntry, intf: &Type, mb: StructuralTypeMember, modul
tpe = tpe.tpe
}

if tpe and tpe.kind == typechecking::TypeKind::STRUCT {
if tpe and tpe.kind == typechecking::TypeKind::STRUCT {
let fields = flatten_fields(tpe)
if is_setter(mb) {
let name = mb.name.slice(6, mb.name.length() - 2)
for var field in @tpe.fields {
for var field in fields {
if field.name == name and equals(mb.parameter_t(0).tpe, field.tpe) { return true }
}
} else if is_getter(mb) {
for var field in @tpe.fields {
for var field in fields {
if field.name == mb.name and equals(mb.return_t(0), field.tpe) { return true }
}
if tpe.const_fields {
Expand Down Expand Up @@ -1422,9 +1423,9 @@ export def implements(a: &Type, b: &Type, module: &toolchain::Module, visited: &
for var i in 0..vector::length(b.members) {
let mb = b.members(i)

if not has_function(type_entry, b, mb, module, visited.copy(), check_embed) {
if not has_function(type_entry, b, mb, module, visited.copy(), check_embed) {
type_entry.cached(nameb) = CacheEntry::NOT_CONTAINS
return false
return false
}
}
type_entry.cached(nameb) = CacheEntry::CONTAINS
Expand Down Expand Up @@ -1600,7 +1601,7 @@ export def convert_type_score(a: &Type, b: &Type, module: &toolchain::Module, is
}

// Embedded structs
if b.kind == TypeKind::STRUCT or is_ref(b) and b.tpe and b.tpe.kind == TypeKind::STRUCT {
if b.kind == TypeKind::STRUCT or (is_ref(b) and b.tpe and b.tpe.kind == TypeKind::STRUCT) {
var nb = b.tpe if is_ref(b) else b
for var field in @nb.fields {
if field.is_embed {
Expand Down Expand Up @@ -2758,7 +2759,11 @@ export def do_type_lookup(node: &parser::Node, state: &State, current_type: &Typ
else make_union_type(fields.to_array(), const_fields.to_array(), current_type))

tpe.line = node.loc.line
tpe.type_name = make_unique_name("<anonymous>", state)
if current_type and current_type.type_name {
tpe.type_name = current_type.type_name
} else {
tpe.type_name = make_unique_name("<anonymous>", state)
}
tpe.name = "<anonymous>"
tpe.line = node.loc.line

Expand Down Expand Up @@ -2882,7 +2887,13 @@ export def do_type_lookup(node: &parser::Node, state: &State, current_type: &Typ
} else if node.kind == parser::NodeKind::STRUCTURAL_T {
let tpe = make_type_raw(TypeKind::STRUCTURAL) if not current_type else current_type
tpe.kind = TypeKind::STRUCTURAL
tpe.type_name = make_unique_name("<anonymous>", state)

if current_type and current_type.type_name {
tpe.type_name = current_type.type_name
} else {
tpe.type_name = make_unique_name("<anonymous>", state)
}

tpe.name = "<anonymous>"

let members = vector::make(StructuralTypeMember)
Expand Down Expand Up @@ -5796,7 +5807,7 @@ def walk_MemberAccess_aggregate(node: &parser::Node, ucs: bool, state: &State) -
}

// TODO Make this a generator, doesn't work for some reason
def flatten_fields(tpe: &Type, state: &State, v: &Vector(StructMember) = null) -> &Vector(StructMember) {
def flatten_fields(tpe: &Type, v: &Vector(StructMember) = null) -> &Vector(StructMember) {
if not v { v = vector::make(StructMember) }
if not tpe { return v }
if not is_struct(tpe) {
Expand All @@ -5807,7 +5818,7 @@ def flatten_fields(tpe: &Type, state: &State, v: &Vector(StructMember) = null) -
for var field in @tpe.fields {
if field.is_embed {
let tpe = field.tpe.tpe if is_box(field.tpe) else field.tpe
flatten_fields(tpe, state, v)
flatten_fields(tpe, v)
} else {
v.push(field)
}
Expand Down Expand Up @@ -5969,7 +5980,7 @@ def walk_StructLit(node: &parser::Node, state: &State) {
let name = last_ident_to_str((@kwarg).value.named_arg.name)

var found = false
for var field in flatten_fields(tpe, state) {
for var field in flatten_fields(tpe) {
if field.name == name {
found = true

Expand Down

0 comments on commit d288928

Please sign in to comment.