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 }