Share method extensions across modules by default. Fix bug in string split.

This commit is contained in:
Christoffer Lerno
2022-12-14 10:55:35 +01:00
committed by Christoffer Lerno
parent dcf0b4c580
commit abf0f64ac0
11 changed files with 45 additions and 19 deletions

View File

@@ -51,6 +51,7 @@ void compiler_init(const char *std_lib_dir)
htable_init(&global_context.compiler_defines, 16 * 1024);
global_context.module_list = NULL;
global_context.generic_module_list = NULL;
global_context.method_extensions = NULL;
vmem_init(&ast_arena, 512);
ast_calloc();
vmem_init(&expr_arena, 512);

View File

@@ -1452,7 +1452,7 @@ typedef struct Module_
AnalysisStage stage : 6;
AstId docs;
Decl** method_extensions;
Decl** private_method_extensions;
HTable symbols;
struct CompilationUnit_ **units;
Module *parent_module;
@@ -1645,6 +1645,7 @@ typedef struct
Module **module_list;
Module **generic_module_list;
Type **type;
Decl** method_extensions;
const char *lib_dir;
const char **sources;
File **loaded_sources;
@@ -2204,7 +2205,7 @@ Decl *sema_find_decl_in_modules(Module **module_list, Path *path, const char *in
Decl *unit_resolve_parameterized_symbol(CompilationUnit *unit, NameResolve *name_resolve);
Decl *sema_resolve_type_method(CompilationUnit *unit, Type *type, const char *method_name, Decl **ambiguous_ref, Decl **private_ref);
Decl *sema_resolve_method(CompilationUnit *unit, Decl *type, const char *method_name, Decl **ambiguous_ref, Decl **private_ref);
Decl *sema_find_extension_method_in_module(Module *module, Type *type, const char *method_name);
Decl *sema_find_extension_method_in_module(Decl **extensions, Type *type, const char *method_name);
Decl *sema_find_symbol(SemaContext *context, const char *symbol);
Decl *sema_find_path_symbol(SemaContext *context, const char *symbol, Path *path);

View File

@@ -1184,7 +1184,7 @@ static bool sema_analyse_operator_common(Decl *method, TypeInfo **rtype_ptr, Dec
static inline Decl *operator_in_module(SemaContext *c, Module *module, OperatorOverload operator_overload)
{
if (module->is_generic) return NULL;
Decl **extensions = module->method_extensions;
Decl **extensions = module->private_method_extensions;
VECEACH(extensions, j)
{
Decl *extension = extensions[j];
@@ -1299,7 +1299,14 @@ static inline bool unit_add_base_extension_method(CompilationUnit *unit, Type *p
method_like->extname = scratch_buffer_copy();
}
DEBUG_LOG("Method-like '%s.%s' analysed.", parent_type->name, method_like->name);
vec_add(unit->module->method_extensions, method_like);
if (method_like->visibility == VISIBLE_LOCAL)
{
vec_add(unit->module->private_method_extensions, method_like);
}
else
{
vec_add(global_context.method_extensions, method_like);
}
return true;
}
@@ -1307,13 +1314,15 @@ static inline bool unit_add_method_like(CompilationUnit *unit, Type *parent_type
{
assert(parent_type->canonical == parent_type);
const char *name = method_like->name;
Decl *method = sema_find_extension_method_in_module(unit->module, parent_type, name);
Decl *method = sema_find_extension_method_in_module(unit->module->private_method_extensions, parent_type, name);
if (!method) sema_find_extension_method_in_module(global_context.method_extensions, parent_type, name);
if (method)
{
SEMA_ERROR(method_like, "This %s is already defined in this module.", method_name_by_decl(method_like));
SEMA_ERROR(method_like, "This %s is already defined.", method_name_by_decl(method_like));
SEMA_NOTE(method, "The previous definition was here.");
return false;
}
if (!type_is_user_defined(parent_type)) return unit_add_base_extension_method(unit, parent_type, method_like);
Decl *parent = parent_type->decl;
Decl *ambiguous = NULL;
@@ -1346,13 +1355,13 @@ static inline bool unit_add_method_like(CompilationUnit *unit, Type *parent_type
method_like->extname = scratch_buffer_copy();
}
DEBUG_LOG("Method-like '%s.%s' analysed.", parent->name, method_like->name);
if (parent->unit->module == unit->module)
if (parent->unit->module == unit->module || method_like->visibility != VISIBLE_LOCAL)
{
vec_add(parent->methods, method_like);
}
else
{
vec_add(unit->module->method_extensions, method_like);
vec_add(unit->module->private_method_extensions, method_like);
}
return true;

View File

@@ -568,9 +568,8 @@ INLINE Decl *sema_resolve_symbol_common(SemaContext *context, NameResolve *name_
return decl;
}
Decl *sema_find_extension_method_in_module(Module *module, Type *type, const char *method_name)
Decl *sema_find_extension_method_in_module(Decl **extensions, Type *type, const char *method_name)
{
Decl **extensions = module->method_extensions;
VECEACH(extensions, i)
{
Decl *extension = extensions[i];
@@ -593,7 +592,7 @@ Decl *sema_resolve_method_in_module(Module *module, Type *actual_type, const cha
Decl **private_found, Decl **ambiguous, MethodSearchType search_type)
{
if (module->is_generic) return NULL;
Decl *found = sema_find_extension_method_in_module(module, actual_type, method_name);
Decl *found = sema_find_extension_method_in_module(module->private_method_extensions, actual_type, method_name);
// The found one might not be visible
if (found && search_type < METHOD_SEARCH_CURRENT && found->visibility < VISIBLE_PUBLIC)
{
@@ -676,6 +675,11 @@ Decl *sema_resolve_type_method(CompilationUnit *unit, Type *type, const char *me
*ambiguous_ref = ambiguous;
return found;
}
if (!found)
{
found = sema_find_extension_method_in_module(global_context.method_extensions, type, method_name);
private = NULL;
}
if (private) *private_ref = private;
if (!found)
{

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.3.117"
#define COMPILER_VERSION "0.3.118"