Mercurial > projects > dil
comparison src/dil/semantic/Module.d @ 806:bcb74c9b895c
Moved out files in the trunk folder to the root.
author | Aziz K?ksal <aziz.koeksal@gmail.com> |
---|---|
date | Sun, 09 Mar 2008 00:12:19 +0100 |
parents | trunk/src/dil/semantic/Module.d@c24be8d4f6ab |
children | 525ee3f848d9 |
comparison
equal
deleted
inserted
replaced
805:a3fab8b74a7d | 806:bcb74c9b895c |
---|---|
1 /++ | |
2 Author: Aziz Köksal | |
3 License: GPL3 | |
4 +/ | |
5 module dil.semantic.Module; | |
6 | |
7 import dil.ast.Node; | |
8 import dil.ast.Declarations; | |
9 import dil.parser.Parser; | |
10 import dil.lexer.Lexer; | |
11 import dil.semantic.Symbol; | |
12 import dil.semantic.Symbols; | |
13 import dil.Information; | |
14 import dil.SourceText; | |
15 import common; | |
16 | |
17 import tango.io.FilePath; | |
18 import tango.io.FileConst; | |
19 | |
20 alias FileConst.PathSeparatorChar dirSep; | |
21 | |
22 /// Represents a semantic D module and a source file. | |
23 class Module : ScopeSymbol | |
24 { | |
25 SourceText sourceText; /// The source file of this module. | |
26 string moduleFQN; /// Fully qualified name of the module. E.g.: dil.ast.Node | |
27 string packageName; /// E.g.: dil.ast | |
28 string moduleName; /// E.g.: Node | |
29 | |
30 CompoundDeclaration root; /// The root of the parse tree. | |
31 ImportDeclaration[] imports; /// ImportDeclarations found in this file. | |
32 ModuleDeclaration moduleDecl; /// The optional ModuleDeclaration in this file. | |
33 Parser parser; /// The parser used to parse this file. | |
34 | |
35 // Module[] modules; | |
36 | |
37 InfoManager infoMan; /// Collects error messages. | |
38 | |
39 this() | |
40 { | |
41 super(SYM.Module, null, null); | |
42 } | |
43 | |
44 /// Constructs a Module object. | |
45 /// Params: | |
46 /// filePath = file path to the source text; loaded in the constructor. | |
47 /// infoMan = used for collecting error messages. | |
48 this(string filePath, InfoManager infoMan = null) | |
49 { | |
50 this(); | |
51 this.sourceText = new SourceText(filePath); | |
52 this.infoMan = infoMan; | |
53 this.sourceText.load(infoMan); | |
54 } | |
55 | |
56 /// Returns the file path of the source text. | |
57 string filePath() | |
58 { | |
59 return sourceText.filePath; | |
60 } | |
61 | |
62 /// Returns the file extension: "d" or "di". | |
63 string fileExtension() | |
64 { | |
65 foreach_reverse(i, c; filePath) | |
66 if (c == '.') | |
67 return filePath[i+1..$]; | |
68 return ""; | |
69 } | |
70 | |
71 /// Sets the parser to be used for parsing the source text. | |
72 void setParser(Parser parser) | |
73 { | |
74 this.parser = parser; | |
75 } | |
76 | |
77 /// Parses the module. | |
78 /// Throws: | |
79 /// An Exception if the there's no ModuleDeclaration and | |
80 /// the file name is an invalid or reserved D identifier. | |
81 void parse() | |
82 { | |
83 if (this.parser is null) | |
84 this.parser = new Parser(sourceText, infoMan); | |
85 | |
86 this.root = parser.start(); | |
87 this.imports = parser.imports; | |
88 | |
89 if (root.children.length) | |
90 { // moduleDecl will be null if first node isn't a ModuleDeclaration. | |
91 this.moduleDecl = root.children[0].Is!(ModuleDeclaration); | |
92 if (this.moduleDecl) | |
93 this.setFQN(moduleDecl.getFQN()); | |
94 } | |
95 | |
96 if (!this.moduleFQN.length) | |
97 { // Take base name of file path as module name. | |
98 auto str = (new FilePath(filePath)).name(); | |
99 if (Lexer.isReservedIdentifier(str)) | |
100 throw new Exception("'"~str~"' is not a valid module name; it's a reserved or invalid D identifier."); | |
101 this.moduleFQN = this.moduleName = str; | |
102 } | |
103 } | |
104 | |
105 /// Returns the first token of the module's source text. | |
106 Token* firstToken() | |
107 { | |
108 return parser.lexer.firstToken(); | |
109 } | |
110 | |
111 /// Returns true if there are errors in the source file. | |
112 bool hasErrors() | |
113 { | |
114 return parser.errors.length || parser.lexer.errors.length; | |
115 } | |
116 | |
117 /// Returns a list of import paths. | |
118 /// E.g.: ["dil/ast/Node", "dil/semantic/Module"] | |
119 string[] getImportPaths() | |
120 { | |
121 string[] result; | |
122 foreach (import_; imports) | |
123 result ~= import_.getModuleFQNs(dirSep); | |
124 return result; | |
125 } | |
126 | |
127 /// Returns the fully qualified name of this module. | |
128 /// E.g.: dil.ast.Node | |
129 string getFQN() | |
130 { | |
131 return moduleFQN; | |
132 } | |
133 | |
134 /// Set's the module's FQN. | |
135 void setFQN(string moduleFQN) | |
136 { | |
137 uint i = moduleFQN.length; | |
138 if (i != 0) // Don't decrement if string has zero length. | |
139 i--; | |
140 // Find last dot. | |
141 for (; i != 0 && moduleFQN[i] != '.'; i--) | |
142 {} | |
143 this.moduleFQN = moduleFQN; | |
144 this.packageName = moduleFQN[0..i]; | |
145 this.moduleName = moduleFQN[(i == 0 ? 0 : i+1) .. $]; | |
146 } | |
147 | |
148 /// Returns the module's FQN with slashes instead of dots. | |
149 /// E.g.: dil/ast/Node | |
150 string getFQNPath() | |
151 { | |
152 string FQNPath = moduleFQN.dup; | |
153 foreach (i, c; FQNPath) | |
154 if (c == '.') | |
155 FQNPath[i] = dirSep; | |
156 return FQNPath; | |
157 } | |
158 } |