Chromium Code Reviews| 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 endNestedScope(); | |
|
Johnni Winther
2017/01/18 12:42:40
Add a comment of where the nested scope begins, i.
ahe
2017/01/18 15:21:50
Done.
| |
| 108 return addBuilder(className, cls); | |
| 109 } | |
| 110 | |
| 111 NamedMixinApplicationBuilder addNamedMixinApplication( | |
| 112 List<MetadataBuilder> metadata, String name, | |
| 113 List<TypeVariableBuilder> typeVariables, int modifiers, | |
| 114 KernelTypeBuilder mixinApplication, List<KernelTypeBuilder> interfaces) { | |
| 115 NamedMixinApplicationBuilder builder = | |
| 116 new KernelNamedMixinApplicationBuilder(metadata, name, typeVariables, | |
| 117 modifiers, mixinApplication, interfaces, classTypes, this); | |
| 118 endNestedScope(); | |
| 119 return addBuilder(name, builder); | |
| 120 } | |
| 121 | |
| 122 FieldBuilder addField(List<MetadataBuilder> metadata, | |
| 123 int modifiers, KernelTypeBuilder type, String name) { | |
| 124 return addBuilder(name, | |
| 125 new KernelFieldBuilder(metadata, type, name, modifiers)); | |
| 126 } | |
| 127 | |
| 128 ProcedureBuilder addProcedure(List<MetadataBuilder> metadata, | |
| 129 int modifiers, KernelTypeBuilder returnType, String name, | |
| 130 List<TypeVariableBuilder> typeVariables, | |
| 131 List<FormalParameterBuilder> formals, AsyncMarker asyncModifier, | |
| 132 ProcedureKind kind) { | |
| 133 return addBuilder(name, | |
| 134 new KernelProcedureBuilder(metadata, modifiers, returnType, name, | |
| 135 typeVariables, formals, asyncModifier, kind)); | |
| 136 } | |
| 137 | |
| 138 void addFactoryMethod(List<MetadataBuilder> metadata, | |
| 139 ConstructorReferenceBuilder constructorName, | |
| 140 List<FormalParameterBuilder> formals, AsyncMarker asyncModifier, | |
| 141 ConstructorReferenceBuilder redirectionTarget) { | |
| 142 String name = constructorName.name; | |
| 143 assert(constructorName.suffix == null); | |
| 144 addBuilder(name, | |
| 145 new KernelProcedureBuilder(metadata, staticMask, null, name, null, | |
| 146 formals, asyncModifier, ProcedureKind.Factory, redirectionTarget)); | |
| 147 } | |
| 148 | |
| 149 EnumBuilder addEnum(List<MetadataBuilder> metadata, String name, | |
| 150 List<String> constants) { | |
| 151 return addBuilder(name, | |
| 152 new KernelEnumBuilder(metadata, name, constants, this)); | |
| 153 } | |
| 154 | |
| 155 FunctionTypeAliasBuilder addFunctionTypeAlias(List<MetadataBuilder> metadata, | |
| 156 KernelTypeBuilder returnType, String name, | |
| 157 List<TypeVariableBuilder> typeVariables, | |
| 158 List<FormalParameterBuilder> formals) { | |
| 159 FunctionTypeAliasBuilder typedef = new KernelFunctionTypeAliasBuilder( | |
| 160 metadata, returnType, name, typeVariables, formals, classTypes, this); | |
| 161 endNestedScope(); | |
| 162 return addBuilder(name, typedef); | |
| 163 } | |
| 164 | |
| 165 KernelFormalParameterBuilder addFormalParameter( | |
| 166 List<MetadataBuilder> metadata, int modifiers, | |
| 167 KernelTypeBuilder type, String name, bool hasThis) { | |
| 168 return new KernelFormalParameterBuilder( | |
| 169 metadata, modifiers, type, name, hasThis); | |
| 170 } | |
| 171 | |
| 172 KernelTypeVariableBuilder addTypeVariable(String name, | |
| 173 KernelTypeBuilder bound) { | |
| 174 return new KernelTypeVariableBuilder(name, bound); | |
| 175 } | |
| 176 | |
| 177 void buildBuilder(Builder builder) { | |
| 178 if (builder is SourceClassBuilder) { | |
| 179 Class cls = builder.build(this); | |
| 180 library.addClass(cls); | |
| 181 Class superclass = cls.superclass; | |
| 182 if (superclass != null && superclass.isMixinApplication) { | |
| 183 List<Class> mixinApplications = <Class>[]; | |
| 184 mixinApplicationClasses.add(cls); | |
| 185 while (superclass != null && superclass.isMixinApplication) { | |
| 186 if (superclass.parent == null) { | |
| 187 mixinApplications.add(superclass); | |
| 188 } | |
| 189 superclass = superclass.superclass; | |
| 190 } | |
| 191 for (Class cls in mixinApplications.reversed) { | |
| 192 // TODO(ahe): Should be able to move this into the above loop as long | |
| 193 // as we don't care about matching dartk perfectly. | |
| 194 library.addClass(cls); | |
| 195 mixinApplicationClasses.add(cls); | |
| 196 } | |
| 197 } | |
| 198 } else if (builder is KernelFieldBuilder) { | |
| 199 library.addMember(builder.build(library)); | |
|
Johnni Winther
2017/01/18 12:42:40
Shouldn't this be tagged as static?
ahe
2017/01/18 15:21:50
Done.
| |
| 200 } else if (builder is KernelProcedureBuilder) { | |
| 201 library.addMember(builder.build(library)..isStatic = true); | |
|
Johnni Winther
2017/01/18 12:42:40
Shouldn't `isStatic = true` be given to the Kernel
ahe
2017/01/18 15:21:50
Not sure. Perhaps `isTopLevel = true`. Kernel mark
| |
| 202 } else if (builder is FunctionTypeAliasBuilder) { | |
| 203 // Kernel discard typedefs and use their corresponding function types | |
| 204 // directly. | |
| 205 } else if (builder is KernelEnumBuilder) { | |
| 206 library.addClass(builder.build(this)); | |
| 207 } else if (builder is PrefixBuilder) { | |
| 208 // Ignored. Kernel doesn't represent prefixes. | |
| 209 } else { | |
| 210 internalError("Unhandled builder: ${builder.runtimeType}"); | |
| 211 } | |
| 212 } | |
| 213 | |
| 214 Library build() { | |
| 215 super.build(); | |
| 216 library.name = name; | |
| 217 // TODO(ahe): Set fileUri. | |
| 218 // library.fileUri = "${fileUri ?? uri}"; | |
| 219 return library; | |
| 220 } | |
| 221 | |
| 222 Builder buildAmbiguousBuilder( | |
| 223 String name, Builder builder, Builder other) { | |
| 224 if (builder.next == null && other.next == null) { | |
| 225 if (builder.isGetter && other.isSetter) { | |
| 226 return new MixedAccessor(builder, other); | |
| 227 } else if (builder.isSetter && other.isGetter) { | |
| 228 return new MixedAccessor(other, builder); | |
| 229 } | |
| 230 } | |
| 231 return new KernelInvalidTypeBuilder(name, this); | |
| 232 } | |
| 233 | |
| 234 void addArgumentsWithMissingDefaultValues(Arguments arguments, | |
| 235 FunctionNode function) { | |
| 236 assert(partOfLibrary == null); | |
| 237 argumentsWithMissingDefaultValues.add([arguments, function]); | |
| 238 } | |
| 239 | |
| 240 int finishStaticInvocations() { | |
| 241 CloneVisitor cloner; | |
| 242 for (var list in argumentsWithMissingDefaultValues) { | |
| 243 final Arguments arguments = list[0]; | |
| 244 final FunctionNode function = list[1]; | |
| 245 | |
| 246 Expression defaultArgumentFrom(Expression expression) { | |
| 247 if (expression == null) { | |
| 248 return new NullLiteral(); | |
| 249 } | |
| 250 cloner ??= new CloneVisitor(); | |
| 251 return cloner.clone(expression); | |
| 252 } | |
| 253 | |
| 254 for (int i = function.requiredParameterCount; i < function.positionalParam eters.length; i++) { | |
|
Johnni Winther
2017/01/18 12:42:40
Long lines.
ahe
2017/01/18 15:21:50
Done.
| |
| 255 arguments.positional[i] ??= defaultArgumentFrom(function.positionalParam eters[i].initializer) | |
| 256 ..parent = arguments; | |
| 257 } | |
| 258 Map<String, VariableDeclaration> names; | |
| 259 for (NamedExpression expression in arguments.named) { | |
| 260 if (expression.value == null) { | |
| 261 if (names == null) { | |
| 262 names = <String, VariableDeclaration>{}; | |
| 263 for (VariableDeclaration parameter in function.namedParameters) { | |
| 264 names[parameter.name] = parameter; | |
| 265 } | |
| 266 } | |
| 267 expression.value = | |
| 268 defaultArgumentFrom(names[expression.name].initializer) | |
| 269 ..parent = expression; | |
| 270 } | |
| 271 } | |
| 272 } | |
| 273 return argumentsWithMissingDefaultValues.length; | |
| 274 } | |
| 275 } | |
| OLD | NEW |