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 }