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

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

Issue 1096583002: Reifier hookup (Closed) Base URL: git@github.com:dart-lang/dart-dev-compiler.git@master
Patch Set: Address comments 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
« no previous file with comments | « lib/src/codegen/js_codegen.dart ('k') | test/codegen/expect/sunflower/sunflower.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/codegen/reify_coercions.dart
diff --git a/lib/src/codegen/reify_coercions.dart b/lib/src/codegen/reify_coercions.dart
index c8ad334dc0e3e63b0eb04cb7b841360f3cfaaccf..e9b54b06e60b68214eda30440a8f8998e0987c86 100644
--- a/lib/src/codegen/reify_coercions.dart
+++ b/lib/src/codegen/reify_coercions.dart
@@ -12,6 +12,7 @@ import 'package:source_span/source_span.dart' show SourceFile;
import 'package:dev_compiler/src/checker/rules.dart';
import 'package:dev_compiler/src/info.dart';
+import 'package:dev_compiler/src/options.dart' show CompilerOptions;
import 'package:dev_compiler/src/utils.dart' as utils;
import 'ast_builder.dart';
@@ -44,6 +45,14 @@ class _LocatedWrapper {
_LocatedWrapper(this.wrapper, this.loc);
}
+abstract class InstrumentedRuntime {
+ Expression wrap(Expression coercion, Expression e, Expression fromType,
+ Expression toType, Expression dartIs, String kind, String location);
+ Expression cast(Expression e, Expression fromType, Expression toType,
+ Expression dartIs, String kind, String location, bool ground);
+ Expression type(Expression witnessFunction);
+}
+
class _Inference extends DownwardsInference {
TypeManager _tm;
@@ -82,8 +91,10 @@ class _Inference extends DownwardsInference {
var id = cName.type.name;
var typeName = AstBuilder.typeName(id, tNames);
cName.type = typeName;
- var rawType = (e.staticType.element as ClassElement).type;
- e.staticType = rawType.substitute4(targs);
+ var newType =
+ (e.staticType.element as ClassElement).type.substitute4(targs);
+ e.staticType = newType;
+ typeName.type = newType;
}
@override
@@ -105,16 +116,22 @@ class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object>
bool _skipCoercions = false;
final TypeRules _rules;
final _Inference _inferrer;
+ final InstrumentedRuntime _runtime;
+ final CompilerOptions _options;
- CoercionReifier._(
- this._cm, this._tm, this._vm, this._library, this._rules, this._inferrer);
+ CoercionReifier._(this._cm, this._tm, this._vm, this._library, this._rules,
+ this._inferrer, this._runtime, this._options);
- factory CoercionReifier(LibraryUnit library, TypeRules rules) {
+ factory CoercionReifier(
+ LibraryUnit library, TypeRules rules, CompilerOptions options,
+ [InstrumentedRuntime runtime]) {
var vm = new VariableManager();
- var tm = new TypeManager(library.library.element.enclosingElement, vm);
- var cm = new CoercionManager(vm, tm, rules);
+ var tm =
+ new TypeManager(library.library.element.enclosingElement, vm, runtime);
+ var cm = new CoercionManager(vm, tm, rules, runtime);
var inferrer = new _Inference(rules, tm);
- return new CoercionReifier._(cm, tm, vm, library, rules, inferrer);
+ return new CoercionReifier._(
+ cm, tm, vm, library, rules, inferrer, runtime, options);
}
// This should be the entry point for this class. Entering via the
@@ -140,7 +157,7 @@ class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object>
final begin = e is AnnotatedNode
? (e as AnnotatedNode).firstTokenAfterCommentAndMetadata.offset
: e.offset;
- if (begin != 0) {
+ if (begin != 0 && e.end > begin) {
var span = _file.span(begin, e.end);
var s = span.message("Cast");
return s.substring(0, s.indexOf("Cast"));
@@ -163,6 +180,7 @@ class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object>
@override
Object visitAsExpression(AsExpression e) {
+ if (_runtime == null) return super.visitAsExpression(e);
var cast = Coercion.cast(_rules.getStaticType(e.expression), e.type.type);
var loc = _locationInfo(e);
Expression castNode =
@@ -188,7 +206,7 @@ class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object>
@override
Object visitDownCast(DownCast node) {
- if (_skipCoercions) {
+ if (_skipCoercions && !_options.allowConstCasts) {
_log.severe("Skipping runtime downcast in constant context");
return null;
}
@@ -205,7 +223,7 @@ class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object>
// TODO(leafp): Bind the coercions at the top level
@override
Object visitClosureWrapBase(ClosureWrapBase node) {
- if (_skipCoercions) {
+ if (_skipCoercions && !_options.allowConstCasts) {
_log.severe("Skipping coercion wrap in constant context");
return null;
}
@@ -241,7 +259,7 @@ class CoercionReifier extends analyzer.GeneralizingAstVisitor<Object>
}
Object visitCompilationUnit(CompilationUnit unit) {
- _cm.enterCompilationUnit();
+ _cm.enterCompilationUnit(unit);
Object ret = super.visitCompilationUnit(unit);
_cm.exitCompilationUnit(unit);
return ret;
@@ -264,14 +282,14 @@ class VariableManager {
// TODO(leafp): Hack, not for real.
int _id = 0;
- Identifier freshIdentifier(String hint) {
+ SimpleIdentifier freshIdentifier(String hint) {
String n = _id.toString();
_id++;
String s = "__$hint$n";
return AstBuilder.identifierFromString(s);
}
- Identifier freshTypeIdentifier(String hint) {
+ SimpleIdentifier freshTypeIdentifier(String hint) {
return freshIdentifier(hint);
}
}
@@ -292,6 +310,7 @@ class CoercionManager {
TypeManager _tm;
bool _hoistWrappers = false;
TypeRules _rules;
+ InstrumentedRuntime _runtime;
// A map containing all of the wrappers collected but not yet discharged
final Map<Identifier, _LocatedWrapper> _topWrappers =
@@ -300,14 +319,14 @@ class CoercionManager {
<Identifier, _LocatedWrapper>{};
Map<Identifier, _LocatedWrapper> _wrappers;
- CoercionManager(this._vm, this._tm, this._rules) {
+ CoercionManager(this._vm, this._tm, this._rules, [this._runtime]) {
_wrappers = _topWrappers;
}
// Call on entry to and exit from a compilation unit in order to properly
// discharge the accumulated wrappers.
- void enterCompilationUnit() {
- _tm.enterCompilationUnit();
+ void enterCompilationUnit(CompilationUnit unit) {
+ _tm.enterCompilationUnit(unit);
_wrappers = _topWrappers;
}
void exitCompilationUnit(CompilationUnit unit) {
@@ -358,6 +377,11 @@ class CoercionManager {
Expression _wrapExpression(Expression e, Wrapper w, String k, String loc) {
var q = _addWrapper(w, loc);
+ if (_runtime == null) {
+ var app = AstBuilder.application(q, <Expression>[e]);
+ app.staticType = w.toType;
+ return app;
+ }
var ttName = _tm.typeNameFromDartType(w.toType);
var tt = _tm.typeExpression(ttName);
var ft = _tm.typeExpressionFromDartType(w.fromType);
@@ -368,15 +392,18 @@ class CoercionManager {
var tup = _bindExpression("x", e);
var id = tup.e0;
var binder = tup.e1;
- var kind = AstBuilder.stringLiteral(k);
- var key = AstBuilder.multiLineStringLiteral(loc);
var dartIs = AstBuilder.isExpression(AstBuilder.parenthesize(id), ttName);
- var arguments = <Expression>[q, id, ft, tt, kind, key, dartIs];
- return binder(new RuntimeOperation("wrap", arguments));
+ var oper = _runtime.wrap(q, id, ft, tt, dartIs, k, loc);
+ return binder(oper);
}
Expression _castExpression(Expression e, Cast c, String k, String loc) {
var ttName = _tm.typeNameFromDartType(c.toType);
+ if (_runtime == null) {
+ var cast = AstBuilder.asExpression(e, ttName);
+ cast.staticType = c.toType;
+ return cast;
+ }
var tt = _tm.typeExpression(ttName);
var ft = _tm.typeExpressionFromDartType(c.fromType);
if (c.fromType.element == null) {
@@ -390,12 +417,10 @@ class CoercionManager {
var tup = _bindExpression("x", e);
var id = tup.e0;
var binder = tup.e1;
- var kind = AstBuilder.stringLiteral(k);
- var key = AstBuilder.multiLineStringLiteral(loc);
var dartIs = AstBuilder.isExpression(AstBuilder.parenthesize(id), ttName);
- var ground = AstBuilder.booleanLiteral(_rules.isGroundType(c.toType));
- var arguments = <Expression>[id, ft, tt, kind, key, dartIs, ground];
- return binder(new RuntimeOperation("cast", arguments));
+ var ground = _rules.isGroundType(c.toType);
+ var oper = _runtime.cast(id, ft, tt, dartIs, k, loc, ground);
+ return binder(oper);
}
Expression _coerceExpression(
@@ -554,14 +579,19 @@ class TypeManager {
final VariableManager _vm;
final LibraryElement _currentLibrary;
final Map<Identifier, NewTypeIdDesc> addedTypes = {};
+ final InstrumentedRuntime _runtime;
+ CompilationUnitElement _currentUnit;
/// 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 = {};
- TypeManager(this._currentLibrary, this._vm);
+ TypeManager(this._currentLibrary, this._vm, [this._runtime]);
+
+ void enterCompilationUnit(CompilationUnit unit) {
+ _currentUnit = unit.element;
+ }
- void enterCompilationUnit() {}
void exitCompilationUnit(CompilationUnit unit) {
unit.declarations.addAll(_typedefs.values);
_typedefs.clear();
@@ -631,20 +661,34 @@ class TypeManager {
var optionalParameters = type.optionalParameterTypes;
var params = new List<FormalParameter>();
for (int i = 0; i < normalParameters.length; i++) {
- FormalParameter fp = _anonymousFormal(normalParameters[i]);
- params.add(AstBuilder.requiredFormal(fp));
+ FormalParameter fp =
+ AstBuilder.requiredFormal(_anonymousFormal(normalParameters[i]));
+ _resolveFormal(fp, normalParameters[i]);
+ params.add(fp);
}
for (int i = 0; i < optionalParameters.length; i++) {
- FormalParameter fp = _anonymousFormal(optionalParameters[i]);
- params.add(AstBuilder.optionalFormal(fp));
+ FormalParameter fp =
+ AstBuilder.optionalFormal(_anonymousFormal(optionalParameters[i]));
+ _resolveFormal(fp, optionalParameters[i]);
+ params.add(fp);
}
for (String k in namedParameters.keys) {
- FormalParameter fp = _anonymousFormal(namedParameters[k]);
- params.add(AstBuilder.namedFormal(fp));
+ FormalParameter fp =
+ AstBuilder.namedFormal(_anonymousFormal(namedParameters[k]));
+ _resolveFormal(fp, namedParameters[k]);
+ params.add(fp);
}
return params;
}
+ void _resolveFormal(FormalParameter fp, DartType type) {
+ ParameterElementImpl fe = new ParameterElementImpl.forNode(fp.identifier);
+ fe.parameterKind = fp.kind;
+ fe.type = type;
+ fp.identifier.staticElement = fe;
+ fp.identifier.staticType = type;
+ }
+
FormalParameter _functionTypedFormal(Identifier v, FunctionType type) {
assert(v != null);
var params = _formalParameterListForFunctionType(type);
@@ -666,18 +710,18 @@ class TypeManager {
return AstBuilder.simpleFormal(v, t);
}
- Identifier freshTypeDefVariable() {
- var t = _vm.freshTypeIdentifier("t");
+ SimpleIdentifier freshTypeDefVariable(String hint) {
+ var t = _vm.freshTypeIdentifier(hint);
var desc = new NewTypeIdDesc(
fromCurrent: true, importedFrom: _currentLibrary, synthetic: true);
addedTypes[t] = desc;
return t;
}
- Identifier typeParameterFromString(String name) =>
+ SimpleIdentifier typeParameterFromString(String name) =>
AstBuilder.identifierFromString(name);
- Identifier freshReferenceToNamedType(DartType type) {
+ SimpleIdentifier freshReferenceToNamedType(DartType type) {
var name = type.name;
assert(name != null);
var id = AstBuilder.identifierFromString(name);
@@ -694,6 +738,68 @@ class TypeManager {
return id;
}
+ FunctionTypeAlias _newResolvedTypedef(
+ FunctionType type, List<TypeParameterType> ftvs) {
+
+ // The name of the typedef (unresolved at this point)
+ // TODO(leafp): better naming.
+ SimpleIdentifier t = freshTypeDefVariable("CastType");
+ // The element for the new typedef
+ var element = new FunctionTypeAliasElementImpl(t.name, 0);
+
+ // Fresh type parameter identifiers for the free type variables
+ List<Identifier> tNames =
+ ftvs.map((x) => typeParameterFromString(x.name)).toList();
+ // The type parameters themselves
+ List<TypeParameter> tps = tNames.map(AstBuilder.typeParameter).toList();
+ // Allocate the elements for the type parameters, fill in their
+ // type (which makes no sense) and link up the various elements
+ // For each type parameter identifier, make an element and a type
+ // with that element, link the two together, set the identifier element
+ // to that element, and the identifier type to that type.
+ List<TypeParameterElement> tElements = tNames.map((x) {
+ var element = new TypeParameterElementImpl(x.name, 0);
+ var type = new TypeParameterTypeImpl(element);
+ element.type = type;
+ x.staticElement = element;
+ x.staticType = type;
+ return element;
+ }).toList();
+ // Get the types out from the elements
+ List<TypeParameterType> tTypes = tElements.map((x) => x.type).toList();
+ // Take the return type from the original type, and replace the free
+ // type variables with the fresh type variables
+ element.returnType = type.returnType.substitute2(tTypes, ftvs);
+ // Set the type parameter elements
+ element.typeParameters = tElements;
+ // Set the parent element to the current compilation unit
+ element.enclosingElement = _currentUnit;
+
+ // This is the type corresponding to the typedef. Note that
+ // almost all methods on this type delegate to the element, so it
+ // cannot be safely be used for anything until the element is fully resolved
+ FunctionTypeImpl substType = new FunctionTypeImpl.con2(element);
+ element.type = substType;
+ // Link the type and the element into the identifier for the typedef
+ t.staticType = substType;
+ t.staticElement = element;
+
+ // Make the formal parameters for the typedef, using the original type
+ // with the fresh type variables substituted in.
+ List<FormalParameter> fps =
+ _formalParameterListForFunctionType(type.substitute2(tTypes, ftvs));
+ // Get the static elements out of the parameters, and use them to
+ // initialize the parameters in the element model
+ element.parameters = fps.map((x) => x.identifier.staticElement).toList();
+ // Build the return type syntax
+ TypeName ret = _typeNameFromDartType(substType.returnType);
+ // This should now be fully resolved (or at least enough so for things
+ // to work so far).
+ FunctionTypeAlias alias = AstBuilder.functionTypeAlias(ret, t, tps, fps);
+
+ return alias;
+ }
+
// 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.
@@ -705,26 +811,19 @@ class TypeManager {
if (tpl != null) {
var ltp = tpl.typeParameters;
ts = new List<TypeName>.from(
- ltp.map((t) => _mkNewTypeName(t.name, null)));
+ ltp.map((t) => _mkNewTypeName(null, t.name, null)));
}
var name = alias.name;
- return _mkNewTypeName(name, ts);
+ return _mkNewTypeName(type, name, ts);
}
List<TypeParameterType> ftvs = _freeTypeVariables(type);
- Identifier t = freshTypeDefVariable();
-
- Iterable<Identifier> tNames =
- ftvs.map((x) => typeParameterFromString(x.name));
- List<TypeParameter> tps = tNames.map(AstBuilder.typeParameter).toList();
- List<FormalParameter> fps = _formalParameterListForFunctionType(type);
- TypeName ret = _typeNameFromDartType(type.returnType);
- FunctionTypeAlias alias = AstBuilder.functionTypeAlias(ret, t, tps, fps);
-
+ FunctionTypeAlias alias = _newResolvedTypedef(type, ftvs);
_typedefs[type] = alias;
List<TypeName> args = ftvs.map(_typeNameFromDartType).toList();
- TypeName namedType = _mkNewTypeName(t, args);
+ TypeName namedType =
+ _mkNewTypeName(alias.name.staticType, alias.name, args);
return namedType;
}
@@ -735,8 +834,7 @@ class TypeManager {
if (dType is FunctionType) return _typeNameFromFunctionType(dType);
_log.severe("No name for type, casting through dynamic");
var d = AstBuilder.identifierFromString("dynamic");
- var t = _mkNewTypeName(d, null);
- t.type = dType;
+ var t = _mkNewTypeName(dType, d, null);
return t;
}
SimpleIdentifier id = freshReferenceToNamedType(dType);
@@ -745,22 +843,23 @@ class TypeManager {
List<DartType> targs = dType.typeArguments;
args = targs.map(_typeNameFromDartType).toList();
}
- var t = _mkNewTypeName(id, args);
- t.type = dType;
+ var t = _mkNewTypeName(dType, id, args);
return t;
}
- TypeName _mkNewTypeName(Identifier id, List<TypeName> args) {
+ TypeName _mkNewTypeName(DartType type, Identifier id, List<TypeName> args) {
var t = AstBuilder.typeName(id, args);
+ t.type = type;
return t;
}
Expression _typeExpression(TypeName t) {
+ assert(_runtime != null);
if (t.typeArguments != null && t.typeArguments.length > 0) {
var w = AstBuilder.identifierFromString("_");
var fp = AstBuilder.simpleFormal(w, t);
var f = AstBuilder.blockFunction(<FormalParameter>[fp], <Statement>[]);
- return new RuntimeOperation("type", <Expression>[f]);
+ return _runtime.type(f);
}
return t.name;
}
« no previous file with comments | « lib/src/codegen/js_codegen.dart ('k') | test/codegen/expect/sunflower/sunflower.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698