Browse Source

Add attribute `@(require) import "foo"` to replace/supplement `_ :: foo`

gingerBill 2 years ago
parent
commit
1cdb975c91
3 changed files with 28 additions and 5 deletions
  1. 23 4
      src/checker.cpp
  2. 4 1
      src/parser.cpp
  3. 1 0
      src/parser.hpp

+ 23 - 4
src/checker.cpp

@@ -4505,6 +4505,23 @@ gb_internal String get_invalid_import_name(String input) {
 	return input;
 }
 
+gb_internal DECL_ATTRIBUTE_PROC(import_decl_attribute) {
+	if (name == ATTRIBUTE_USER_TAG_NAME) {
+		ExactValue ev = check_decl_attribute_value(c, value);
+		if (ev.kind != ExactValue_String) {
+			error(elem, "Expected a string value for '%.*s'", LIT(name));
+		}
+		return true;
+	} else if (name == "require") {
+		if (value != nullptr) {
+			error(elem, "Expected no parameter for '%.*s'", LIT(name));
+		}
+		ac->require_declaration = true;
+		return true;
+	}
+	return false;
+}
+
 gb_internal void check_add_import_decl(CheckerContext *ctx, Ast *decl) {
 	if (decl->state_flags & StateFlag_BeenHandled) return;
 	decl->state_flags |= StateFlag_BeenHandled;
@@ -4553,10 +4570,12 @@ gb_internal void check_add_import_decl(CheckerContext *ctx, Ast *decl) {
 		force_use = true;
 	}
 
-	// NOTE(bill, 2019-05-19): If the directory path is not a valid entity name, force the user to assign a custom one
-	// if (import_name.len == 0 || import_name == "_") {
-	// 	import_name = scope->pkg->name;
-	// }
+	AttributeContext ac = {};
+	check_decl_attributes(ctx, id->attributes, import_decl_attribute, &ac);
+	if (ac.require_declaration) {
+		force_use = true;
+	}
+
 
 	if (import_name.len == 0) {
 		String invalid_name = id->fullpath;

+ 4 - 1
src/parser.cpp

@@ -1212,6 +1212,7 @@ gb_internal Ast *ast_import_decl(AstFile *f, Token token, Token relpath, Token i
 	result->ImportDecl.import_name = import_name;
 	result->ImportDecl.docs        = docs;
 	result->ImportDecl.comment     = comment;
+	result->ImportDecl.attributes.allocator = ast_allocator(f);
 	return result;
 }
 
@@ -4634,7 +4635,9 @@ gb_internal Ast *parse_attribute(AstFile *f, Token token, TokenKind open_kind, T
 		array_add(&decl->ForeignBlockDecl.attributes, attribute);
 	} else if (decl->kind == Ast_ForeignImportDecl) {
 		array_add(&decl->ForeignImportDecl.attributes, attribute);
-	}else {
+	} else if (decl->kind == Ast_ImportDecl) {
+		array_add(&decl->ImportDecl.attributes, attribute);
+	} else {
 		syntax_error(decl, "Expected a value or foreign declaration after an attribute, got %.*s", LIT(ast_strings[decl->kind]));
 		return ast_bad_stmt(f, token, f->curr_token);
 	}

+ 1 - 0
src/parser.hpp

@@ -617,6 +617,7 @@ AST_KIND(_DeclBegin,      "", bool) \
 		Token    relpath;       \
 		String   fullpath;      \
 		Token    import_name;   \
+		Array<Ast *> attributes;  \
 		CommentGroup *docs;     \
 		CommentGroup *comment;  \
 	}) \