| 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 | 7 import 'package:kernel/ast.dart' show |
| 8 AsyncMarker, | 8 AsyncMarker, |
| 9 ProcedureKind; | 9 ProcedureKind; |
| 10 | 10 |
| 11 import '../combinator.dart' show | 11 import '../combinator.dart' show |
| 12 Combinator; | 12 Combinator; |
| 13 | 13 |
| 14 import '../errors.dart' show | 14 import '../errors.dart' show |
| 15 internalError; | 15 internalError; |
| 16 | 16 |
| 17 import '../import.dart' show | 17 import '../import.dart' show |
| 18 Import; | 18 Import; |
| 19 | 19 |
| 20 import 'source_loader.dart' show | 20 import 'source_loader.dart' show |
| 21 SourceLoader; | 21 SourceLoader; |
| 22 | 22 |
| 23 import '../builder/scope.dart' show | 23 import '../builder/scope.dart' show |
| 24 Scope; | 24 Scope; |
| 25 | 25 |
| 26 import '../builder/builder.dart' show | 26 import '../builder/builder.dart' show |
| 27 Builder, | 27 Builder, |
| 28 ClassBuilder, |
| 28 ConstructorReferenceBuilder, | 29 ConstructorReferenceBuilder, |
| 29 FormalParameterBuilder, | 30 FormalParameterBuilder, |
| 30 LibraryBuilder, | 31 LibraryBuilder, |
| 31 MemberBuilder, | 32 MemberBuilder, |
| 32 MetadataBuilder, | 33 MetadataBuilder, |
| 33 PrefixBuilder, | 34 PrefixBuilder, |
| 34 ProcedureBuilder, | 35 ProcedureBuilder, |
| 35 TypeBuilder, | 36 TypeBuilder, |
| 36 TypeDeclarationBuilder, | 37 TypeDeclarationBuilder, |
| 37 TypeVariableBuilder, | 38 TypeVariableBuilder, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 50 final List<SourceLibraryBuilder<T, R>> parts = <SourceLibraryBuilder<T, R>>[]; | 51 final List<SourceLibraryBuilder<T, R>> parts = <SourceLibraryBuilder<T, R>>[]; |
| 51 | 52 |
| 52 final List<Import> imports = <Import>[]; | 53 final List<Import> imports = <Import>[]; |
| 53 | 54 |
| 54 final Map<String, Builder> exports = <String, Builder>{}; | 55 final Map<String, Builder> exports = <String, Builder>{}; |
| 55 | 56 |
| 56 final Scope scope = new Scope(<String, Builder>{}, null, isModifiable: false); | 57 final Scope scope = new Scope(<String, Builder>{}, null, isModifiable: false); |
| 57 | 58 |
| 58 final Uri fileUri; | 59 final Uri fileUri; |
| 59 | 60 |
| 61 final List<List> implementationBuilders = <List<List>>[]; |
| 62 |
| 60 String name; | 63 String name; |
| 61 | 64 |
| 62 String partOf; | 65 String partOf; |
| 63 | 66 |
| 64 List<MetadataBuilder> metadata; | 67 List<MetadataBuilder> metadata; |
| 65 | 68 |
| 66 /// The current declaration that is being built. When we start parsing a | 69 /// The current declaration that is being built. When we start parsing a |
| 67 /// declaration (class, method, and so on), we don't have enough information | 70 /// declaration (class, method, and so on), we don't have enough information |
| 68 /// to create a builder and this object records its members and types until, | 71 /// to create a builder and this object records its members and types until, |
| 69 /// for example, [addClass] is called. | 72 /// for example, [addClass] is called. |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 AsyncMarker asyncModifier, ConstructorReferenceBuilder redirectionTarget, | 194 AsyncMarker asyncModifier, ConstructorReferenceBuilder redirectionTarget, |
| 192 int charOffset, String nativeMethodName); | 195 int charOffset, String nativeMethodName); |
| 193 | 196 |
| 194 FormalParameterBuilder addFormalParameter( | 197 FormalParameterBuilder addFormalParameter( |
| 195 List<MetadataBuilder> metadata, int modifiers, | 198 List<MetadataBuilder> metadata, int modifiers, |
| 196 T type, String name, bool hasThis, int charOffset); | 199 T type, String name, bool hasThis, int charOffset); |
| 197 | 200 |
| 198 TypeVariableBuilder addTypeVariable(String name, T bound, int charOffset); | 201 TypeVariableBuilder addTypeVariable(String name, T bound, int charOffset); |
| 199 | 202 |
| 200 Builder addBuilder(String name, Builder builder, int charOffset) { | 203 Builder addBuilder(String name, Builder builder, int charOffset) { |
| 201 if (name.indexOf(".") != -1) { | 204 if (name.indexOf(".") != -1 && name.indexOf("&") == -1) { |
| 202 addCompileTimeError(charOffset, "Only constructors and factories can have" | 205 addCompileTimeError(charOffset, "Only constructors and factories can have" |
| 203 " names containing a period ('.'): $name"); | 206 " names containing a period ('.'): $name"); |
| 204 } | 207 } |
| 205 // TODO(ahe): Set the parent correctly here. Could then change the | 208 // TODO(ahe): Set the parent correctly here. Could then change the |
| 206 // implementation of MemberBuilder.isTopLevel to test explicitly for a | 209 // implementation of MemberBuilder.isTopLevel to test explicitly for a |
| 207 // LibraryBuilder. | 210 // LibraryBuilder. |
| 208 if (currentDeclaration == libraryDeclaration) { | 211 if (currentDeclaration == libraryDeclaration) { |
| 209 if (builder is MemberBuilder) { | 212 if (builder is MemberBuilder) { |
| 210 builder.parent = this; | 213 builder.parent = this; |
| 211 } else if (builder is TypeDeclarationBuilder) { | 214 } else if (builder is TypeDeclarationBuilder) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 224 if (builder is PrefixBuilder && existing is PrefixBuilder) { | 227 if (builder is PrefixBuilder && existing is PrefixBuilder) { |
| 225 assert(existing.next == null); | 228 assert(existing.next == null); |
| 226 builder.exports.forEach((String name, Builder builder) { | 229 builder.exports.forEach((String name, Builder builder) { |
| 227 Builder other = existing.exports.putIfAbsent(name, () => builder); | 230 Builder other = existing.exports.putIfAbsent(name, () => builder); |
| 228 if (other != builder) { | 231 if (other != builder) { |
| 229 existing.exports[name] = | 232 existing.exports[name] = |
| 230 other.combineAmbiguousImport(name, builder, this); | 233 other.combineAmbiguousImport(name, builder, this); |
| 231 } | 234 } |
| 232 }); | 235 }); |
| 233 return existing; | 236 return existing; |
| 234 } else if (existing != null && (existing.next != null || | 237 } else if (isDuplicatedDefinition(existing, builder)) { |
| 235 ((!existing.isGetter || !builder.isSetter) && | |
| 236 (!existing.isSetter || !builder.isGetter)))) { | |
| 237 addCompileTimeError(charOffset, "Duplicated definition of '$name'."); | 238 addCompileTimeError(charOffset, "Duplicated definition of '$name'."); |
| 238 } | 239 } |
| 239 return members[name] = builder; | 240 return members[name] = builder; |
| 240 } | 241 } |
| 241 | 242 |
| 243 bool isDuplicatedDefinition(Builder existing, Builder other) { |
| 244 if (existing == null) return false; |
| 245 Builder next = existing.next; |
| 246 if (next == null) { |
| 247 if (existing.isGetter && other.isSetter) return false; |
| 248 if (existing.isSetter && other.isGetter) return false; |
| 249 } else { |
| 250 if (next is ClassBuilder && !next.isMixinApplication) return true; |
| 251 } |
| 252 if (existing is ClassBuilder && other is ClassBuilder) { |
| 253 // We allow multiple mixin applications with the same name. An |
| 254 // alternative is to share these mixin applications. This situation can |
| 255 // happen if you have `class A extends Object with Mixin {}` and `class B |
| 256 // extends Object with Mixin {}` in the same library. |
| 257 return !existing.isMixinApplication || !other.isMixinApplication; |
| 258 } |
| 259 return true; |
| 260 } |
| 261 |
| 242 void buildBuilder(Builder builder); | 262 void buildBuilder(Builder builder); |
| 243 | 263 |
| 244 R build() { | 264 R build() { |
| 265 assert(implementationBuilders.isEmpty); |
| 245 members.forEach((String name, Builder builder) { | 266 members.forEach((String name, Builder builder) { |
| 246 do { | 267 do { |
| 247 buildBuilder(builder); | 268 buildBuilder(builder); |
| 248 builder = builder.next; | 269 builder = builder.next; |
| 249 } while (builder != null); | 270 } while (builder != null); |
| 250 }); | 271 }); |
| 272 for (List list in implementationBuilders) { |
| 273 String name = list[0]; |
| 274 Builder builder = list[1]; |
| 275 int charOffset = list[2]; |
| 276 addBuilder(name, builder, charOffset); |
| 277 buildBuilder(builder); |
| 278 } |
| 251 return null; | 279 return null; |
| 252 } | 280 } |
| 253 | 281 |
| 282 void addImplementationBuilder(String name, Builder builder, int charOffset) { |
| 283 implementationBuilders.add([name, builder, charOffset]); |
| 284 } |
| 285 |
| 254 void validatePart() { | 286 void validatePart() { |
| 255 if (parts.isNotEmpty) { | 287 if (parts.isNotEmpty) { |
| 256 internalError("Part with parts: $uri"); | 288 internalError("Part with parts: $uri"); |
| 257 } | 289 } |
| 258 if (exporters.isNotEmpty) { | 290 if (exporters.isNotEmpty) { |
| 259 internalError( | 291 internalError( |
| 260 "${exporters.first.exporter.uri} attempts to export the part $uri."); | 292 "${exporters.first.exporter.uri} attempts to export the part $uri."); |
| 261 } | 293 } |
| 262 } | 294 } |
| 263 | 295 |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 } | 469 } |
| 438 | 470 |
| 439 /// Called to register [procedure] as a factory whose types are collected in | 471 /// Called to register [procedure] as a factory whose types are collected in |
| 440 /// [factoryDeclaration]. Later, once the class has been built, we can | 472 /// [factoryDeclaration]. Later, once the class has been built, we can |
| 441 /// synthesize type variables on the factory matching the class'. | 473 /// synthesize type variables on the factory matching the class'. |
| 442 void addFactoryDeclaration( | 474 void addFactoryDeclaration( |
| 443 ProcedureBuilder procedure, DeclarationBuilder<T> factoryDeclaration) { | 475 ProcedureBuilder procedure, DeclarationBuilder<T> factoryDeclaration) { |
| 444 factoryDeclarations[procedure] = factoryDeclaration; | 476 factoryDeclarations[procedure] = factoryDeclaration; |
| 445 } | 477 } |
| 446 } | 478 } |
| OLD | NEW |