blob: 8240de74216fe90478169078fb7bb248809eb087 [file] [log] [blame]
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library fasta.kernel_class_builder;
import 'package:kernel/ast.dart' show
Class,
DartType,
ExpressionStatement,
InterfaceType,
Member,
StringLiteral,
Supertype,
Throw;
import '../errors.dart' show
internalError;
import 'kernel_builder.dart' show
Builder,
ClassBuilder,
ConstructorReferenceBuilder,
KernelProcedureBuilder,
KernelTypeBuilder,
LibraryBuilder,
MetadataBuilder,
ProcedureBuilder,
TypeVariableBuilder,
computeDefaultTypeArguments;
import 'redirecting_factory_body.dart' show
RedirectingFactoryBody;
abstract class KernelClassBuilder
extends ClassBuilder<KernelTypeBuilder, InterfaceType> {
KernelClassBuilder(
List<MetadataBuilder> metadata, int modifiers,
String name, List<TypeVariableBuilder> typeVariables,
KernelTypeBuilder supertype, List<KernelTypeBuilder> interfaces,
Map<String, Builder> members, List<KernelTypeBuilder> types,
LibraryBuilder parent)
: super(metadata, modifiers, name, typeVariables, supertype, interfaces,
members, types, parent);
Class get cls;
Class get target => cls;
/// [arguments] have already been built.
InterfaceType buildTypesWithBuiltArguments(List<DartType> arguments) {
return arguments == null
? cls.rawType
: new InterfaceType(cls,
// TODO(ahe): Not sure what to do if `arguments.length !=
// cls.typeParameters.length`.
computeDefaultTypeArguments(cls.typeParameters, arguments));
}
InterfaceType buildType(List<KernelTypeBuilder> arguments) {
List<DartType> typeArguments;
if (arguments != null) {
typeArguments = <DartType>[];
for (KernelTypeBuilder builder in arguments) {
DartType type = builder.build();
if (type == null) {
internalError("Bad type: ${builder.runtimeType}");
}
typeArguments.add(type);
}
}
return buildTypesWithBuiltArguments(typeArguments);
}
Supertype buildSupertype(List<KernelTypeBuilder> arguments) {
List<DartType> typeArguments;
if (arguments != null) {
typeArguments = <DartType>[];
for (KernelTypeBuilder builder in arguments) {
DartType type = builder.build();
if (type == null) {
internalError("Bad type: ${builder.runtimeType}");
}
typeArguments.add(type);
}
return new Supertype(cls, typeArguments);
} else {
return cls.asRawSupertype;
}
}
int resolveConstructors(LibraryBuilder library) {
int count = super.resolveConstructors(library);
if (count != 0) {
members.forEach((String name, Builder builder) {
if (builder is KernelProcedureBuilder && builder.isFactory) {
// Compute the immediate redirection target, not the effective.
ConstructorReferenceBuilder redirectionTarget =
builder.redirectionTarget;
if (redirectionTarget != null) {
assert(builder.actualBody == null);
Builder targetBuilder = redirectionTarget.target;
if (targetBuilder is ProcedureBuilder) {
Member target = targetBuilder.target;
builder.body = new RedirectingFactoryBody(target);
} else {
// TODO(ahe): Throw NSM error. This requires access to core
// types.
String message =
"Missing constructor: ${redirectionTarget.fullNameForErrors}";
print(message);
builder.body = new ExpressionStatement(
new Throw(new StringLiteral(message)));
}
}
}
});
}
return count;
}
}