OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 library fasta.source_library_builder; | 5 library fasta.source_library_builder; |
6 | 6 |
7 import 'package:kernel/ast.dart' show AsyncMarker, ProcedureKind; | 7 import 'package:kernel/ast.dart' show AsyncMarker, ProcedureKind; |
8 | 8 |
9 import '../combinator.dart' show Combinator; | 9 import '../combinator.dart' show Combinator; |
10 | 10 |
11 import '../errors.dart' show inputError, internalError; | 11 import '../errors.dart' show inputError, internalError; |
12 | 12 |
13 import '../export.dart' show Export; | 13 import '../export.dart' show Export; |
14 | 14 |
15 import '../messages.dart' show warning; | |
16 | |
17 import '../import.dart' show Import; | 15 import '../import.dart' show Import; |
18 | 16 |
19 import 'source_loader.dart' show SourceLoader; | 17 import 'source_loader.dart' show SourceLoader; |
20 | 18 |
21 import '../builder/scope.dart' show Scope; | 19 import '../builder/scope.dart' show Scope; |
22 | 20 |
23 import '../builder/builder.dart' | 21 import '../builder/builder.dart' |
24 show | 22 show |
25 Builder, | 23 Builder, |
26 ClassBuilder, | 24 ClassBuilder, |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 "A file that's a part of a library can't have parts itself."); | 330 "A file that's a part of a library can't have parts itself."); |
333 } | 331 } |
334 if (exporters.isNotEmpty) { | 332 if (exporters.isNotEmpty) { |
335 Export export = exporters.first; | 333 Export export = exporters.first; |
336 inputError( | 334 inputError( |
337 export.fileUri, export.charOffset, "A part can't be exported."); | 335 export.fileUri, export.charOffset, "A part can't be exported."); |
338 } | 336 } |
339 } | 337 } |
340 | 338 |
341 void includeParts() { | 339 void includeParts() { |
| 340 Set<Uri> seenParts = new Set<Uri>(); |
342 for (SourceLibraryBuilder<T, R> part in parts.toList()) { | 341 for (SourceLibraryBuilder<T, R> part in parts.toList()) { |
343 if (part == this) { | 342 if (part == this) { |
344 addCompileTimeError(-1, "A file can't be a part of itself."); | 343 addCompileTimeError(-1, "A file can't be a part of itself."); |
| 344 } else if (seenParts.add(part.fileUri)) { |
| 345 includePart(part); |
345 } else { | 346 } else { |
346 includePart(part); | 347 addCompileTimeError( |
| 348 -1, "Can't use '${part.fileUri}' as a part more than once."); |
347 } | 349 } |
348 } | 350 } |
349 } | 351 } |
350 | 352 |
351 void includePart(SourceLibraryBuilder<T, R> part) { | 353 void includePart(SourceLibraryBuilder<T, R> part) { |
352 if (name != null) { | 354 if (name != null) { |
353 if (!part.isPart) { | 355 if (!part.isPart) { |
354 warning( | 356 addCompileTimeError( |
355 part.fileUri, | |
356 -1, | 357 -1, |
357 "Has no 'part of' declaration but is used as " | 358 "Can't use ${part.fileUri} as a part, because it has no 'part of'" |
358 "a part by ${name} ($uri)."); | 359 " declaration."); |
359 parts.remove(part); | 360 parts.remove(part); |
360 return; | 361 return; |
361 } | 362 } |
362 if (part.partOfName != name && part.partOfUri != uri) { | 363 if (part.partOfName != name && part.partOfUri != uri) { |
363 String partName = part.partOfName ?? "${part.partOfUri}"; | 364 String partName = part.partOfName ?? "${part.partOfUri}"; |
364 String myName = name == null ? "'$uri'" : "'${name}' ($uri)"; | 365 String myName = name == null ? "'$uri'" : "'${name}' ($uri)"; |
365 warning(part.fileUri, -1, | 366 addWarning( |
366 "Is part of '$partName' but is used as a part by $myName."); | 367 -1, |
367 parts.remove(part); | 368 "Using '${part.fileUri}' as part of '$myName' but it's 'part of'" |
368 return; | 369 " declaration says '$partName'."); |
| 370 // The part is still included. |
369 } | 371 } |
370 } | 372 } |
371 part.members.forEach((String name, Builder builder) { | 373 part.members.forEach((String name, Builder builder) { |
372 if (builder.next != null) { | 374 if (builder.next != null) { |
373 assert(builder.next.next == null); | 375 assert(builder.next.next == null); |
374 addBuilder(name, builder.next, builder.next.charOffset); | 376 addBuilder(name, builder.next, builder.next.charOffset); |
375 } | 377 } |
376 addBuilder(name, builder, builder.charOffset); | 378 addBuilder(name, builder, builder.charOffset); |
377 }); | 379 }); |
378 types.addAll(part.types); | 380 types.addAll(part.types); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 } | 538 } |
537 | 539 |
538 /// Called to register [procedure] as a factory whose types are collected in | 540 /// Called to register [procedure] as a factory whose types are collected in |
539 /// [factoryDeclaration]. Later, once the class has been built, we can | 541 /// [factoryDeclaration]. Later, once the class has been built, we can |
540 /// synthesize type variables on the factory matching the class'. | 542 /// synthesize type variables on the factory matching the class'. |
541 void addFactoryDeclaration( | 543 void addFactoryDeclaration( |
542 ProcedureBuilder procedure, DeclarationBuilder<T> factoryDeclaration) { | 544 ProcedureBuilder procedure, DeclarationBuilder<T> factoryDeclaration) { |
543 factoryDeclarations[procedure] = factoryDeclaration; | 545 factoryDeclarations[procedure] = factoryDeclaration; |
544 } | 546 } |
545 } | 547 } |
OLD | NEW |