1 /// Copyright: Copyright (c) 2017-2019 Andrey Penechko.
2 /// License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
3 /// Authors: Andrey Penechko.
4 module vox.fe.ast.decl.alias_;
5 
6 import vox.all;
7 
8 /// Aliases are super simple in implementation
9 /// Since they can only be used by name (via NameUseExprNode node),
10 /// we simply replace NameUseExprNode with aliased entity when name is resolved
11 @(AstType.decl_alias)
12 struct AliasDeclNode
13 {
14 	mixin AstNodeData!(AstType.decl_alias);
15 	ScopeIndex parentScope;
16 	Identifier id;
17 	AstIndex initializer;
18 }
19 
20 void print_alias(AliasDeclNode* node, ref AstPrintState state)
21 {
22 	state.print("ALIAS ", state.context.idString(node.id));
23 	print_ast(node.initializer, state);
24 }
25 
26 void post_clone_alias(AliasDeclNode* node, ref CloneState state)
27 {
28 	state.fixScope(node.parentScope);
29 	state.fixAstIndex(node.initializer);
30 }
31 
32 void name_register_self_alias(AstIndex nodeIndex, AliasDeclNode* node, ref NameRegisterState state)
33 {
34 	node.state = AstNodeState.name_register_self;
35 	node.parentScope.insert_scope(node.id, nodeIndex, state.context);
36 	node.state = AstNodeState.name_register_nested_done;
37 }
38 
39 void name_resolve_alias(AliasDeclNode* node, ref NameResolveState state)
40 {
41 	CompilationContext* c = state.context;
42 	node.state = AstNodeState.name_resolve;
43 	require_name_resolve(node.initializer, state);
44 	AstNode* initializer = node.initializer.get_node(c);
45 	if (initializer.isType) {
46 		// ok
47 	} else if (initializer.astType == AstType.expr_name_use) {
48 		// ok
49 		initializer.flags |= NameUseFlags.forbidParenthesesFreeCall;
50 	}
51 	else if (initializer.astType == AstType.expr_call)
52 	{
53 		// CTFE function that returns $alias
54 		node.initializer = eval_static_expr_alias(node.initializer, state.context);
55 		initializer = node.initializer.get_node(c);
56 	}
57 	else
58 	{
59 		c.error(node.loc, "Cannot create alias of %s", get_node_kind_name(node.initializer, c));
60 	}
61 	if (initializer.isType)
62 		node.flags |= AstFlags.isType;
63 	node.state = AstNodeState.name_resolve_done;
64 }
65 
66 void type_check_alias(AliasDeclNode* node, ref TypeCheckState state)
67 {
68 	node.state = AstNodeState.type_check;
69 	// user of NameUseExprNode will require type check of initializer
70 	node.state = AstNodeState.type_check_done;
71 }
72 
73 
74 @(AstType.decl_alias_array)
75 struct AliasArrayDeclNode {
76 	mixin AstNodeData!(AstType.decl_alias_array, 0, AstNodeState.type_check_done);
77 	AstNodes items;
78 }
79 
80 void print_alias_array(AliasArrayDeclNode* node, ref AstPrintState state)
81 {
82 	state.print("alias array ", node.items);
83 }