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
132
133
134
135
136
|
/* ____ ____ ____ ____ ______ *\
** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
** /_____/\____/\___/\____/____/ **
** **
** $Id$
\* */
package scalac.symtab.classfile;
import ch.epfl.lamp.util.*;
import scalac.*;
import scalac.symtab.*;
import scalac.util.*;
import java.io.*;
import java.util.HashMap;
public class PackageParser extends SymbolLoader {
/** the class parser
*/
public ClassParser classCompletion;
public SymblParser symblCompletion; // provisional
protected final CLRPackageParser importer;
public PackageParser(Global global) {
super(global);
this.classCompletion = new ClassParser(global);
this.symblCompletion = new SymblParser(global); // provisional
if (global.reporter.verbose)
System.out.println("classpath = " + global.classPath);//debug
importer = (global.target == global.TARGET_MSIL)
? CLRPackageParser.create(global) : null;
}
/** complete package type symbol p by loading all package members
*/
protected String doComplete(Symbol p) {
Scope members = new Scope();
String dirname = null;
HashMap/*<Symbol, AbstractFile>*/ symFile = new HashMap();
if (!p.isRoot()) {
dirname = SourceRepresentation.externalizeFileName(p, "/");
}
String[] base = global.classPath.components();
for (int i = 0; i < base.length; i++) {
includeMembers(
AbstractFile.open(base[i], dirname),
p, members, symFile);
}
if (global.target == global.TARGET_MSIL)
importer.importCLRTypes(p, members, this);
p.setInfo(Type.compoundType(Type.EMPTY_ARRAY, members, p));
return dirname == null ? "anonymous package" : "package '"+dirname+"'";
}
private boolean isMostRecent(AbstractFile f, Symbol previous, HashMap symFile) {
if (previous == Symbol.NONE || previous.isPackage()) return true;
if (previous.pos != Position.NOPOS) return false;
AbstractFile pf = (AbstractFile) symFile.get(previous);
if (f.getName().endsWith(".scala")) {
if (pf.getName().endsWith(".scala")) return false;
if (!global.separate) return true;
}
if (f.getName().endsWith(".class")) {
if (pf.getName().endsWith(".class")) return false;
if (!global.separate) return false;
}
return f.lastModified() > pf.lastModified();
}
/** read directory of a classpath directory and include members
* in package/module scope
*/
protected void includeMembers(AbstractFile dir, Symbol p, Scope locals,
HashMap symFile) {
if (dir == null)
return;
boolean inclClasses = p != global.definitions.ROOT_CLASS;
String[] filenames = null;
try {
if ((filenames = dir.list()) == null)
return;
for (int j = 0; j < filenames.length; j++) {
String fname = filenames[j];
AbstractFile f = dir.open(fname);
if (inclClasses && fname.endsWith(".class")) {
Name n = Name.fromString(fname.substring(0, fname.length() - 6))
.toTypeName();
if (isMostRecent(f, locals.lookup(n), symFile)) {
ClassSymbol clazz = new ClassSymbol(n, p, classCompletion);
// todo: needed?
clazz.allConstructors().setInfo(classCompletion);
clazz.module().setInfo(classCompletion);
// enter class
locals.enter(clazz);
// enter module
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());
symFile.put(clazz, f);
}
} else if (inclClasses && fname.endsWith(".scala")) {
Name n = Name.fromString(fname.substring(0, fname.length() - 6))
.toTypeName();
if (isMostRecent(f, locals.lookup(n), symFile)) {
SourceCompleter completer = new SourceCompleter(global);
ClassSymbol clazz = new ClassSymbol(n, p, completer);
//todo: needed?
clazz.allConstructors().setInfo(completer);
clazz.module().setInfo(completer);
// enter class
locals.enter(clazz);
locals.enter(clazz.module());
symFile.put(clazz, f);
}
} 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);
//todo: moduleClass needs to be entered?
locals.enter(module.moduleClass());
}
}
}
} catch (IOException e) {
}
}
}
|