Skip to content

Commit 120c8c3

Browse files
committed
[kernel] Erase function type parameters to fake strong mode on the VM.
The VM does not support function type parameters at the moment, but we can erase them at the last minute, to enable testing of other parts of strong mode. This also disables error checking in the SDK since the VM's patch files are not in strong mode. BUG= [email protected] Review URL: https://chromereviews.googleplex.com/518647013 .
1 parent b56d061 commit 120c8c3

File tree

5 files changed

+111
-18
lines changed

5 files changed

+111
-18
lines changed

pkg/kernel/lib/analyzer/loader.dart

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -535,20 +535,17 @@ class DartLoader implements ReferenceLevelLoader {
535535
var element = context.computeLibraryElement(source);
536536
context.resolveCompilationUnit(source, element);
537537
_buildLibraryBody(element, node);
538-
for (var unit in element.units) {
539-
LineInfo lines;
540-
for (var error in context.computeErrors(unit.source)) {
541-
if (error.errorCode is CompileTimeErrorCode ||
542-
error.errorCode is ParserErrorCode ||
543-
error.errorCode is ScannerErrorCode ||
544-
error.errorCode is StrongModeCode) {
545-
if (error.errorCode == ParserErrorCode.CONST_FACTORY &&
546-
node.importUri.scheme == 'dart') {
547-
// Ignore warnings about 'const' factories in the patched SDK.
548-
continue;
538+
if (node.importUri.scheme != 'dart') {
539+
for (var unit in element.units) {
540+
LineInfo lines;
541+
for (var error in context.computeErrors(unit.source)) {
542+
if (error.errorCode is CompileTimeErrorCode ||
543+
error.errorCode is ParserErrorCode ||
544+
error.errorCode is ScannerErrorCode ||
545+
error.errorCode is StrongModeCode) {
546+
lines ??= context.computeLineInfo(source);
547+
errors.add(formatErrorMessage(error, source.shortName, lines));
549548
}
550-
lines ??= context.computeLineInfo(source);
551-
errors.add(formatErrorMessage(error, source.shortName, lines));
552549
}
553550
}
554551
}
@@ -689,8 +686,8 @@ AnalysisOptions createAnalysisOptions(bool strongMode) {
689686
return new AnalysisOptionsImpl()
690687
..strongMode = strongMode
691688
..enableGenericMethods = strongMode
692-
..generateImplicitErrors = true
693-
..generateSdkErrors = true
689+
..generateImplicitErrors = false
690+
..generateSdkErrors = false
694691
..preserveComments = false
695692
..hint = false
696693
..enableSuperMixins = true;

pkg/kernel/lib/ast.dart

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1254,7 +1254,11 @@ class VariableGet extends Expression {
12541254
promotedType?.accept(v);
12551255
}
12561256

1257-
transformChildren(Transformer v) {}
1257+
transformChildren(Transformer v) {
1258+
if (promotedType != null) {
1259+
promotedType = v.visitDartType(promotedType);
1260+
}
1261+
}
12581262
}
12591263

12601264
/// Assign a local variable or function parameter.
@@ -1952,6 +1956,7 @@ class ConditionalExpression extends Expression {
19521956
condition?.accept(v);
19531957
then?.accept(v);
19541958
otherwise?.accept(v);
1959+
staticType?.accept(v);
19551960
}
19561961

19571962
transformChildren(Transformer v) {
@@ -1967,6 +1972,9 @@ class ConditionalExpression extends Expression {
19671972
otherwise = otherwise.accept(v);
19681973
otherwise?.parent = this;
19691974
}
1975+
if (staticType != null) {
1976+
staticType = v.visitDartType(staticType);
1977+
}
19701978
}
19711979
}
19721980

pkg/kernel/lib/target/flutter.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
// BSD-style license that can be found in the LICENSE file.
44
library kernel.target.flutter;
55

6-
import 'targets.dart';
76
import '../ast.dart';
8-
import '../transformations/mixin_full_resolution.dart' as mix;
97
import '../transformations/continuation.dart' as cont;
8+
import '../transformations/erasure.dart';
9+
import '../transformations/mixin_full_resolution.dart' as mix;
1010
import '../transformations/setup_builtin_library.dart' as setup_builtin_library;
11+
import 'targets.dart';
1112

1213
class FlutterTarget extends Target {
1314
final TargetFlags flags;
@@ -54,5 +55,9 @@ class FlutterTarget extends Target {
5455
// Repair `_getMainClosure()` function in dart:{_builtin,ui} libraries.
5556
setup_builtin_library.transformProgram(program);
5657
setup_builtin_library.transformProgram(program, libraryUri: 'dart:ui');
58+
59+
if (strongMode) {
60+
new Erasure().transform(program);
61+
}
5762
}
5863
}

pkg/kernel/lib/target/vm.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'targets.dart';
77
import '../ast.dart';
88
import '../transformations/mixin_full_resolution.dart' as mix;
99
import '../transformations/continuation.dart' as cont;
10+
import '../transformations/erasure.dart';
1011
import '../transformations/setup_builtin_library.dart' as setup_builtin_library;
1112

1213
/// Specializes the kernel IR to the Dart VM.
@@ -49,5 +50,9 @@ class VmTarget extends Target {
4950

5051
// Repair `_getMainClosure()` function in dart:_builtin.
5152
setup_builtin_library.transformProgram(program);
53+
54+
if (strongMode) {
55+
new Erasure().transform(program);
56+
}
5257
}
5358
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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+
library kernel.transformations.erasure;
5+
6+
import '../ast.dart';
7+
import '../type_algebra.dart';
8+
9+
/// Erases all function type parameter lists and replaces all uses of them with
10+
/// their upper bounds.
11+
///
12+
/// This is a temporary measure to run strong mode code in the VM, which does
13+
/// not yet support function type parameters.
14+
///
15+
/// This does not preserve dynamic type safety.
16+
class Erasure extends Transformer {
17+
final Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{};
18+
19+
void transform(Program program) {
20+
program.accept(this);
21+
}
22+
23+
@override
24+
visitDartType(DartType type) => substitute(type, substitution);
25+
26+
@override
27+
visitProcedure(Procedure node) {
28+
if (node.kind == ProcedureKind.Factory) {
29+
assert(node.enclosingClass != null);
30+
assert(node.enclosingClass.typeParameters.length ==
31+
node.function.typeParameters.length);
32+
// Factories can have function type parameters as long as they correspond
33+
// exactly to those on the enclosing class.
34+
// Skip the visitFunctionNode but traverse body for local functions.
35+
node.function.transformChildren(this);
36+
} else {
37+
node.transformChildren(this);
38+
}
39+
return node;
40+
}
41+
42+
@override
43+
visitFunctionNode(FunctionNode node) {
44+
for (var parameter in node.typeParameters) {
45+
substitution[parameter] = const DynamicType();
46+
}
47+
for (var parameter in node.typeParameters) {
48+
substitution[parameter] = substitute(parameter.bound, substitution);
49+
}
50+
node.transformChildren(this);
51+
node.typeParameters.forEach(substitution.remove);
52+
node.typeParameters.clear();
53+
return node;
54+
}
55+
56+
@override
57+
visitStaticInvocation(StaticInvocation node) {
58+
if (node.target.kind != ProcedureKind.Factory) {
59+
node.arguments.types.clear();
60+
}
61+
node.transformChildren(this);
62+
return node;
63+
}
64+
65+
@override
66+
visitMethodInvocation(MethodInvocation node) {
67+
node.arguments.types.clear();
68+
node.transformChildren(this);
69+
return node;
70+
}
71+
72+
@override
73+
visitDirectMethodInvocation(DirectMethodInvocation node) {
74+
node.arguments.types.clear();
75+
node.transformChildren(this);
76+
return node;
77+
}
78+
}

0 commit comments

Comments
 (0)