Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1246)

Unified Diff: lib/src/codegen/reify_coercions.dart

Issue 1070453002: Refactor reifier to make it less dart_codegen specific. (Closed) Base URL: git@github.com:dart-lang/dart-dev-compiler.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: lib/src/codegen/reify_coercions.dart
diff --git a/lib/src/codegen/reify_coercions.dart b/lib/src/codegen/reify_coercions.dart
index d3b3725b051970dcb556851030137793a54564e9..dae898e44c7b9bf58b74fbb3617165daa67f9bbe 100644
--- a/lib/src/codegen/reify_coercions.dart
+++ b/lib/src/codegen/reify_coercions.dart
@@ -27,6 +27,17 @@ class Tuple2<T0, T1> {
typedef T Function1<S, T>(S _);
+class NewTypeIdDesc {
+ // If null, then this is not a library level identifier (i.e. it's
Jennifer Messerly 2015/04/08 20:28:16 nit: triple slash for doc comment style: /// If n
+ // a type parameter, or a special type like void, dynamic, etc)
+ LibraryElement importedFrom;
+ // True => use/def in same library
vsm 2015/04/08 15:31:02 Does class this describe one specific use? If not
+ bool fromCurrent;
+ // True => not a source variable
+ bool synthetic;
+ NewTypeIdDesc({this.fromCurrent, this.importedFrom, this.synthetic});
+}
+
class _LocatedWrapper {
final String loc;
final Wrapper wrapper;
@@ -84,17 +95,20 @@ class _Inference extends DownwardsInference {
// This class implements a pass which modifies (in place) the ast replacing
// abstract coercion nodes with their dart implementations.
-class UnitCoercionReifier extends analyzer.GeneralizingAstVisitor<Object>
+class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object>
with ConversionVisitor<Object> {
CoercionManager _cm;
- final TypeManager _tm;
- final VariableManager _vm;
+ TypeManager _tm;
+ VariableManager _vm;
+ LibraryUnit _library;
SourceFile _file;
bool _skipCoercions = false;
final TypeRules _rules;
_Inference _inferrer;
- UnitCoercionReifier(this._tm, this._vm, this._rules) {
+ CoercionReifier(this._library, this._rules) {
+ _vm = new VariableManager();
Jennifer Messerly 2015/04/08 20:28:16 if you want to keep final fields, it could be done
+ _tm = new TypeManager(_library.library.element.enclosingElement, _vm);
_cm = new CoercionManager(_vm, _tm, _rules);
_inferrer = new _Inference(_rules, _tm);
}
@@ -102,10 +116,19 @@ class UnitCoercionReifier extends analyzer.GeneralizingAstVisitor<Object>
// This should be the entry point for this class. Entering via the
// visit functions directly may not do the right thing with respect
// to discharging the collected definitions.
- void reify(CompilationUnit unit) {
+ // Returns the set of new type identifiers added by the reifier
+ Map<Identifier, NewTypeIdDesc> reify() {
+ for (var unit in _library.partsThenLibrary) {
Jennifer Messerly 2015/04/08 20:28:16 _library.partsThenLibrary.forEach(generateUnit); ?
+ generateUnit(unit);
+ }
+ return _tm.addedTypes;
+ }
+
+ void generateUnit(CompilationUnit unit) {
_file = new SourceFile(unit.element.source.contents.data,
url: unit.element.source.uri);
visitCompilationUnit(unit);
+ _file = null;
}
///////////////// Private //////////////////////////////////
@@ -526,15 +549,17 @@ class CoercionManager {
// Note that in order to hoist the typedefs out of parameterized classes
// we must close over any type variables.
class TypeManager {
- VariableManager _vm;
- Set<TypeName> _newTypes = new Set<TypeName>();
+ final VariableManager _vm;
+ final LibraryElement _currentLibrary;
+ final Map<Identifier, NewTypeIdDesc> addedTypes =
vsm 2015/04/08 15:31:02 Omit the type on the left?
+ new Map<Identifier, NewTypeIdDesc>();
/// A map containing new function typedefs to be introduced at the top level
/// This uses LinkedHashMap to emit code in a consistent order.
final Map<FunctionType, FunctionTypeAlias> _typedefs =
new Map<FunctionType, FunctionTypeAlias>();
- TypeManager(this._vm);
+ TypeManager(this._currentLibrary, this._vm);
void enterCompilationUnit() {}
void exitCompilationUnit(CompilationUnit unit) {
@@ -555,8 +580,6 @@ class TypeManager {
Expression typeExpression(TypeName t) => _typeExpression(t);
- Set<TypeName> get addedTypes => _newTypes;
-
///////////////// Private //////////////////////////////////
List<TypeParameterType> _freeTypeVariables(DartType type) {
var s = new Set<TypeParameterType>();
@@ -650,6 +673,34 @@ class TypeManager {
return AstBuilder.simpleFormal(v, t);
}
+ Identifier freshTypeDefVariable() {
+ var t = _vm.freshTypeIdentifier("t");
+ var desc = new NewTypeIdDesc(
+ fromCurrent: true, importedFrom: _currentLibrary, synthetic: true);
+ addedTypes[t] = desc;
+ return t;
+ }
+
+ Identifier typeParameterFromString(String name) =>
+ AstBuilder.identifierFromString(name);
+
+ Identifier freshReferenceToNamedType(DartType type) {
+ var name = type.name;
+ assert(name != null);
+ var id = AstBuilder.identifierFromString(name);
+ var element = type.element;
+ id.staticElement = element;
+ var library = null;
+ // This can happen for types like (e.g.) void
+ if (element != null) library = element.library;
+ var desc = new NewTypeIdDesc(
+ fromCurrent: _currentLibrary == library,
+ importedFrom: library,
+ synthetic: false);
+ addedTypes[id] = desc;
+ return id;
+ }
+
// I think we can avoid alpha-varying type parameters, since
// the binding forms are so limited, so we just re-use the
// the original names for the formals and the actuals.
@@ -668,10 +719,10 @@ class TypeManager {
}
List<TypeParameterType> ftvs = _freeTypeVariables(type);
- Identifier t = _vm.freshTypeIdentifier("t");
+ Identifier t = freshTypeDefVariable();
Iterable<Identifier> tNames =
- ftvs.map((x) => AstBuilder.identifierFromString(x.name));
+ ftvs.map((x) => typeParameterFromString(x.name));
List<TypeParameter> tps = tNames.map(AstBuilder.typeParameter).toList();
List<FormalParameter> fps = _formalParameterListForFunctionType(type);
TypeName ret = _typeNameFromDartType(type.returnType);
@@ -686,22 +737,16 @@ class TypeManager {
}
TypeName _typeNameFromDartType(DartType dType) {
- // TODO(leafp) This doesn't re-use the name when the function type
- // is derived from a typedef, since I've moved it above the check
- // for a name. I think there's a bug in the resolver here: I
- // sometimes see function types named not with a typedef name,
- // but rather with the name of the function that they classify.
- if (dType is FunctionType) return _typeNameFromFunctionType(dType);
String name = dType.name;
if (name == null || name == "" || dType.isBottom) {
+ if (dType is FunctionType) return _typeNameFromFunctionType(dType);
Leaf 2015/04/07 22:29:58 This is the only thing that changes the output cod
_log.severe("No name for type, casting through dynamic");
var d = AstBuilder.identifierFromString("dynamic");
var t = _mkNewTypeName(d, null);
t.type = dType;
return t;
}
- SimpleIdentifier id = AstBuilder.identifierFromString(name);
- id.staticElement = dType.element;
+ SimpleIdentifier id = freshReferenceToNamedType(dType);
List<TypeName> args = null;
if (dType is ParameterizedType) {
List<DartType> targs = dType.typeArguments;
@@ -714,7 +759,6 @@ class TypeManager {
TypeName _mkNewTypeName(Identifier id, List<TypeName> args) {
var t = AstBuilder.typeName(id, args);
- _newTypes.add(t);
return t;
}

Powered by Google App Engine
This is Rietveld 408576698