| Index: frog/gen.dart
|
| diff --git a/frog/gen.dart b/frog/gen.dart
|
| index c518d2e13b5566f263f7a0b10fbbb1d6d47d998a..57ba1be3c79f269f9eda99e5cd45ee5eb9686a75 100644
|
| --- a/frog/gen.dart
|
| +++ b/frog/gen.dart
|
| @@ -48,6 +48,10 @@ class WorldGenerator {
|
| world.coreimpl.types['StringImplementation'].markUsed();
|
| genMethod(
|
| world.coreimpl.types['StringImplementation'].getMember('contains'));
|
| + if (world.corelib.types['String'].isUsed) {
|
| + // 'String.split' creates a list.
|
| + world.coreimpl.types['ListFactory'].markUsed();
|
| + }
|
| }
|
|
|
| // Only include isolate-specific code if isolates are used.
|
| @@ -225,6 +229,16 @@ class WorldGenerator {
|
| }
|
| }
|
|
|
| + String _boundMethod(Type type, String name) {
|
| + if (type.isSingletonNative) {
|
| + return '${type.jsname}.$name.bind(${type.jsname})';
|
| + } else if (type.isHiddenNativeType) {
|
| + return 'Object.getPrototype(this).${type.jsname}.bind(this)';
|
| + } else {
|
| + return '${type.jsname}.prototype.$name.bind(this)';
|
| + }
|
| + }
|
| +
|
| _maybeIsTest(Type onType, Type checkType) {
|
| bool isSubtype = onType.isSubtypeOf(checkType);
|
| if (checkType.isTested) {
|
| @@ -466,9 +480,12 @@ function $inheritsMembers(child, parent) {
|
| }
|
| }
|
|
|
| - _writeMethod(Member method) {
|
| - if (method.generator != null) {
|
| - method.generator.writeDefinition(writer, null);
|
| + _writeMethod(Member m) {
|
| + if (m.generator != null) {
|
| + m.generator.writeDefinition(writer, null);
|
| + } else if (m is MethodMember && m.isNative
|
| + && m.dynamic._providePropertySyntax && !m.dynamic._provideFieldSyntax) {
|
| + MethodGenerator._maybeGenerateBoundGetter(m, writer);
|
| }
|
| }
|
|
|
| @@ -862,17 +879,23 @@ class MethodGenerator implements TreeVisitor {
|
|
|
| if (method is MethodMember) {
|
| MethodMember m = method;
|
| - if (m._providePropertySyntax) {
|
| - defWriter.enterBlock('${m.declaringType.jsname}.prototype'
|
| - + '.get\$${m.jsname} = function() {');
|
| - // TODO(jimhug): Bind not available in older Safari, need fallback?
|
| - defWriter.writeln('return ${m.declaringType.jsname}.prototype.'
|
| - + '${m.jsname}.bind(this);');
|
| - defWriter.exitBlock('}');
|
| -
|
| - if (m._provideFieldSyntax) {
|
| - world.internalError('bound m accessed with field syntax');
|
| - }
|
| + _maybeGenerateBoundGetter(m, defWriter);
|
| + }
|
| + }
|
| +
|
| + static _maybeGenerateBoundGetter(MethodMember m, CodeWriter defWriter) {
|
| + if (m._providePropertySyntax && !m.declaringType.isSingletonNative) {
|
| + defWriter.enterBlock(
|
| + world.gen._prototypeOf(m.declaringType, "get\$" + m.jsname)
|
| + + ' = function() {');
|
| + // TODO(jimhug): Bind not available in older Safari, need fallback?
|
| + defWriter.writeln('return '
|
| + + world.gen._boundMethod(m.declaringType, m.jsname));
|
| + defWriter.exitBlock('}');
|
| +
|
| + if (m._provideFieldSyntax) {
|
| + world.internalError('bound "${m.name}" accessed with field syntax',
|
| + m.definition.span);
|
| }
|
| }
|
| }
|
| @@ -1459,8 +1482,9 @@ class MethodGenerator implements TreeVisitor {
|
| // Special path for list for readability and perf optimization.
|
| if (list.type.isList) {
|
| var tmpi = _scope.create('\$i', world.numType, null);
|
| + var listLength = listVar.get_(this, 'length', node.list);
|
| writer.enterBlock('for (var ${tmpi.code} = 0;' +
|
| - '${tmpi.code} < ${listVar.code}.length; ${tmpi.code}++) {');
|
| + '${tmpi.code} < ${listLength.code}; ${tmpi.code}++) {');
|
| var value = listVar.invoke(this, ':index', node.list,
|
| new Arguments(null, [tmpi]));
|
| writer.writeln('var ${item.code} = ${value.code};');
|
|
|