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
|
/* ____ ____ ____ ____ ______ *\
** / __// __ \/ __// __ \/ ____/ 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();
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);
}
}
|