Skip to content

Commit caff16a

Browse files
author
John Messerly
committed
merged
2 parents 1c0759a + 3e5d1d8 commit caff16a

File tree

9 files changed

+248
-34
lines changed

9 files changed

+248
-34
lines changed

pkg/dev_compiler/lib/runtime/dart_sdk.js

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,9 @@ dart_library.library('dart_sdk', null, /* Imports */[
946946
dart.throwStrongModeTypeError = function(object, actual, type) {
947947
dart.throw(new _js_helper.StrongModeTypeError(object, dart.typeName(actual), dart.typeName(type)));
948948
};
949+
dart.throwUnimplementedError = function(message) {
950+
dart.throw(new core.UnimplementedError(message));
951+
};
949952
dart.throwAssertionError = function() {
950953
dart.throw(new core.AssertionError());
951954
};
@@ -1564,6 +1567,9 @@ dart_library.library('dart_sdk', null, /* Imports */[
15641567
if (ft2 === core.Function) {
15651568
return true;
15661569
}
1570+
if (ft1 === core.Function) {
1571+
return false;
1572+
}
15671573
let ret1 = ft1.returnType;
15681574
let ret2 = ft2.returnType;
15691575
let args1 = ft1.args;
@@ -2251,7 +2257,25 @@ dart_library.library('dart_sdk', null, /* Imports */[
22512257
dart._typeFormalCount = Symbol("_typeFormalCount");
22522258
dart.isSubtype = dart._subtypeMemo((t1, t2) => t1 === t2 || dart._isSubtype(t1, t2, true));
22532259
dart.hasOwnProperty = Object.prototype.hasOwnProperty;
2254-
_debugger.skipDartConfig = dart.const(new core.Object());
2260+
_debugger.JsonMLConfig = class JsonMLConfig extends core.Object {
2261+
new(name) {
2262+
this.name = name;
2263+
}
2264+
};
2265+
dart.setSignature(_debugger.JsonMLConfig, {
2266+
constructors: () => ({new: dart.definiteFunctionType(_debugger.JsonMLConfig, [core.String])})
2267+
});
2268+
dart.defineLazy(_debugger.JsonMLConfig, {
2269+
get none() {
2270+
return dart.const(new _debugger.JsonMLConfig("none"));
2271+
},
2272+
get skipDart() {
2273+
return dart.const(new _debugger.JsonMLConfig("skipDart"));
2274+
},
2275+
get keyToString() {
2276+
return dart.const(new _debugger.JsonMLConfig("keyToString"));
2277+
}
2278+
});
22552279
_debugger.maxIterableChildrenToDisplay = 50;
22562280
dart.defineLazy(_debugger, {
22572281
get _devtoolsFormatter() {
@@ -2334,10 +2358,10 @@ dart_library.library('dart_sdk', null, /* Imports */[
23342358
new(opts) {
23352359
let name = opts && 'name' in opts ? opts.name : null;
23362360
let value = opts && 'value' in opts ? opts.value : null;
2337-
let skipDart = opts && 'skipDart' in opts ? opts.skipDart : null;
2361+
let config = opts && 'config' in opts ? opts.config : _debugger.JsonMLConfig.none;
23382362
this.name = name;
23392363
this.value = value;
2340-
this.skipDart = skipDart == true;
2364+
this.config = config;
23412365
}
23422366
['=='](other) {
23432367
return _debugger.NameValuePair.is(other) && other.name == this.name;
@@ -2347,7 +2371,7 @@ dart_library.library('dart_sdk', null, /* Imports */[
23472371
}
23482372
};
23492373
dart.setSignature(_debugger.NameValuePair, {
2350-
constructors: () => ({new: dart.definiteFunctionType(_debugger.NameValuePair, [], {name: core.String, value: core.Object, skipDart: core.bool})})
2374+
constructors: () => ({new: dart.definiteFunctionType(_debugger.NameValuePair, [], {name: core.String, value: core.Object, config: _debugger.JsonMLConfig})})
23512375
});
23522376
_debugger.MapEntry = class MapEntry extends core.Object {
23532377
new(opts) {
@@ -2358,7 +2382,7 @@ dart_library.library('dart_sdk', null, /* Imports */[
23582382
}
23592383
};
23602384
dart.setSignature(_debugger.MapEntry, {
2361-
constructors: () => ({new: dart.definiteFunctionType(_debugger.MapEntry, [], {key: core.String, value: core.Object})})
2385+
constructors: () => ({new: dart.definiteFunctionType(_debugger.MapEntry, [], {key: core.Object, value: core.Object})})
23622386
});
23632387
_debugger.ClassMetadata = class ClassMetadata extends core.Object {
23642388
new(object) {
@@ -2445,11 +2469,14 @@ dart_library.library('dart_sdk', null, /* Imports */[
24452469
this[_simpleFormatter] = simpleFormatter;
24462470
}
24472471
header(object, config) {
2448-
if (core.identical(config, _debugger.skipDartConfig) || dart.test(_debugger.isNativeJavaScriptObject(object))) {
2472+
if (dart.equals(config, _debugger.JsonMLConfig.skipDart) || dart.test(_debugger.isNativeJavaScriptObject(object))) {
24492473
return null;
24502474
}
24512475
let c = this[_simpleFormatter].preview(object);
24522476
if (c == null) return null;
2477+
if (dart.equals(config, _debugger.JsonMLConfig.keyToString)) {
2478+
c = dart.toString(object);
2479+
}
24532480
let element = new _debugger.JsonMLElement('span');
24542481
element.setStyle('background-color: #d9edf7');
24552482
element.createTextChild(c);
@@ -2471,9 +2498,7 @@ dart_library.library('dart_sdk', null, /* Imports */[
24712498
nameSpan.addStyle("padding-left: 13px;");
24722499
li.appendChild(nameSpan);
24732500
let objectTag = li.createObjectTag(child.value);
2474-
if (dart.test(child.skipDart)) {
2475-
objectTag.addAttribute('config', _debugger.skipDartConfig);
2476-
}
2501+
objectTag.addAttribute('config', child.config);
24772502
if (!dart.test(this[_simpleFormatter].hasChildren(child.value))) {
24782503
li.setStyle("padding-left: 13px;");
24792504
}
@@ -2650,7 +2675,7 @@ dart_library.library('dart_sdk', null, /* Imports */[
26502675
return core.String._check(dart.typeName(dart.getReifiedType(object)));
26512676
}
26522677
children(object) {
2653-
return JSArrayOfNameValuePair().of([new _debugger.NameValuePair({name: 'signature', value: this.preview(object)}), new _debugger.NameValuePair({name: 'JavaScript Function', value: object, skipDart: true})]);
2678+
return JSArrayOfNameValuePair().of([new _debugger.NameValuePair({name: 'signature', value: this.preview(object)}), new _debugger.NameValuePair({name: 'JavaScript Function', value: object, config: _debugger.JsonMLConfig.skipDart})]);
26542679
}
26552680
};
26562681
dart.setSignature(_debugger.FunctionFormatter, {
@@ -2676,7 +2701,7 @@ dart_library.library('dart_sdk', null, /* Imports */[
26762701
let map = core.Map._check(object);
26772702
let entries = LinkedHashSetOfNameValuePair().new();
26782703
map[dartx.forEach](dart.fn((key, value) => {
2679-
let entryWrapper = new _debugger.MapEntry({key: core.String._check(key), value: value});
2704+
let entryWrapper = new _debugger.MapEntry({key: key, value: value});
26802705
entries.add(new _debugger.NameValuePair({name: dart.toString(entries.length), value: entryWrapper}));
26812706
}, dynamicAnddynamicTovoid()));
26822707
this.addMetadataChildren(object, entries);
@@ -2744,9 +2769,9 @@ dart_library.library('dart_sdk', null, /* Imports */[
27442769
if (mixins != null && dart.test(dart.dload(mixins, 'isNotEmpty'))) {
27452770
ret[dartx.add](new _debugger.NameValuePair({name: '[[Mixins]]', value: new _debugger.HeritageClause('mixins', core.List._check(mixins))}));
27462771
}
2747-
ret[dartx.add](new _debugger.NameValuePair({name: '[[JavaScript View]]', value: entry.object, skipDart: true}));
2772+
ret[dartx.add](new _debugger.NameValuePair({name: '[[JavaScript View]]', value: entry.object, config: _debugger.JsonMLConfig.skipDart}));
27482773
if (!core.Type.is(entry.object)) {
2749-
ret[dartx.add](new _debugger.NameValuePair({name: '[[JavaScript Constructor]]', value: _debugger.JSNative.getProperty(entry.object, 'constructor'), skipDart: true}));
2774+
ret[dartx.add](new _debugger.NameValuePair({name: '[[JavaScript Constructor]]', value: _debugger.JSNative.getProperty(entry.object, 'constructor'), config: _debugger.JsonMLConfig.skipDart}));
27502775
}
27512776
return ret;
27522777
}
@@ -2773,7 +2798,7 @@ dart_library.library('dart_sdk', null, /* Imports */[
27732798
return true;
27742799
}
27752800
children(object) {
2776-
return JSArrayOfNameValuePair().of([new _debugger.NameValuePair({name: 'key', value: dart.dload(object, 'key')}), new _debugger.NameValuePair({name: 'value', value: dart.dload(object, 'value')})]);
2801+
return JSArrayOfNameValuePair().of([new _debugger.NameValuePair({name: 'key', value: dart.dload(object, 'key'), config: _debugger.JsonMLConfig.keyToString}), new _debugger.NameValuePair({name: 'value', value: dart.dload(object, 'value')})]);
27772802
}
27782803
};
27792804
_debugger.MapEntryFormatter[dart.implements] = () => [_debugger.Formatter];

pkg/dev_compiler/lib/src/analyzer/context.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,9 @@ AnalysisContext createAnalysisContextWithSources(AnalyzerOptions options,
142142
/// Creates an analysis context that contains our restricted typing rules.
143143
AnalysisContextImpl createAnalysisContext() {
144144
var res = AnalysisEngine.instance.createAnalysisContext();
145-
res.analysisOptions = new AnalysisOptionsImpl()..strongMode = true;
145+
res.analysisOptions = new AnalysisOptionsImpl()
146+
..strongMode = true
147+
..trackCacheDependencies = false;
146148
return res;
147149
}
148150

pkg/dev_compiler/lib/src/compiler/code_generator.dart

Lines changed: 147 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2716,18 +2716,32 @@ class CodeGenerator extends GeneralizingAstVisitor
27162716
return _emitSend(target, '[]=', [lhs.index, rhs]);
27172717
}
27182718

2719+
if (lhs is SimpleIdentifier) {
2720+
return _emitSetSimpleIdentifier(lhs, rhs);
2721+
}
2722+
27192723
Expression target = null;
27202724
SimpleIdentifier id;
27212725
if (lhs is PropertyAccess) {
27222726
if (lhs.operator.lexeme == '?.') {
27232727
return _emitNullSafeSet(lhs, rhs);
27242728
}
2725-
27262729
target = _getTarget(lhs);
27272730
id = lhs.propertyName;
27282731
} else if (lhs is PrefixedIdentifier) {
2732+
if (isLibraryPrefix(lhs.prefix)) {
2733+
return _emitSet(lhs.identifier, rhs);
2734+
}
27292735
target = lhs.prefix;
27302736
id = lhs.identifier;
2737+
} else {
2738+
assert(false);
2739+
}
2740+
2741+
assert(target != null);
2742+
2743+
if (target is SuperExpression) {
2744+
return _emitSetSuper(lhs, target, id, rhs);
27312745
}
27322746

27332747
if (target != null && isDynamicInvoke(target)) {
@@ -2744,6 +2758,138 @@ class CodeGenerator extends GeneralizingAstVisitor
27442758
[_visit(target), _emitMemberName(id.name), _visit(rhs)]);
27452759
}
27462760

2761+
var accessor = id.staticElement;
2762+
var element =
2763+
accessor is PropertyAccessorElement ? accessor.variable : accessor;
2764+
2765+
if (element is ClassMemberElement && element is! ConstructorElement) {
2766+
bool isStatic = element.isStatic;
2767+
if (isStatic) {
2768+
if (element is FieldElement) {
2769+
return _emitSetStaticProperty(lhs, element, rhs);
2770+
}
2771+
return _badAssignment('Unknown static: $element', lhs, rhs);
2772+
}
2773+
if (element is FieldElement) {
2774+
return _emitWriteInstanceProperty(
2775+
lhs, _visit(target), element, _visit(rhs));
2776+
}
2777+
}
2778+
2779+
return _badAssignment('Unhandled assignment', lhs, rhs);
2780+
}
2781+
2782+
JS.Expression _badAssignment(String problem, Expression lhs, Expression rhs) {
2783+
// TODO(sra): We should get here only for compiler bugs or weirdness due to
2784+
// --unsafe-force-compile. Once those paths have been addressed, throw at
2785+
// compile time.
2786+
return js.call('dart.throwUnimplementedError((#, #, #))',
2787+
[js.string('$lhs ='), _visit(rhs), js.string(problem)]);
2788+
}
2789+
2790+
/// Emits assignment to a simple identifier. Handles all legal simple
2791+
/// identifier assignment targets (local, top level library member, implicit
2792+
/// `this` or class, etc.)
2793+
JS.Expression _emitSetSimpleIdentifier(
2794+
SimpleIdentifier node, Expression rhs) {
2795+
JS.Expression unimplemented() {
2796+
return _badAssignment("Unimplemented: unknown name '$node'", node, rhs);
2797+
}
2798+
2799+
var accessor = node.staticElement;
2800+
if (accessor == null) return unimplemented();
2801+
2802+
// Get the original declaring element. If we had a property accessor, this
2803+
// indirects back to a (possibly synthetic) field.
2804+
var element = accessor;
2805+
if (accessor is PropertyAccessorElement) element = accessor.variable;
2806+
2807+
_declareBeforeUse(element);
2808+
2809+
if (element is LocalVariableElement || element is ParameterElement) {
2810+
return _emitSetLocal(node, element, rhs);
2811+
}
2812+
2813+
if (element.enclosingElement is CompilationUnitElement) {
2814+
// Top level library member.
2815+
return _emitSetTopLevel(node, element, rhs);
2816+
}
2817+
2818+
// Unqualified class member. This could mean implicit `this`, or implicit
2819+
// static from the same class.
2820+
if (element is ClassMemberElement) {
2821+
bool isStatic = element.isStatic;
2822+
if (isStatic) {
2823+
if (element is FieldElement) {
2824+
return _emitSetStaticProperty(node, element, rhs);
2825+
}
2826+
return unimplemented();
2827+
}
2828+
2829+
// For instance members, we add implicit-this.
2830+
if (element is FieldElement) {
2831+
return _emitWriteInstanceProperty(
2832+
node, new JS.This(), element, _visit(rhs));
2833+
}
2834+
return unimplemented();
2835+
}
2836+
2837+
// We should not get here.
2838+
return unimplemented();
2839+
}
2840+
2841+
/// Emits assignment to a simple local variable or parameter.
2842+
JS.Expression _emitSetLocal(
2843+
SimpleIdentifier node, Element element, Expression rhs) {
2844+
JS.Expression target;
2845+
if (element is TemporaryVariableElement) {
2846+
// If this is one of our compiler's temporary variables, use its JS form.
2847+
target = element.jsVariable;
2848+
} else if (element is ParameterElement) {
2849+
target = _emitParameter(element);
2850+
} else {
2851+
target = new JS.Identifier(element.name);
2852+
}
2853+
2854+
return _visit(rhs).toAssignExpression(annotate(target, node));
2855+
}
2856+
2857+
/// Emits assignment to library scope element [element].
2858+
JS.Expression _emitSetTopLevel(
2859+
Expression lhs, Element element, Expression rhs) {
2860+
return _visit(rhs)
2861+
.toAssignExpression(annotate(_emitTopLevelName(element), lhs));
2862+
}
2863+
2864+
/// Emits assignment to a static field element or property.
2865+
JS.Expression _emitSetStaticProperty(
2866+
Expression lhs, Element element, Expression rhs) {
2867+
// For static methods, we add the raw type name, without generics or
2868+
// library prefix. We don't need those because static calls can't use
2869+
// the generic type.
2870+
ClassElement classElement = element.enclosingElement;
2871+
var type = classElement.type;
2872+
var dynType = _emitType(fillDynamicTypeArgs(type));
2873+
var member = _emitMemberName(element.name, isStatic: true, type: type);
2874+
return _visit(rhs).toAssignExpression(
2875+
annotate(new JS.PropertyAccess(dynType, member), lhs));
2876+
}
2877+
2878+
/// Emits an assignment to the [element] property of instance referenced by
2879+
/// [jsTarget].
2880+
JS.Expression _emitWriteInstanceProperty(Expression lhs,
2881+
JS.Expression jsTarget, Element element, JS.Expression value) {
2882+
String memberName = element.name;
2883+
var type = (element.enclosingElement as ClassElement).type;
2884+
var name = _emitMemberName(memberName, type: type);
2885+
return value.toAssignExpression(
2886+
annotate(new JS.PropertyAccess(jsTarget, name), lhs));
2887+
}
2888+
2889+
JS.Expression _emitSetSuper(Expression lhs, SuperExpression target,
2890+
SimpleIdentifier id, Expression rhs) {
2891+
// TODO(sra): Determine whether and access helper is required for the
2892+
// setter. For now fall back on the r-value path.
27472893
return _visit(rhs).toAssignExpression(_visit(lhs));
27482894
}
27492895

pkg/dev_compiler/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ author: Dart Dev Compiler team <[email protected]>
88
homepage: https://github.com/dart-lang/dev_compiler
99

1010
dependencies:
11-
analyzer: ^0.27.4-alpha.7
11+
analyzer: ^0.27.4-alpha.11
1212
args: ^0.13.0
1313
bazel_worker: ^0.1.0
1414
cli_util: ^0.0.1
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import "package:expect/expect.dart";
2+
3+
// regression test for ddc #588
4+
5+
typedef int Int2Int(int x);
6+
7+
void foo(List<Int2Int> list) {
8+
list.forEach((f) => print(f(42)));
9+
}
10+
11+
void main() {
12+
var l = <Function>[];
13+
Expect.throws(() => foo(l), (e) => e is TypeError);
14+
}

pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/errors.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ throwStrongModeTypeError(object, actual, type) => JS('', '''(() => {
2727
$typeName($type)));
2828
})()''');
2929

30+
throwUnimplementedError(message) => JS('', '''(() => {
31+
$throw_(new $UnimplementedError($message));
32+
})()''');
33+
3034
throwAssertionError() => JS('', '''(() => {
3135
$throw_(new $AssertionError());
3236
})()''');

pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,10 @@ isFunctionSubtype(ft1, ft2, covariant) => JS('', '''(() => {
496496
return true;
497497
}
498498
499+
if ($ft1 === $Function) {
500+
return false;
501+
}
502+
499503
let ret1 = $ft1.returnType;
500504
let ret2 = $ft2.returnType;
501505

0 commit comments

Comments
 (0)