| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library fasta.source_library_builder; |
| 6 |
| 7 import 'package:kernel/ast.dart' show |
| 8 AsyncMarker, |
| 9 ProcedureKind; |
| 10 |
| 11 import '../combinator.dart' show |
| 12 Combinator; |
| 13 |
| 14 import '../errors.dart' show |
| 15 inputError, |
| 16 internalError; |
| 17 |
| 18 import '../import.dart' show |
| 19 Import; |
| 20 |
| 21 import 'source_loader.dart' show |
| 22 SourceLoader; |
| 23 |
| 24 import '../builder/scope.dart' show |
| 25 Scope; |
| 26 |
| 27 import '../builder/builder.dart' show |
| 28 Builder, |
| 29 ClassBuilder, |
| 30 ConstructorReferenceBuilder, |
| 31 EnumBuilder, |
| 32 FieldBuilder, |
| 33 FormalParameterBuilder, |
| 34 FunctionTypeAliasBuilder, |
| 35 LibraryBuilder, |
| 36 MemberBuilder, |
| 37 MetadataBuilder, |
| 38 NamedMixinApplicationBuilder, |
| 39 PrefixBuilder, |
| 40 ProcedureBuilder, |
| 41 TypeBuilder, |
| 42 TypeDeclarationBuilder, |
| 43 TypeVariableBuilder, |
| 44 Unhandled; |
| 45 |
| 46 abstract class SourceLibraryBuilder<T extends TypeBuilder, R> |
| 47 extends LibraryBuilder<T, R> { |
| 48 final SourceLoader loader; |
| 49 |
| 50 final Map<String, Builder> members = <String, Builder>{}; |
| 51 |
| 52 final List<T> types = <T>[]; |
| 53 |
| 54 final List<ConstructorReferenceBuilder> constructorReferences = |
| 55 <ConstructorReferenceBuilder>[]; |
| 56 |
| 57 final List<LibraryBuilder> parts = <LibraryBuilder>[]; |
| 58 |
| 59 final List<Import> imports = <Import>[]; |
| 60 |
| 61 final Map<String, Builder> exports = <String, Builder>{}; |
| 62 |
| 63 final Scope scope = new Scope(<String, Builder>{}, null, isModifiable: false); |
| 64 |
| 65 String name; |
| 66 |
| 67 String partOf; |
| 68 |
| 69 Uri fileUri; |
| 70 |
| 71 List<MetadataBuilder> metadata; |
| 72 |
| 73 Map<String, MemberBuilder> classMembers; |
| 74 |
| 75 // TODO(ahe): Rename this. It's not just for classes. |
| 76 List<T> classTypes; |
| 77 |
| 78 SourceLibraryBuilder(this.loader); |
| 79 |
| 80 Uri get uri; |
| 81 |
| 82 bool get isPart => partOf != null; |
| 83 |
| 84 T addInterfaceType(String name, List<T> arguments); |
| 85 |
| 86 T addMixinApplication(T supertype, List<T> mixins); |
| 87 |
| 88 T addType(T type) { |
| 89 List<T> types = classTypes ?? this.types; |
| 90 types.add(type); |
| 91 return type; |
| 92 } |
| 93 |
| 94 T addVoidType(); |
| 95 |
| 96 ConstructorReferenceBuilder addConstructorReference( |
| 97 String name, List<T> typeArguments, String suffix) { |
| 98 ConstructorReferenceBuilder ref = |
| 99 new ConstructorReferenceBuilder(name, typeArguments, suffix); |
| 100 constructorReferences.add(ref); |
| 101 return ref; |
| 102 } |
| 103 |
| 104 void beginNestedScope() { |
| 105 classMembers = <String, MemberBuilder>{}; |
| 106 classTypes = <T>[]; |
| 107 } |
| 108 |
| 109 void endNestedScope() { |
| 110 classMembers = null; |
| 111 classTypes = null; |
| 112 } |
| 113 |
| 114 Uri resolve(String path) => uri.resolve(path); |
| 115 |
| 116 void addExport(List<MetadataBuilder> metadata, String uri, |
| 117 Unhandled conditionalUris, List<Combinator> combinators) { |
| 118 loader.read(resolve(uri)).addExporter(this, combinators); |
| 119 } |
| 120 |
| 121 void addImport(List<MetadataBuilder> metadata, String uri, |
| 122 Unhandled conditionalUris, String prefix, List<Combinator> combinators, |
| 123 bool deferred) { |
| 124 imports.add(new Import(loader.read(resolve(uri)), prefix, combinators)); |
| 125 } |
| 126 |
| 127 void addPart(List<MetadataBuilder> metadata, String uri) { |
| 128 parts.add(loader.read(resolve(uri))); |
| 129 } |
| 130 |
| 131 void addPartOf(List<MetadataBuilder> metadata, String name) { |
| 132 partOf = name; |
| 133 } |
| 134 |
| 135 ClassBuilder addClass(List<MetadataBuilder> metadata, |
| 136 int modifiers, String name, |
| 137 List<TypeVariableBuilder> typeVariables, T supertype, |
| 138 List<T> interfaces); |
| 139 |
| 140 NamedMixinApplicationBuilder addNamedMixinApplication( |
| 141 List<MetadataBuilder> metadata, String name, |
| 142 List<TypeVariableBuilder> typeVariables, int modifiers, |
| 143 T mixinApplication, List<T> interfaces); |
| 144 |
| 145 FieldBuilder addField(List<MetadataBuilder> metadata, |
| 146 int modifiers, T type, String name); |
| 147 |
| 148 void addFields(List<MetadataBuilder> metadata, int modifiers, |
| 149 T type, List<String> names) { |
| 150 for (String name in names) { |
| 151 addField(metadata, modifiers, type, name); |
| 152 } |
| 153 } |
| 154 |
| 155 ProcedureBuilder addProcedure(List<MetadataBuilder> metadata, |
| 156 int modifiers, T returnType, String name, |
| 157 List<TypeVariableBuilder> typeVariables, |
| 158 List<FormalParameterBuilder> formals, AsyncMarker asyncModifier, |
| 159 ProcedureKind kind); |
| 160 |
| 161 EnumBuilder addEnum(List<MetadataBuilder> metadata, String name, |
| 162 List<String> constants); |
| 163 |
| 164 FunctionTypeAliasBuilder addFunctionTypeAlias(List<MetadataBuilder> metadata, |
| 165 T returnType, String name, |
| 166 List<TypeVariableBuilder> typeVariables, |
| 167 List<FormalParameterBuilder> formals); |
| 168 |
| 169 void addFactoryMethod(List<MetadataBuilder> metadata, |
| 170 ConstructorReferenceBuilder name, List<FormalParameterBuilder> formals, |
| 171 AsyncMarker asyncModifier, ConstructorReferenceBuilder redirectionTarget); |
| 172 |
| 173 FormalParameterBuilder addFormalParameter( |
| 174 List<MetadataBuilder> metadata, int modifiers, |
| 175 T type, String name, bool hasThis); |
| 176 |
| 177 TypeVariableBuilder addTypeVariable(String name, T bound); |
| 178 |
| 179 Builder addBuilder(String name, Builder builder) { |
| 180 // TODO(ahe): Set the parent correctly here. Could then change the |
| 181 // implementation of MemberBuilder.isTopLevel to test explicitly for a |
| 182 // LibraryBuilder. |
| 183 if (classMembers == null) { |
| 184 if (builder is MemberBuilder) { |
| 185 builder.parent = this; |
| 186 } else if (builder is TypeDeclarationBuilder) { |
| 187 builder.parent = this; |
| 188 } else if (builder is PrefixBuilder) { |
| 189 assert(builder.parent == this); |
| 190 } else { |
| 191 return internalError("Unhandled: ${builder.runtimeType}"); |
| 192 } |
| 193 } |
| 194 Map<String, Builder> members = classMembers ?? this.members; |
| 195 Builder existing = members[name]; |
| 196 builder.next = existing; |
| 197 if (builder is PrefixBuilder && existing is PrefixBuilder) { |
| 198 assert(existing.next == null); |
| 199 builder.exports.forEach((String name, Builder builder) { |
| 200 Builder other = existing.exports.putIfAbsent(name, () => builder); |
| 201 if (other != builder) { |
| 202 existing.exports[name] = |
| 203 other.combineAmbiguousImport(name, builder, this); |
| 204 } |
| 205 }); |
| 206 return existing; |
| 207 } else if (existing != null && (existing.next != null || |
| 208 ((!existing.isGetter || !builder.isSetter) && |
| 209 (!existing.isSetter || !builder.isGetter)))) { |
| 210 return inputError(uri, -1, "Duplicated definition of $name"); |
| 211 } |
| 212 return members[name] = builder; |
| 213 } |
| 214 |
| 215 void buildBuilder(Builder builder); |
| 216 |
| 217 R build() { |
| 218 members.forEach((String name, Builder builder) { |
| 219 do { |
| 220 buildBuilder(builder); |
| 221 builder = builder.next; |
| 222 } while (builder != null); |
| 223 }); |
| 224 return null; |
| 225 } |
| 226 |
| 227 void validatePart() { |
| 228 if (parts.isNotEmpty) { |
| 229 internalError("Part with parts: $uri"); |
| 230 } |
| 231 if (exporters.isNotEmpty) { |
| 232 internalError( |
| 233 "${exporters.first.exporter.uri} attempts to export the part $uri."); |
| 234 } |
| 235 } |
| 236 |
| 237 void includeParts() { |
| 238 for (LibraryBuilder part in parts.toList()) { |
| 239 includePart(part); |
| 240 } |
| 241 } |
| 242 |
| 243 void includePart(SourceLibraryBuilder part) { |
| 244 if (name != null) { |
| 245 if (part.partOf == null) { |
| 246 print("${part.uri} has no 'part of' declaration but is used as a part " |
| 247 "by ${name} ($uri)"); |
| 248 parts.remove(part); |
| 249 return; |
| 250 } |
| 251 if (part.partOf != name) { |
| 252 print("${part.uri} is part of '${part.partOf}' but is used as a part " |
| 253 "by '${name}' ($uri)"); |
| 254 parts.remove(part); |
| 255 return; |
| 256 } |
| 257 } |
| 258 part.members.forEach(addBuilder); |
| 259 types.addAll(part.types); |
| 260 constructorReferences.addAll(part.constructorReferences); |
| 261 part.partOfLibrary = this; |
| 262 // TODO(ahe): Include metadata from part? |
| 263 } |
| 264 |
| 265 void buildInitialScopes() { |
| 266 members.forEach(addToExportScope); |
| 267 members.forEach(addToScope); |
| 268 } |
| 269 |
| 270 void addImportsToScope() { |
| 271 bool explicitCoreImport = this == loader.coreLibrary; |
| 272 for (Import import in imports) { |
| 273 if (import.imported == loader.coreLibrary) { |
| 274 explicitCoreImport = true; |
| 275 } |
| 276 import.finalizeImports(this); |
| 277 } |
| 278 if (!explicitCoreImport) { |
| 279 loader.coreLibrary.exports.forEach(addToScope); |
| 280 } |
| 281 } |
| 282 |
| 283 void addToScope(String name, Builder member) { |
| 284 Builder existing = scope.lookup(name); |
| 285 if (existing != null) { |
| 286 if (existing != member) { |
| 287 scope.local[name] = existing.combineAmbiguousImport(name, member, this); |
| 288 } |
| 289 // TODO(ahe): handle duplicated names. |
| 290 } else { |
| 291 scope.local[name] = member; |
| 292 } |
| 293 } |
| 294 |
| 295 bool addToExportScope(String name, Builder member) { |
| 296 if (name.startsWith("_")) return false; |
| 297 if (member is PrefixBuilder) return false; |
| 298 Builder existing = exports[name]; |
| 299 if (existing != null) { |
| 300 // TODO(ahe): handle duplicated names. |
| 301 return false; |
| 302 } else { |
| 303 exports[name] = member; |
| 304 } |
| 305 return true; |
| 306 } |
| 307 |
| 308 int resolveTypes(_) { |
| 309 int typeCount = types.length; |
| 310 for (T t in types) { |
| 311 t.resolveIn(scope); |
| 312 } |
| 313 members.forEach((String name, Builder member) { |
| 314 typeCount += member.resolveTypes(this); |
| 315 }); |
| 316 return typeCount; |
| 317 } |
| 318 |
| 319 int convertConstructors(_) { |
| 320 int count = 0; |
| 321 members.forEach((String name, Builder member) { |
| 322 count += member.convertConstructors(this); |
| 323 }); |
| 324 return count; |
| 325 } |
| 326 |
| 327 int resolveConstructors(_) { |
| 328 int count = 0; |
| 329 members.forEach((String name, Builder member) { |
| 330 count += member.resolveConstructors(this); |
| 331 }); |
| 332 return count; |
| 333 } |
| 334 } |
| OLD | NEW |