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.kernel_library_builder; |
| 6 |
| 7 import 'package:kernel/ast.dart'; |
| 8 |
| 9 import 'package:kernel/clone.dart' show |
| 10 CloneVisitor; |
| 11 |
| 12 import '../errors.dart' show |
| 13 internalError; |
| 14 |
| 15 import '../loader.dart' show |
| 16 Loader; |
| 17 |
| 18 import '../modifier.dart' show |
| 19 staticMask; |
| 20 |
| 21 import '../source/source_library_builder.dart' show |
| 22 SourceLibraryBuilder; |
| 23 |
| 24 import '../source/source_class_builder.dart' show |
| 25 SourceClassBuilder; |
| 26 |
| 27 import 'kernel_builder.dart' show |
| 28 Builder, |
| 29 ClassBuilder, |
| 30 ConstructorReferenceBuilder, |
| 31 DynamicTypeBuilder, |
| 32 EnumBuilder, |
| 33 FieldBuilder, |
| 34 FormalParameterBuilder, |
| 35 FunctionTypeAliasBuilder, |
| 36 KernelEnumBuilder, |
| 37 KernelFieldBuilder, |
| 38 KernelFormalParameterBuilder, |
| 39 KernelFunctionTypeAliasBuilder, |
| 40 KernelInterfaceTypeBuilder, |
| 41 KernelInvalidTypeBuilder, |
| 42 KernelMixinApplicationBuilder, |
| 43 KernelNamedMixinApplicationBuilder, |
| 44 KernelProcedureBuilder, |
| 45 KernelTypeBuilder, |
| 46 KernelTypeVariableBuilder, |
| 47 MemberBuilder, |
| 48 MetadataBuilder, |
| 49 MixedAccessor, |
| 50 NamedMixinApplicationBuilder, |
| 51 PrefixBuilder, |
| 52 ProcedureBuilder, |
| 53 TypeVariableBuilder; |
| 54 |
| 55 class KernelLibraryBuilder |
| 56 extends SourceLibraryBuilder<KernelTypeBuilder, Library> { |
| 57 final Library library; |
| 58 |
| 59 final List<Class> mixinApplicationClasses = <Class>[]; |
| 60 |
| 61 final List<List> argumentsWithMissingDefaultValues = <List>[]; |
| 62 |
| 63 KernelLibraryBuilder(Uri uri, Loader loader) |
| 64 : library = new Library(uri), |
| 65 super(loader); |
| 66 |
| 67 Uri get uri => library.importUri; |
| 68 |
| 69 KernelTypeBuilder addInterfaceType(String name, |
| 70 List<KernelTypeBuilder> arguments) { |
| 71 KernelInterfaceTypeBuilder type = |
| 72 new KernelInterfaceTypeBuilder(name, arguments); |
| 73 if (identical(name, "dynamic")) { |
| 74 // TODO(ahe): Make const. |
| 75 type.builder = new DynamicTypeBuilder(const DynamicType()); |
| 76 } else { |
| 77 addType(type); |
| 78 } |
| 79 return type; |
| 80 } |
| 81 |
| 82 KernelTypeBuilder addMixinApplication(KernelTypeBuilder supertype, |
| 83 List<KernelTypeBuilder> mixins) { |
| 84 KernelTypeBuilder type = |
| 85 new KernelMixinApplicationBuilder(supertype, mixins); |
| 86 return addType(type); |
| 87 } |
| 88 |
| 89 KernelTypeBuilder addVoidType() { |
| 90 return new KernelInterfaceTypeBuilder("void", null); |
| 91 } |
| 92 |
| 93 ClassBuilder addClass(List<MetadataBuilder> metadata, |
| 94 int modifiers, String className, |
| 95 List<TypeVariableBuilder> typeVariables, KernelTypeBuilder supertype, |
| 96 List<KernelTypeBuilder> interfaces) { |
| 97 ClassBuilder cls = new SourceClassBuilder(metadata, modifiers, className, |
| 98 typeVariables, supertype, interfaces, classMembers, classTypes, this, |
| 99 new List<ConstructorReferenceBuilder>.from(constructorReferences)); |
| 100 constructorReferences.clear(); |
| 101 classMembers.forEach((String name, MemberBuilder builder) { |
| 102 while (builder != null) { |
| 103 builder.parent = cls; |
| 104 builder = builder.next; |
| 105 } |
| 106 }); |
| 107 // Nested scope began in `OutlineBuilder.beginClassDeclaration`. |
| 108 endNestedScope(); |
| 109 return addBuilder(className, cls); |
| 110 } |
| 111 |
| 112 NamedMixinApplicationBuilder addNamedMixinApplication( |
| 113 List<MetadataBuilder> metadata, String name, |
| 114 List<TypeVariableBuilder> typeVariables, int modifiers, |
| 115 KernelTypeBuilder mixinApplication, List<KernelTypeBuilder> interfaces) { |
| 116 NamedMixinApplicationBuilder builder = |
| 117 new KernelNamedMixinApplicationBuilder(metadata, name, typeVariables, |
| 118 modifiers, mixinApplication, interfaces, classTypes, this); |
| 119 // Nested scope began in `OutlineBuilder.beginNamedMixinApplication`. |
| 120 endNestedScope(); |
| 121 return addBuilder(name, builder); |
| 122 } |
| 123 |
| 124 FieldBuilder addField(List<MetadataBuilder> metadata, |
| 125 int modifiers, KernelTypeBuilder type, String name) { |
| 126 return addBuilder(name, |
| 127 new KernelFieldBuilder(metadata, type, name, modifiers)); |
| 128 } |
| 129 |
| 130 ProcedureBuilder addProcedure(List<MetadataBuilder> metadata, |
| 131 int modifiers, KernelTypeBuilder returnType, String name, |
| 132 List<TypeVariableBuilder> typeVariables, |
| 133 List<FormalParameterBuilder> formals, AsyncMarker asyncModifier, |
| 134 ProcedureKind kind) { |
| 135 return addBuilder(name, |
| 136 new KernelProcedureBuilder(metadata, modifiers, returnType, name, |
| 137 typeVariables, formals, asyncModifier, kind)); |
| 138 } |
| 139 |
| 140 void addFactoryMethod(List<MetadataBuilder> metadata, |
| 141 ConstructorReferenceBuilder constructorName, |
| 142 List<FormalParameterBuilder> formals, AsyncMarker asyncModifier, |
| 143 ConstructorReferenceBuilder redirectionTarget) { |
| 144 String name = constructorName.name; |
| 145 assert(constructorName.suffix == null); |
| 146 addBuilder(name, |
| 147 new KernelProcedureBuilder(metadata, staticMask, null, name, null, |
| 148 formals, asyncModifier, ProcedureKind.Factory, redirectionTarget)); |
| 149 } |
| 150 |
| 151 EnumBuilder addEnum(List<MetadataBuilder> metadata, String name, |
| 152 List<String> constants) { |
| 153 return addBuilder(name, |
| 154 new KernelEnumBuilder(metadata, name, constants, this)); |
| 155 } |
| 156 |
| 157 FunctionTypeAliasBuilder addFunctionTypeAlias(List<MetadataBuilder> metadata, |
| 158 KernelTypeBuilder returnType, String name, |
| 159 List<TypeVariableBuilder> typeVariables, |
| 160 List<FormalParameterBuilder> formals) { |
| 161 FunctionTypeAliasBuilder typedef = new KernelFunctionTypeAliasBuilder( |
| 162 metadata, returnType, name, typeVariables, formals, classTypes, this); |
| 163 // Nested scope began in `OutlineBuilder.beginFunctionTypeAlias`. |
| 164 endNestedScope(); |
| 165 return addBuilder(name, typedef); |
| 166 } |
| 167 |
| 168 KernelFormalParameterBuilder addFormalParameter( |
| 169 List<MetadataBuilder> metadata, int modifiers, |
| 170 KernelTypeBuilder type, String name, bool hasThis) { |
| 171 return new KernelFormalParameterBuilder( |
| 172 metadata, modifiers, type, name, hasThis); |
| 173 } |
| 174 |
| 175 KernelTypeVariableBuilder addTypeVariable(String name, |
| 176 KernelTypeBuilder bound) { |
| 177 return new KernelTypeVariableBuilder(name, bound); |
| 178 } |
| 179 |
| 180 void buildBuilder(Builder builder) { |
| 181 if (builder is SourceClassBuilder) { |
| 182 Class cls = builder.build(this); |
| 183 library.addClass(cls); |
| 184 Class superclass = cls.superclass; |
| 185 if (superclass != null && superclass.isMixinApplication) { |
| 186 List<Class> mixinApplications = <Class>[]; |
| 187 mixinApplicationClasses.add(cls); |
| 188 while (superclass != null && superclass.isMixinApplication) { |
| 189 if (superclass.parent == null) { |
| 190 mixinApplications.add(superclass); |
| 191 } |
| 192 superclass = superclass.superclass; |
| 193 } |
| 194 for (Class cls in mixinApplications.reversed) { |
| 195 // TODO(ahe): Should be able to move this into the above loop as long |
| 196 // as we don't care about matching dartk perfectly. |
| 197 library.addClass(cls); |
| 198 mixinApplicationClasses.add(cls); |
| 199 } |
| 200 } |
| 201 } else if (builder is KernelFieldBuilder) { |
| 202 library.addMember(builder.build(library)..isStatic = true); |
| 203 } else if (builder is KernelProcedureBuilder) { |
| 204 library.addMember(builder.build(library)..isStatic = true); |
| 205 } else if (builder is FunctionTypeAliasBuilder) { |
| 206 // Kernel discard typedefs and use their corresponding function types |
| 207 // directly. |
| 208 } else if (builder is KernelEnumBuilder) { |
| 209 library.addClass(builder.build(this)); |
| 210 } else if (builder is PrefixBuilder) { |
| 211 // Ignored. Kernel doesn't represent prefixes. |
| 212 } else { |
| 213 internalError("Unhandled builder: ${builder.runtimeType}"); |
| 214 } |
| 215 } |
| 216 |
| 217 Library build() { |
| 218 super.build(); |
| 219 library.name = name; |
| 220 // TODO(ahe): Set fileUri. |
| 221 // library.fileUri = "${fileUri ?? uri}"; |
| 222 return library; |
| 223 } |
| 224 |
| 225 Builder buildAmbiguousBuilder( |
| 226 String name, Builder builder, Builder other) { |
| 227 if (builder.next == null && other.next == null) { |
| 228 if (builder.isGetter && other.isSetter) { |
| 229 return new MixedAccessor(builder, other); |
| 230 } else if (builder.isSetter && other.isGetter) { |
| 231 return new MixedAccessor(other, builder); |
| 232 } |
| 233 } |
| 234 return new KernelInvalidTypeBuilder(name, this); |
| 235 } |
| 236 |
| 237 void addArgumentsWithMissingDefaultValues(Arguments arguments, |
| 238 FunctionNode function) { |
| 239 assert(partOfLibrary == null); |
| 240 argumentsWithMissingDefaultValues.add([arguments, function]); |
| 241 } |
| 242 |
| 243 int finishStaticInvocations() { |
| 244 CloneVisitor cloner; |
| 245 for (var list in argumentsWithMissingDefaultValues) { |
| 246 final Arguments arguments = list[0]; |
| 247 final FunctionNode function = list[1]; |
| 248 |
| 249 Expression defaultArgumentFrom(Expression expression) { |
| 250 if (expression == null) { |
| 251 return new NullLiteral(); |
| 252 } |
| 253 cloner ??= new CloneVisitor(); |
| 254 return cloner.clone(expression); |
| 255 } |
| 256 |
| 257 for (int i = function.requiredParameterCount; |
| 258 i < function.positionalParameters.length; |
| 259 i++) { |
| 260 arguments.positional[i] ??= |
| 261 defaultArgumentFrom(function.positionalParameters[i].initializer) |
| 262 ..parent = arguments; |
| 263 } |
| 264 Map<String, VariableDeclaration> names; |
| 265 for (NamedExpression expression in arguments.named) { |
| 266 if (expression.value == null) { |
| 267 if (names == null) { |
| 268 names = <String, VariableDeclaration>{}; |
| 269 for (VariableDeclaration parameter in function.namedParameters) { |
| 270 names[parameter.name] = parameter; |
| 271 } |
| 272 } |
| 273 expression.value = |
| 274 defaultArgumentFrom(names[expression.name].initializer) |
| 275 ..parent = expression; |
| 276 } |
| 277 } |
| 278 } |
| 279 return argumentsWithMissingDefaultValues.length; |
| 280 } |
| 281 } |
OLD | NEW |