| // 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 kernel.transformations.reify.runtime.declarations; |
| |
| import 'types.dart' show FunctionType, Interface, ReifiedType, TypeVariable; |
| |
| typedef String Id2String(Object id); |
| |
| /// Represents a class. |
| /// |
| /// There's one instance of this class for each class in the program. |
| /// |
| /// Note: not all classes can be represented as a compile-time constants. For |
| /// example, most core classes, such as, `String`, `int`, and `double` |
| /// implement `Comparable` in a way that cannot be expressed as a constant. |
| class Class { |
| final id; |
| |
| Interface supertype; |
| |
| FunctionType callableType; |
| |
| final List<TypeVariable> variables; |
| |
| List<Interface> interfaces; |
| |
| static Id2String debugId2String; |
| |
| Class(this.id, this.supertype, |
| {this.callableType, |
| this.variables: const <TypeVariable>[], |
| this.interfaces /* set in init */}); |
| |
| Interface get thisType { |
| return new Interface(this, variables); |
| } |
| |
| String get name => debugId2String == null ? "$id" : debugId2String(id); |
| |
| String toString() { |
| StringBuffer sb = new StringBuffer(); |
| sb.write("class $name"); |
| if (variables.isNotEmpty) { |
| sb.write("<"); |
| bool first = true; |
| for (TypeVariable tv in variables) { |
| if (!first) { |
| sb.write(", "); |
| } |
| sb.write(tv); |
| sb.write(" extends "); |
| sb.write(tv.bound); |
| } |
| sb.write(">"); |
| } |
| if (supertype != null) { |
| sb.write(" extends $supertype"); |
| } |
| if (interfaces.isNotEmpty) { |
| sb.write(" implements "); |
| sb.writeAll(interfaces, ", "); |
| } |
| return "$sb"; |
| } |
| } |
| |
| /// Allocates a (non-growable) list of [amount] class declarations with ids `0` |
| /// to `amount - 1`. This function is called from the generated code that |
| /// initializes the type information. |
| List<Class> allocateDeclarations(List<String> names, List<int> typeParameters) { |
| List<TypeVariable> allocateVariables(int amount) { |
| if (amount == 0) return const <TypeVariable>[]; |
| return new List<TypeVariable>.generate( |
| amount, (int i) => new TypeVariable(i), |
| growable: false); |
| } |
| |
| return new List<Class>.generate( |
| names.length, |
| (int i) => new Class(names[i], null, |
| variables: allocateVariables(typeParameters[i])), |
| growable: false); |
| } |
| |
| /// Initializes the supertype and interfaces of `classes[index]`. |
| /// This function is called from generated code. |
| void init(List<Class> classes, int index, ReifiedType supertype, |
| [List<Interface> interfaces = const <Interface>[], |
| FunctionType callableType]) { |
| Class declaration = classes[index]; |
| assert(supertype == null); |
| declaration.supertype = supertype; |
| assert(interfaces == null); |
| declaration.interfaces = interfaces; |
| declaration.callableType = callableType; |
| } |