fix(change_detect): Handle '$' in change detector strings
In Dart, '$' indicates the beginning of an interpolation. - Escapes '$' in strings when generating change detector classes. - Adds a unit test to cover this case.
This commit is contained in:
parent
621604dc66
commit
f1e8176995
|
@ -142,7 +142,7 @@ class _CodegenState {
|
||||||
$_changeDetectorTypeName(
|
$_changeDetectorTypeName(
|
||||||
this.$_DISPATCHER_ACCESSOR,
|
this.$_DISPATCHER_ACCESSOR,
|
||||||
this.$_PROTOS_ACCESSOR,
|
this.$_PROTOS_ACCESSOR,
|
||||||
this.$_DIRECTIVES_ACCESSOR) : super(${JSON.encode(_changeDetectorDefId)});
|
this.$_DIRECTIVES_ACCESSOR) : super(${_encodeValue(_changeDetectorDefId)});
|
||||||
|
|
||||||
void detectChangesInRecords(throwOnChange) {
|
void detectChangesInRecords(throwOnChange) {
|
||||||
if (!hydrated()) {
|
if (!hydrated()) {
|
||||||
|
@ -383,7 +383,7 @@ class _CodegenState {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RecordType.CONST:
|
case RecordType.CONST:
|
||||||
rhs = JSON.encode(r.funcOrValue);
|
rhs = _encodeValue(r.funcOrValue);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RecordType.PROPERTY:
|
case RecordType.PROPERTY:
|
||||||
|
@ -435,9 +435,9 @@ class _CodegenState {
|
||||||
for (var i = 0; i < r.args.length; ++i) {
|
for (var i = 0; i < r.args.length; ++i) {
|
||||||
var name = _localNames[r.args[i]];
|
var name = _localNames[r.args[i]];
|
||||||
res.write(
|
res.write(
|
||||||
'${JSON.encode(r.fixedArgs[i])} "\$\{$name == null ? "" : $name\}" ');
|
'${_encodeValue(r.fixedArgs[i])} "\$\{$name == null ? "" : $name\}" ');
|
||||||
}
|
}
|
||||||
res.write(JSON.encode(r.fixedArgs[r.args.length]));
|
res.write(_encodeValue(r.fixedArgs[r.args.length]));
|
||||||
return '$res';
|
return '$res';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,6 +523,9 @@ class _CodegenState {
|
||||||
}
|
}
|
||||||
''';
|
''';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String _encodeValue(funcOrValue) =>
|
||||||
|
JSON.encode(funcOrValue).replaceAll(r'$', r'\$');
|
||||||
}
|
}
|
||||||
|
|
||||||
const PROTO_CHANGE_DETECTOR_FACTORY_METHOD = 'newProtoChangeDetector';
|
const PROTO_CHANGE_DETECTOR_FACTORY_METHOD = 'newProtoChangeDetector';
|
||||||
|
|
|
@ -263,6 +263,7 @@ class _DirectiveUpdating {
|
||||||
* equivalent to their ids.
|
* equivalent to their ids.
|
||||||
*/
|
*/
|
||||||
var _availableDefinitions = [
|
var _availableDefinitions = [
|
||||||
|
'"$"',
|
||||||
'10',
|
'10',
|
||||||
'"str"',
|
'"str"',
|
||||||
'"a\n\nb"',
|
'"a\n\nb"',
|
||||||
|
|
|
@ -302,6 +302,9 @@ export function main() {
|
||||||
expect(val.dispatcher.log).toEqual(['propName=BvalueA']);
|
expect(val.dispatcher.log).toEqual(['propName=BvalueA']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should escape values in literals that indicate interpolation',
|
||||||
|
() => { expect(_bindSimpleValue('"$"')).toEqual(['propName=$']); });
|
||||||
|
|
||||||
describe('pure functions', () => {
|
describe('pure functions', () => {
|
||||||
it('should preserve memoized result', () => {
|
it('should preserve memoized result', () => {
|
||||||
var person = new Person('bob');
|
var person = new Person('bob');
|
||||||
|
|
|
@ -21,7 +21,7 @@ void main(List<String> args) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
buf.write(',');
|
buf.write(',');
|
||||||
}
|
}
|
||||||
buf.write(" '''${allDefs[i].cdDef.id}''': "
|
buf.write(" '''${_escape(allDefs[i].cdDef.id)}''': "
|
||||||
"$className.$PROTO_CHANGE_DETECTOR_FACTORY_METHOD");
|
"$className.$PROTO_CHANGE_DETECTOR_FACTORY_METHOD");
|
||||||
}
|
}
|
||||||
buf.write('};');
|
buf.write('};');
|
||||||
|
@ -37,4 +37,6 @@ void main(List<String> args) {
|
||||||
'''));
|
'''));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String _escape(String id) => id.replaceAll(r'$', r'\$');
|
||||||
|
|
||||||
const _MAP_NAME = '_idToProtoMap';
|
const _MAP_NAME = '_idToProtoMap';
|
||||||
|
|
Loading…
Reference in New Issue