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 }