1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
/* ____ ____ ____ ____ ______ *\
** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
** /_____/\____/\___/\____/____/ **
** **
** $Id$
\* */
package scalac.symtab.classfile;
import scalac.*;
import scalac.symtab.*;
import scalac.util.*;
import java.io.*;
public class PackageParser extends Type.LazyType {
/** the global compilation environment
*/
protected Global global;
/** the class parser
*/
public ClassParser classCompletion;
public PackageParser(Global global) {
this.global = global;
this.classCompletion = new ClassParser(global);
}
/** complete package type symbol p by loading all package members
*/
public void complete(Symbol p) {
long msec = System.currentTimeMillis();
Scope members = new Scope();
String dirname = null;
Name name = p.fullName();
if (name.length() == 0) {
// includeMembers(AbstractFile.open(null, "."), p, members, false);
} else {
dirname = externalizeFileName(name);
assert !dirname.startsWith("com") : p;//debug
if (!dirname.endsWith("/"))
dirname += "/";
}
String[] base = global.classPath.components();
for (int i = 0; i < base.length; i++) {
includeMembers(
AbstractFile.open(base[i], dirname), p, members, dirname != null);
}
p.setInfo(Type.compoundType(Type.EMPTY_ARRAY, members, p));
if (dirname == null)
dirname = "anonymous package";
global.operation("scanned " + dirname + " in " +
(System.currentTimeMillis() - msec) + "ms");
}
/** read directory of a classpath directory and include members
* in package/module scope
*/
protected void includeMembers(AbstractFile dir, Symbol p, Scope locals,
boolean inclClasses) {
if (dir == null)
return;
String[] filenames = null;
try {
if ((filenames = dir.list()) == null)
return;
for (int j = 0; j < filenames.length; j++) {
String fname = filenames[j];
if (inclClasses && fname.endsWith(".class")) {
Name n = Name.fromString(fname.substring(0, fname.length() - 6))
.toTypeName();
if (locals.lookup(n) == Symbol.NONE) {
ClassSymbol clazz = new ClassSymbol(n, p, classCompletion);
clazz.constructor().setInfo(
classCompletion.staticsParser(clazz));
// enter class
locals.enter(clazz);
locals.enter(clazz.constructor());
// enter module, except for scala.Object class
// todo: why not there also?.
if (!(n == Names.Object.toTypeName() &&
p.fullName().toTermName() == Names.scala)) {
Scope.Entry e = locals.lookupEntry(clazz.module().name);
if (e != Scope.Entry.NONE) {
// we already have a package of the same name; delete it
locals.unlink(e);
}
locals.enter(clazz.module());
}
}
} else if (fname.endsWith("/") && !fname.equals("META-INF/")) {
Name n = Name.fromString(fname.substring(0, fname.length() - 1));
if (locals.lookup(n) == Symbol.NONE) {
TermSymbol module = TermSymbol.newJavaPackageModule(n, p, this);
locals.enter(module);
}
} else if (fname.endsWith(".scala")) {
Name n = Name.fromString(fname.substring(0, fname.length() - 6))
.toTypeName();
//if (locals.lookup(n) == Symbol.NONE) {
SourceCompleter completer = new SourceCompleter(global,
dir.getPath() + File.separatorChar + fname);
ClassSymbol clazz = new ClassSymbol(n, p, completer);
clazz.constructor().setInfo(completer);
clazz.module().setInfo(completer);
// enter class
locals.enter(clazz);
locals.enter(clazz.constructor());
locals.enter(clazz.module());
//}
}
}
} catch (IOException e) {
}
}
/** return external representation of file name s,
* converting '.' to File.separatorChar
*/
public String externalizeFileName(Name n) {
if ((n == null) || (n.length() == 0))
return ".";
byte[] ascii = n.toAscii();
String s = SourceRepresentation.ascii2string(
ascii, 0, ascii.length);
return s.replace('.', File.separatorChar);
}
}
|