Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 47b5fb7

Browse files
committed
fix(parser): Do not use isInterface. Works around dartbug 9434
1 parent 5becb45 commit 47b5fb7

File tree

2 files changed

+69
-24
lines changed

2 files changed

+69
-24
lines changed

lib/parser.dart

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -144,29 +144,35 @@ getterChild(value, childKey) {
144144
}
145145
}
146146

147-
if (isInterface(value, Getter) && value.containsKey(childKey)) {
148-
return [true, value[childKey]];
149-
} else {
150-
InstanceMirror instanceMirror = reflect(value);
151-
Symbol curSym = new Symbol(childKey);
152-
try {
153-
// maybe it is a member field?
154-
return [true, instanceMirror.getField(curSym).reflectee];
155-
} catch (e) {
156-
// maybe it is a member method?
157-
if (instanceMirror.type.members.containsKey(curSym)) {
158-
MethodMirror methodMirror = instanceMirror.type.members[curSym];
159-
return [true, _relaxFnArgs((args) {
160-
if (args == null) args = [];
161-
try {
162-
return instanceMirror.invoke(curSym, args).reflectee;
163-
} catch (e) {
164-
throw "$e \n\n${e.stacktrace}";
165-
}
166-
})];
167-
}
168-
return [false, null];
147+
// TODO: replace with isInterface(value, Getter) when dart:mirrors
148+
// can support mixins.
149+
try {
150+
// containsKey() might not return a boolean, so explicitly test
151+
// against true.
152+
if (value.containsKey(childKey) == true) {
153+
return [true, value[childKey]];
169154
}
155+
} on NoSuchMethodError catch(e) {}
156+
157+
InstanceMirror instanceMirror = reflect(value);
158+
Symbol curSym = new Symbol(childKey);
159+
try {
160+
// maybe it is a member field?
161+
return [true, instanceMirror.getField(curSym).reflectee];
162+
} catch (e) {
163+
// maybe it is a member method?
164+
if (instanceMirror.type.members.containsKey(curSym)) {
165+
MethodMirror methodMirror = instanceMirror.type.members[curSym];
166+
return [true, _relaxFnArgs((args) {
167+
if (args == null) args = [];
168+
try {
169+
return instanceMirror.invoke(curSym, args).reflectee;
170+
} catch (e) {
171+
throw "$e \n\n${e.stacktrace}";
172+
}
173+
})];
174+
}
175+
return [false, null];
170176
}
171177
}
172178

@@ -195,10 +201,13 @@ getter(scope, locals, path) {
195201
}
196202

197203
setterChild(obj, childKey, value) {
198-
if (isInterface(obj, Setter)) {
204+
// TODO: replace with isInterface(value, Setter) when dart:mirrors
205+
// can support mixins.
206+
try {
199207
obj[childKey] = value;
200208
return value;
201-
}
209+
} on NoSuchMethodError catch(e) {}
210+
202211
InstanceMirror instanceMirror = reflect(obj);
203212
Symbol curSym = new Symbol(childKey);
204213
try {

test/parser_spec.dart

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,22 @@ class TestData {
99
method() => "testMethod";
1010
}
1111

12+
class Mixin {}
13+
class MixedTestData extends TestData with Mixin {
14+
}
15+
16+
class MapData {
17+
operator[](x) => "mapped-$x";
18+
containsKey(x) => true;
19+
}
20+
class MixedMapData extends MapData with Mixin { }
21+
class InheritedMapData extends MapData { }
22+
23+
class BadContainsKeys {
24+
containsKey(x) => null;
25+
String str = "member";
26+
}
27+
1228
class LexerExpect extends Expect {
1329
LexerExpect(actual) : super(actual);
1430
toBeToken(int index, String text) {
@@ -565,6 +581,26 @@ main() {
565581
expect(Parser.parse('str="bob"')(data)).toEqual('bob');
566582
expect(data.str).toEqual("bob");
567583
});
584+
585+
it('should support member field getters from mixins', () {
586+
MixedTestData data = new MixedTestData();
587+
data.str = 'dole';
588+
expect(Parser.parse('str')(data)).toEqual('dole');
589+
});
590+
591+
it('should support map getters from superclass', () {
592+
InheritedMapData mapData = new InheritedMapData();
593+
expect(Parser.parse('notmixed')(mapData)).toEqual('mapped-notmixed');
594+
});
595+
596+
it('should support map getters from mixins', () {
597+
MixedMapData data = new MixedMapData();
598+
expect(Parser.parse('str')(data)).toEqual('mapped-str');
599+
});
600+
601+
iit('should gracefully handle bad containsKey', () {
602+
expect(Parser.parse('str')(new BadContainsKeys())).toEqual('member');
603+
});
568604
});
569605

570606
describe('assignable', () {

0 commit comments

Comments
 (0)