Chromium Code Reviews| 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) { | |
|
karlklose
2017/02/15 09:09:30
Please add a comment about what invariance this ha
ahe
2017/02/15 09:36:51
Done.
| |
| 253 return !existing.isMixinApplication || !other.isMixinApplication; | |
| 254 } | |
| 255 return true; | |
| 256 } | |
| 257 | |
| 242 void buildBuilder(Builder builder); | 258 void buildBuilder(Builder builder); |
| 243 | 259 |
| 244 R build() { | 260 R build() { |
| 261 assert(implementationBuilders.isEmpty); | |
| 245 members.forEach((String name, Builder builder) { | 262 members.forEach((String name, Builder builder) { |
| 246 do { | 263 do { |
| 247 buildBuilder(builder); | 264 buildBuilder(builder); |
| 248 builder = builder.next; | 265 builder = builder.next; |
| 249 } while (builder != null); | 266 } while (builder != null); |
| 250 }); | 267 }); |
| 268 for (List list in implementationBuilders) { | |
| 269 String name = list[0]; | |
| 270 Builder builder = list[1]; | |
| 271 int charOffset = list[2]; | |
| 272 addBuilder(name, builder, charOffset); | |
| 273 buildBuilder(builder); | |
| 274 } | |
| 251 return null; | 275 return null; |
| 252 } | 276 } |
| 253 | 277 |
| 278 void addImplementationBuilder(String name, Builder builder, int charOffset) { | |
| 279 implementationBuilders.add([name, builder, charOffset]); | |
| 280 } | |
| 281 | |
| 254 void validatePart() { | 282 void validatePart() { |
| 255 if (parts.isNotEmpty) { | 283 if (parts.isNotEmpty) { |
| 256 internalError("Part with parts: $uri"); | 284 internalError("Part with parts: $uri"); |
| 257 } | 285 } |
| 258 if (exporters.isNotEmpty) { | 286 if (exporters.isNotEmpty) { |
| 259 internalError( | 287 internalError( |
| 260 "${exporters.first.exporter.uri} attempts to export the part $uri."); | 288 "${exporters.first.exporter.uri} attempts to export the part $uri."); |
| 261 } | 289 } |
| 262 } | 290 } |
| 263 | 291 |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 437 } | 465 } |
| 438 | 466 |
| 439 /// Called to register [procedure] as a factory whose types are collected in | 467 /// Called to register [procedure] as a factory whose types are collected in |
| 440 /// [factoryDeclaration]. Later, once the class has been built, we can | 468 /// [factoryDeclaration]. Later, once the class has been built, we can |
| 441 /// synthesize type variables on the factory matching the class'. | 469 /// synthesize type variables on the factory matching the class'. |
| 442 void addFactoryDeclaration( | 470 void addFactoryDeclaration( |
| 443 ProcedureBuilder procedure, DeclarationBuilder<T> factoryDeclaration) { | 471 ProcedureBuilder procedure, DeclarationBuilder<T> factoryDeclaration) { |
| 444 factoryDeclarations[procedure] = factoryDeclaration; | 472 factoryDeclarations[procedure] = factoryDeclaration; |
| 445 } | 473 } |
| 446 } | 474 } |
| OLD | NEW |