Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(450)

Side by Side Diff: frog/library.dart

Issue 9107031: fix Library*NegativeTests (and a couple Prefix ones by accident) (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: rebased Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 class LibraryImport { 5 class LibraryImport {
6 String prefix; 6 final String prefix;
7 Library library; 7 final Library library;
8 LibraryImport(this.library, [this.prefix = null]); 8 final SourceSpan span;
9 LibraryImport(this.library, [this.prefix, this.span]);
10 }
11
12 // TODO(jimhug): Make this more useful for good error messages.
13 class AmbiguousMember extends Member {
14 List<Member> members;
15 AmbiguousMember(String name, this.members): super(name, null);
9 } 16 }
10 17
11 18
12 /** Represents a Dart library. */ 19 /** Represents a Dart library. */
13 class Library extends Element { 20 class Library extends Element {
14 final SourceFile baseSource; 21 final SourceFile baseSource;
15 Map<String, DefinedType> types; 22 Map<String, DefinedType> types;
16 List<LibraryImport> imports; 23 List<LibraryImport> imports;
17 String sourceDir; 24 String sourceDir;
18 List<SourceFile> natives; 25 List<SourceFile> natives;
19 List<SourceFile> sources; 26 List<SourceFile> sources;
20 27
28 Map<String, Member> _topNames;
21 Map<String, MemberSet> _privateMembers; 29 Map<String, MemberSet> _privateMembers;
22 30
23 /** The type that holds top level types in the library. */ 31 /** The type that holds top level types in the library. */
24 DefinedType topType; 32 DefinedType topType;
25 33
26 /** Set to true by [WorldGenerator] once this type has been written. */ 34 /** Set to true by [WorldGenerator] once this type has been written. */
27 bool isWritten = false; 35 bool isWritten = false;
28 36
29 Library(this.baseSource) : super(null, null) { 37 Library(this.baseSource) : super(null, null) {
30 sourceDir = dirname(baseSource.filename); 38 sourceDir = dirname(baseSource.filename);
(...skipping 21 matching lines...) Expand all
52 String makeFullPath(String filename) { 60 String makeFullPath(String filename) {
53 if (filename.startsWith('dart:')) return filename; 61 if (filename.startsWith('dart:')) return filename;
54 // TODO(jmesserly): replace with node.js path.resolve 62 // TODO(jmesserly): replace with node.js path.resolve
55 if (filename.startsWith('/')) return filename; 63 if (filename.startsWith('/')) return filename;
56 if (filename.startsWith('file:///')) return filename; 64 if (filename.startsWith('file:///')) return filename;
57 if (filename.startsWith('http://')) return filename; 65 if (filename.startsWith('http://')) return filename;
58 return joinPaths(sourceDir, filename); 66 return joinPaths(sourceDir, filename);
59 } 67 }
60 68
61 /** Adds an import to the library. */ 69 /** Adds an import to the library. */
62 addImport(String fullname, String prefix) { 70 addImport(String fullname, String prefix, SourceSpan span) {
63 var newLib = world.getOrAddLibrary(fullname); 71 var newLib = world.getOrAddLibrary(fullname);
64 imports.add(new LibraryImport(newLib, prefix)); 72 // Special exemption in spec to ensure core is only imported once
Jennifer Messerly 2012/01/12 01:58:33 Is this to avoid our implicit import of dart:core
73 if (newLib.isCore) return;
74 imports.add(new LibraryImport(newLib, prefix, span));
65 return newLib; 75 return newLib;
66 } 76 }
67 77
68 addNative(String fullname) { 78 addNative(String fullname) {
69 natives.add(world.reader.readFile(fullname)); 79 natives.add(world.reader.readFile(fullname));
70 } 80 }
71 81
72 MemberSet _findMembers(String name) { 82 MemberSet _findMembers(String name) {
73 if (name.startsWith('_')) { 83 if (name.startsWith('_')) {
74 return _privateMembers[name]; 84 return _privateMembers[name];
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 return null; 166 return null;
157 } 167 }
158 168
159 // The type we got back was the "top level" library type. 169 // The type we got back was the "top level" library type.
160 // Now perform a lookup in that library for the next name. 170 // Now perform a lookup in that library for the next name.
161 return result.library.findTypeByName(type.names[0].name); 171 return result.library.findTypeByName(type.names[0].name);
162 } 172 }
163 return result; 173 return result;
164 } 174 }
165 175
176 // TODO(jimhug): Should be merged with new lookup method's logic.
166 Type findTypeByName(String name) { 177 Type findTypeByName(String name) {
167 var ret = types[name]; 178 var ret = types[name];
168 179
169 // Check all imports even if ret != null to detect conflicting names. 180 // Check all imports even if ret != null to detect conflicting names.
170 // TODO(jimhug): Only do this on first lookup. 181 // TODO(jimhug): Only do this on first lookup.
171 for (var imported in imports) { 182 for (var imported in imports) {
172 var newRet = null; 183 var newRet = null;
173 if (imported.prefix == null) { 184 if (imported.prefix == null) {
174 newRet = imported.library.types[name]; 185 newRet = imported.library.types[name];
175 } else if (imported.prefix == name) { 186 } else if (imported.prefix == name) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 220
210 static String _getDottedName(NameTypeReference type) { 221 static String _getDottedName(NameTypeReference type) {
211 if (type.names != null) { 222 if (type.names != null) {
212 var names = map(type.names, (n) => n.name); 223 var names = map(type.names, (n) => n.name);
213 return type.name.name + '.' + Strings.join(names, '.'); 224 return type.name.name + '.' + Strings.join(names, '.');
214 } else { 225 } else {
215 return type.name.name; 226 return type.name.name;
216 } 227 }
217 } 228 }
218 229
219 Member lookup(String name, SourceSpan span) { 230 Member lookup(String name, SourceSpan span) {
Jennifer Messerly 2012/01/12 01:58:33 Member lookup(String name, SourceSpan span) => _to
220 var retType = findTypeByName(name); 231 return _topNames[name];
221 var ret = null;
222
223 if (retType != null) {
224 ret = retType.typeMember;
225 }
226
227 var newRet = topType.getMember(name);
228 // TODO(jimhug): Shares too much code with body of loop.
229 if (newRet != null) {
230 if (ret != null && ret != newRet) {
231 world.error('conflicting members for "$name"',
232 span, ret.span, newRet.span);
233 } else {
234 ret = newRet;
235 }
236 }
237
238 // Check all imports even if ret != null to detect conflicting names.
239 // TODO(jimhug): Only do this on first lookup.
240 for (var imported in imports) {
241 if (imported.prefix == null) {
242 newRet = imported.library.topType.getMember(name);
243 if (newRet != null) {
244 if (ret != null && ret != newRet) {
245 world.error('conflicting members for "$name"',
246 span, ret.span, newRet.span);
247 } else {
248 ret = newRet;
249 }
250 }
251 }
252 }
253 return ret;
254 } 232 }
255 233
256 resolve() { 234 resolve() {
257 if (name == null) { 235 if (name == null) {
258 // TODO(jimhug): More fodder for io library. 236 // TODO(jimhug): More fodder for io library.
259 name = baseSource.filename; 237 name = baseSource.filename;
260 var index = name.lastIndexOf('/', name.length); 238 var index = name.lastIndexOf('/', name.length);
261 if (index >= 0) { 239 if (index >= 0) {
262 name = name.substring(index+1); 240 name = name.substring(index+1);
263 } 241 }
264 index = name.indexOf('.'); 242 index = name.indexOf('.');
265 if (index > 0) { 243 if (index > 0) {
266 name = name.substring(0, index); 244 name = name.substring(0, index);
267 } 245 }
268 } 246 }
269 // TODO(jimhug): Expand to handle all illegal id characters 247 // TODO(jimhug): Expand to handle all illegal id characters
270 _jsname = 248 _jsname =
271 name.replaceAll('.', '_').replaceAll(':', '_').replaceAll(' ', '_'); 249 name.replaceAll('.', '_').replaceAll(':', '_').replaceAll(' ', '_');
272 250
273 for (var type in types.getValues()) { 251 for (var type in types.getValues()) {
274 type.resolve(); 252 type.resolve();
275 } 253 }
276 } 254 }
277 255
256 _addTopName(String name, Member member, [SourceSpan localSpan]) {
257 var existing = _topNames[name];
258 if (existing === null) {
259 _topNames[name] = member;
260 } else {
261 if (existing is AmbiguousMember) {
262 existing.members.add(member);
263 } else {
264 var newMember = new AmbiguousMember(name, [existing, member]);
265 world.error('conflicting members for "$name"',
266 existing.span, member.span, localSpan);
267 _topNames[name] = newMember;
268 }
269 }
270 }
271
272 _addTopNames(Library lib) {
273 for (var member in lib.topType.members.getValues()) {
274 if (member.isPrivate && lib != this) continue;
275 _addTopName(member.name, member);
276 }
277 for (var type in lib.types.getValues()) {
278 if (!type.isTop) {
279 if (lib != this && type.typeMember.isPrivate) continue;
280 _addTopName(type.name, type.typeMember);
281 }
282 }
283 }
284
285 /**
286 * This method will check for any conflicts in top-level names in this
287 * library. It will also build up a map from top-level names to a single
288 * member to be used for future lookups both to keep error messages clean
289 * and as a minor perf optimization.
290 */
291 postResolveChecks() {
292 _topNames = {};
293 // check for conflicts between top-level names
294 _addTopNames(this);
295 for (var imported in imports) {
296 if (imported.prefix == null) {
297 _addTopNames(imported.library);
298 } else {
299 _addTopName(imported.prefix, imported.library.topType.typeMember,
300 imported.span);
301 }
302 }
303 }
304
278 visitSources() { 305 visitSources() {
279 var visitor = new _LibraryVisitor(this); 306 var visitor = new _LibraryVisitor(this);
280 visitor.addSource(baseSource); 307 visitor.addSource(baseSource);
281 } 308 }
282 309
283 toString() => baseSource.filename; 310 toString() => baseSource.filename;
284 311
285 int hashCode() => baseSource.filename.hashCode(); 312 int hashCode() => baseSource.filename.hashCode();
286 313
287 bool operator ==(other) => other is Library && 314 bool operator ==(other) => other is Library &&
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 if (prefix == '') prefix = null; 410 if (prefix == '') prefix = null;
384 411
385 var filename = library.makeFullPath(name); 412 var filename = library.makeFullPath(name);
386 413
387 if (library.imports.some((li) => li.library.baseSource == filename)) { 414 if (library.imports.some((li) => li.library.baseSource == filename)) {
388 // TODO(jimhug): Can you import a lib twice with different prefixes? 415 // TODO(jimhug): Can you import a lib twice with different prefixes?
389 world.error('duplicate import of "$name"', node.span); 416 world.error('duplicate import of "$name"', node.span);
390 return; 417 return;
391 } 418 }
392 419
393 var newLib = library.addImport(filename, prefix); 420 var newLib = library.addImport(filename, prefix, node.span);
394 // TODO(jimhug): Add check that imported library has a #library 421 // TODO(jimhug): Add check that imported library has a #library
395 break; 422 break;
396 423
397 case "source": 424 case "source":
398 seenSource = true; 425 seenSource = true;
399 name = getSingleStringArg(node); 426 name = getSingleStringArg(node);
400 addSourceFromName(name, node.span); 427 addSourceFromName(name, node.span);
401 if (seenResource) { 428 if (seenResource) {
402 world.error('#sources must come before any #resource', node.span); 429 world.error('#sources must come before any #resource', node.span);
403 } 430 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 510
484 void visitFunctionDefinition(FunctionDefinition node) { 511 void visitFunctionDefinition(FunctionDefinition node) {
485 currentType.addMethod(node.name.name, node); 512 currentType.addMethod(node.name.name, node);
486 } 513 }
487 514
488 void visitFunctionTypeDefinition(FunctionTypeDefinition node) { 515 void visitFunctionTypeDefinition(FunctionTypeDefinition node) {
489 var type = library.addType(node.func.name.name, node, false); 516 var type = library.addType(node.func.name.name, node, false);
490 type.addMethod(':call', node.func); 517 type.addMethod(':call', node.func);
491 } 518 }
492 } 519 }
OLDNEW
« no previous file with comments | « frog/lib/corelib_impl.dart ('k') | frog/member.dart » ('j') | frog/member.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698