Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * A function element that represents a closure call. The signature is copied | 8 * A function element that represents a closure call. The signature is copied |
| 9 * from the given element. | 9 * from the given element. |
| 10 */ | 10 */ |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 280 // characters. | 280 // characters. |
| 281 static const FIELD_CODE_CHARACTERS = r"<=>?@{|}~%&'()*"; | 281 static const FIELD_CODE_CHARACTERS = r"<=>?@{|}~%&'()*"; |
| 282 static const NO_FIELD_CODE = 0; | 282 static const NO_FIELD_CODE = 0; |
| 283 static const FIRST_FIELD_CODE = 1; | 283 static const FIRST_FIELD_CODE = 1; |
| 284 static const RANGE1_FIRST = 0x3c; // <=>?@ encodes 1..5 | 284 static const RANGE1_FIRST = 0x3c; // <=>?@ encodes 1..5 |
| 285 static const RANGE1_LAST = 0x40; | 285 static const RANGE1_LAST = 0x40; |
| 286 static const RANGE2_FIRST = 0x7b; // {|}~ encodes 6..9 | 286 static const RANGE2_FIRST = 0x7b; // {|}~ encodes 6..9 |
| 287 static const RANGE2_LAST = 0x7e; | 287 static const RANGE2_LAST = 0x7e; |
| 288 static const RANGE3_FIRST = 0x25; // %&'()*+ encodes 10..16 | 288 static const RANGE3_FIRST = 0x25; // %&'()*+ encodes 10..16 |
| 289 static const RANGE3_LAST = 0x2b; | 289 static const RANGE3_LAST = 0x2b; |
| 290 static const REFLECTION_MARKER = 0x2d; | |
| 290 | 291 |
| 291 jsAst.FunctionDeclaration get generateAccessorFunction { | 292 jsAst.FunctionDeclaration get generateAccessorFunction { |
| 292 const RANGE1_SIZE = RANGE1_LAST - RANGE1_FIRST + 1; | 293 const RANGE1_SIZE = RANGE1_LAST - RANGE1_FIRST + 1; |
| 293 const RANGE2_SIZE = RANGE2_LAST - RANGE2_FIRST + 1; | 294 const RANGE2_SIZE = RANGE2_LAST - RANGE2_FIRST + 1; |
| 294 const RANGE1_ADJUST = - (FIRST_FIELD_CODE - RANGE1_FIRST); | 295 const RANGE1_ADJUST = - (FIRST_FIELD_CODE - RANGE1_FIRST); |
| 295 const RANGE2_ADJUST = - (FIRST_FIELD_CODE + RANGE1_SIZE - RANGE2_FIRST); | 296 const RANGE2_ADJUST = - (FIRST_FIELD_CODE + RANGE1_SIZE - RANGE2_FIRST); |
| 296 const RANGE3_ADJUST = | 297 const RANGE3_ADJUST = |
| 297 - (FIRST_FIELD_CODE + RANGE1_SIZE + RANGE2_SIZE - RANGE3_FIRST); | 298 - (FIRST_FIELD_CODE + RANGE1_SIZE + RANGE2_SIZE - RANGE3_FIRST); |
| 298 | 299 |
| 299 String receiverParamName = compiler.enableMinification ? "r" : "receiver"; | 300 String receiverParamName = compiler.enableMinification ? "r" : "receiver"; |
| 300 String valueParamName = compiler.enableMinification ? "v" : "value"; | 301 String valueParamName = compiler.enableMinification ? "v" : "value"; |
| 301 | 302 |
| 302 // function generateAccessor(field, prototype) { | 303 // function generateAccessor(field, prototype) { |
| 303 jsAst.Fun fun = js.fun(['field', 'prototype'], [ | 304 jsAst.Fun fun = js.fun(['field', 'prototype'], [ |
| 304 js('var len = field.length'), | 305 js('var len = field.length'), |
| 305 js('var code = field.charCodeAt(len - 1)'), | 306 js('var code = field.charCodeAt(len - 1)'), |
| 307 js('var reflectable = false'), | |
| 308 js.if_('code == $REFLECTION_MARKER', [ | |
| 309 js('len--'), | |
| 310 js('code = field.charCodeAt(len - 1)'), | |
| 311 js('field = field.substring(0, len)'), | |
| 312 js('reflectable = true') | |
| 313 ]), | |
| 306 js('code = ((code >= $RANGE1_FIRST) && (code <= $RANGE1_LAST))' | 314 js('code = ((code >= $RANGE1_FIRST) && (code <= $RANGE1_LAST))' |
| 307 ' ? code - $RANGE1_ADJUST' | 315 ' ? code - $RANGE1_ADJUST' |
| 308 ' : ((code >= $RANGE2_FIRST) && (code <= $RANGE2_LAST))' | 316 ' : ((code >= $RANGE2_FIRST) && (code <= $RANGE2_LAST))' |
| 309 ' ? code - $RANGE2_ADJUST' | 317 ' ? code - $RANGE2_ADJUST' |
| 310 ' : ((code >= $RANGE3_FIRST) && (code <= $RANGE3_LAST))' | 318 ' : ((code >= $RANGE3_FIRST) && (code <= $RANGE3_LAST))' |
| 311 ' ? code - $RANGE3_ADJUST' | 319 ' ? code - $RANGE3_ADJUST' |
| 312 ' : $NO_FIELD_CODE'), | 320 ' : $NO_FIELD_CODE'), |
| 313 | 321 |
| 314 // if (needsAccessor) { | 322 // if (needsAccessor) { |
| 315 js.if_('code', [ | 323 js.if_('code', [ |
| 316 js('var getterCode = code & 3'), | 324 js('var getterCode = code & 3'), |
| 317 js('var setterCode = code >> 2'), | 325 js('var setterCode = code >> 2'), |
| 318 js('var accessorName = field = field.substring(0, len - 1)'), | 326 js('var accessorName = field = field.substring(0, len - 1)'), |
| 319 | 327 |
| 320 js('var divider = field.indexOf(":")'), | 328 js('var divider = field.indexOf(":")'), |
| 321 js.if_('divider > 0', [ // Colon never in first position. | 329 js.if_('divider > 0', [ // Colon never in first position. |
| 322 js('accessorName = field.substring(0, divider)'), | 330 js('accessorName = field.substring(0, divider)'), |
| 323 js('field = field.substring(divider + 1)') | 331 js('field = field.substring(divider + 1)') |
| 324 ]), | 332 ]), |
| 325 | 333 |
| 326 // if (needsGetter) { | 334 // if (needsGetter) { |
| 327 js.if_('getterCode', [ | 335 js.if_('getterCode', [ |
| 328 js('var args = (getterCode & 2) ? "$receiverParamName" : ""'), | 336 js('var args = (getterCode & 2) ? "$receiverParamName" : ""'), |
| 329 js('var receiver = (getterCode & 1) ? "this" : "$receiverParamName"'), | 337 js('var receiver = (getterCode & 1) ? "this" : "$receiverParamName"'), |
| 330 js('var body = "return " + receiver + "." + field'), | 338 js('var body = "return " + receiver + "." + field'), |
| 331 js('prototype["${namer.getterPrefix}" + accessorName] = ' | 339 js('prototype["${namer.getterPrefix}" + accessorName] = ' |
| 332 'new Function(args, body)') | 340 'new Function(args, body)'), |
| 341 js('prototype["${namer.getterPrefix}" + accessorName].\$reflectable =' | |
|
ngeoffray
2013/08/29 07:45:49
Please move $reflectable to the namer.
karlklose
2013/08/29 15:33:37
Done.
| |
| 342 ' reflectable') | |
|
ngeoffray
2013/08/29 07:45:49
Only add it if reflectable is true?
karlklose
2013/08/29 15:33:37
Done.
| |
| 333 ]), | 343 ]), |
| 334 | 344 |
| 335 // if (needsSetter) { | 345 // if (needsSetter) { |
| 336 js.if_('setterCode', [ | 346 js.if_('setterCode', [ |
| 337 js('var args = (setterCode & 2)' | 347 js('var args = (setterCode & 2)' |
| 338 ' ? "$receiverParamName,${_}$valueParamName"' | 348 ' ? "$receiverParamName,${_}$valueParamName"' |
| 339 ' : "$valueParamName"'), | 349 ' : "$valueParamName"'), |
| 340 js('var receiver = (setterCode & 1) ? "this" : "$receiverParamName"'), | 350 js('var receiver = (setterCode & 1) ? "this" : "$receiverParamName"'), |
| 341 js('var body = receiver + "." + field + "$_=$_$valueParamName"'), | 351 js('var body = receiver + "." + field + "$_=$_$valueParamName"'), |
| 342 js('prototype["${namer.setterPrefix}" + accessorName] = ' | 352 js('prototype["${namer.setterPrefix}" + accessorName] = ' |
| 343 'new Function(args, body)') | 353 'new Function(args, body)'), |
| 354 js('prototype["${namer.setterPrefix}" + accessorName].\$reflectable =' | |
| 355 ' reflectable') | |
|
ngeoffray
2013/08/29 07:45:49
ditto.
karlklose
2013/08/29 15:33:37
Done.
| |
| 344 ]), | 356 ]), |
| 345 | 357 |
| 346 ]), | 358 ]), |
| 347 | 359 |
| 348 // return field; | 360 // return field; |
| 349 js.return_('field') | 361 js.return_('field') |
| 350 ]); | 362 ]); |
| 351 | 363 |
| 352 return new jsAst.FunctionDeclaration( | 364 return new jsAst.FunctionDeclaration( |
| 353 new jsAst.VariableDeclaration('generateAccessor'), | 365 new jsAst.VariableDeclaration('generateAccessor'), |
| (...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1092 } else { | 1104 } else { |
| 1093 body = [js.return_(js('this')[namer.getName(member)](argumentsBuffer))]; | 1105 body = [js.return_(js('this')[namer.getName(member)](argumentsBuffer))]; |
| 1094 } | 1106 } |
| 1095 | 1107 |
| 1096 jsAst.Fun function = js.fun(parametersBuffer, body); | 1108 jsAst.Fun function = js.fun(parametersBuffer, body); |
| 1097 | 1109 |
| 1098 defineStub(invocationName, function); | 1110 defineStub(invocationName, function); |
| 1099 | 1111 |
| 1100 String reflectionName = getReflectionName(selector, invocationName); | 1112 String reflectionName = getReflectionName(selector, invocationName); |
| 1101 if (reflectionName != null) { | 1113 if (reflectionName != null) { |
| 1102 defineStub('+$reflectionName', js('0')); | 1114 var reflectable = |
| 1115 js(backend.isAccessibleByReflection(member) ? '1' : '0'); | |
| 1116 defineStub('+$reflectionName', reflectable); | |
| 1103 } | 1117 } |
| 1104 } | 1118 } |
| 1105 | 1119 |
| 1106 void addParameterStubs(FunctionElement member, | 1120 void addParameterStubs(FunctionElement member, |
| 1107 DefineStubFunction defineStub) { | 1121 DefineStubFunction defineStub) { |
| 1108 // We fill the lists depending on the selector. For example, | 1122 // We fill the lists depending on the selector. For example, |
| 1109 // take method foo: | 1123 // take method foo: |
| 1110 // foo(a, b, {c, d}); | 1124 // foo(a, b, {c, d}); |
| 1111 // | 1125 // |
| 1112 // We may have multiple ways of calling foo: | 1126 // We may have multiple ways of calling foo: |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1263 jsAst.Expression code = backend.generatedCode[member]; | 1277 jsAst.Expression code = backend.generatedCode[member]; |
| 1264 if (code == null) return; | 1278 if (code == null) return; |
| 1265 String name = namer.getName(member); | 1279 String name = namer.getName(member); |
| 1266 if (backend.isInterceptedMethod(member)) { | 1280 if (backend.isInterceptedMethod(member)) { |
| 1267 interceptorInvocationNames.add(name); | 1281 interceptorInvocationNames.add(name); |
| 1268 } | 1282 } |
| 1269 code = extendWithMetadata(member, code); | 1283 code = extendWithMetadata(member, code); |
| 1270 builder.addProperty(name, code); | 1284 builder.addProperty(name, code); |
| 1271 String reflectionName = getReflectionName(member, name); | 1285 String reflectionName = getReflectionName(member, name); |
| 1272 if (reflectionName != null) { | 1286 if (reflectionName != null) { |
| 1273 builder.addProperty('+$reflectionName', js('0')); | 1287 var reflectable = |
| 1288 js(backend.isAccessibleByReflection(member) ? '1' : '0'); | |
| 1289 builder.addProperty('+$reflectionName', reflectable); | |
| 1274 } | 1290 } |
| 1275 code = backend.generatedBailoutCode[member]; | 1291 code = backend.generatedBailoutCode[member]; |
| 1276 if (code != null) { | 1292 if (code != null) { |
| 1277 builder.addProperty(namer.getBailoutName(member), code); | 1293 builder.addProperty(namer.getBailoutName(member), code); |
| 1278 } | 1294 } |
| 1279 FunctionElement function = member; | 1295 FunctionElement function = member; |
| 1280 FunctionSignature parameters = function.computeSignature(compiler); | 1296 FunctionSignature parameters = function.computeSignature(compiler); |
| 1281 if (!parameters.optionalParameters.isEmpty) { | 1297 if (!parameters.optionalParameters.isEmpty) { |
| 1282 addParameterStubs(member, builder.addProperty); | 1298 addParameterStubs(member, builder.addProperty); |
| 1283 } | 1299 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1318 | 1334 |
| 1319 String getReflectionNameInternal(elementOrSelector, String mangledName) { | 1335 String getReflectionNameInternal(elementOrSelector, String mangledName) { |
| 1320 String name = elementOrSelector.name.slowToString(); | 1336 String name = elementOrSelector.name.slowToString(); |
| 1321 if (elementOrSelector.isGetter()) return name; | 1337 if (elementOrSelector.isGetter()) return name; |
| 1322 if (elementOrSelector.isSetter()) { | 1338 if (elementOrSelector.isSetter()) { |
| 1323 if (!mangledName.startsWith(namer.setterPrefix)) return '$name='; | 1339 if (!mangledName.startsWith(namer.setterPrefix)) return '$name='; |
| 1324 String base = mangledName.substring(namer.setterPrefix.length); | 1340 String base = mangledName.substring(namer.setterPrefix.length); |
| 1325 String getter = '${namer.getterPrefix}$base'; | 1341 String getter = '${namer.getterPrefix}$base'; |
| 1326 mangledFieldNames[getter] = name; | 1342 mangledFieldNames[getter] = name; |
| 1327 recordedMangledNames.add(getter); | 1343 recordedMangledNames.add(getter); |
| 1328 return null; | 1344 // TODO(karlklose,ahe): we do not actually need to store information |
| 1345 // about the name of this setter in the output, but it is needed for | |
| 1346 // marking the function as invokable by reflection. | |
| 1347 return '$name='; | |
| 1329 } | 1348 } |
| 1330 if (elementOrSelector is Selector | 1349 if (elementOrSelector is Selector |
| 1331 || elementOrSelector.isFunction() | 1350 || elementOrSelector.isFunction() |
| 1332 || elementOrSelector.isConstructor()) { | 1351 || elementOrSelector.isConstructor()) { |
| 1333 int requiredParameterCount; | 1352 int requiredParameterCount; |
| 1334 int optionalParameterCount; | 1353 int optionalParameterCount; |
| 1335 String namedArguments = ''; | 1354 String namedArguments = ''; |
| 1336 bool isConstructor = false; | 1355 bool isConstructor = false; |
| 1337 if (elementOrSelector is Selector) { | 1356 if (elementOrSelector is Selector) { |
| 1338 Selector selector = elementOrSelector; | 1357 Selector selector = elementOrSelector; |
| (...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1854 } | 1873 } |
| 1855 } | 1874 } |
| 1856 int code = getterCode + (setterCode << 2); | 1875 int code = getterCode + (setterCode << 2); |
| 1857 if (code == 0) { | 1876 if (code == 0) { |
| 1858 compiler.reportInternalError( | 1877 compiler.reportInternalError( |
| 1859 field, 'Internal error: code is 0 ($element/$field)'); | 1878 field, 'Internal error: code is 0 ($element/$field)'); |
| 1860 } else { | 1879 } else { |
| 1861 buffer.write(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]); | 1880 buffer.write(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]); |
| 1862 } | 1881 } |
| 1863 } | 1882 } |
| 1883 if (backend.isAccessibleByReflection(field)) { | |
| 1884 buffer.write(new String.fromCharCode(REFLECTION_MARKER)); | |
| 1885 } | |
| 1864 } | 1886 } |
| 1865 }); | 1887 }); |
| 1866 } | 1888 } |
| 1867 | 1889 |
| 1868 bool fieldsAdded = buffer.length > bufferClassLength; | 1890 bool fieldsAdded = buffer.length > bufferClassLength; |
| 1869 String compactClassData = buffer.toString(); | 1891 String compactClassData = buffer.toString(); |
| 1870 jsAst.Expression classDataNode = js.string(compactClassData); | 1892 jsAst.Expression classDataNode = js.string(compactClassData); |
| 1871 if (hasMetadata) { | 1893 if (hasMetadata) { |
| 1872 fieldMetadata.insert(0, classDataNode); | 1894 fieldMetadata.insert(0, classDataNode); |
| 1873 classDataNode = new jsAst.ArrayInitializer.from(fieldMetadata); | 1895 classDataNode = new jsAst.ArrayInitializer.from(fieldMetadata); |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2293 .toSet(); | 2315 .toSet(); |
| 2294 | 2316 |
| 2295 for (Element element in Elements.sortedByPosition(elements)) { | 2317 for (Element element in Elements.sortedByPosition(elements)) { |
| 2296 CodeBuffer buffer = bufferForElement(element, eagerBuffer); | 2318 CodeBuffer buffer = bufferForElement(element, eagerBuffer); |
| 2297 jsAst.Expression code = backend.generatedCode[element]; | 2319 jsAst.Expression code = backend.generatedCode[element]; |
| 2298 String name = namer.getName(element); | 2320 String name = namer.getName(element); |
| 2299 code = extendWithMetadata(element, code); | 2321 code = extendWithMetadata(element, code); |
| 2300 emitStaticFunction(buffer, name, code); | 2322 emitStaticFunction(buffer, name, code); |
| 2301 String reflectionName = getReflectionName(element, name); | 2323 String reflectionName = getReflectionName(element, name); |
| 2302 if (reflectionName != null) { | 2324 if (reflectionName != null) { |
| 2303 buffer.write(',$n$n"+$reflectionName":${_}0'); | 2325 var reflectable = backend.isAccessibleByReflection(element) ? 1 : 0; |
| 2326 buffer.write(',$n$n"+$reflectionName":${_}$reflectable'); | |
| 2304 } | 2327 } |
| 2305 jsAst.Expression bailoutCode = backend.generatedBailoutCode[element]; | 2328 jsAst.Expression bailoutCode = backend.generatedBailoutCode[element]; |
| 2306 if (bailoutCode != null) { | 2329 if (bailoutCode != null) { |
| 2307 pendingElementsWithBailouts.remove(element); | 2330 pendingElementsWithBailouts.remove(element); |
| 2308 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode); | 2331 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode); |
| 2309 } | 2332 } |
| 2310 } | 2333 } |
| 2311 | 2334 |
| 2312 if (!pendingElementsWithBailouts.isEmpty) { | 2335 if (!pendingElementsWithBailouts.isEmpty) { |
| 2313 addComment('pendingElementsWithBailouts', eagerBuffer); | 2336 addComment('pendingElementsWithBailouts', eagerBuffer); |
| (...skipping 1757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4071 var functions = []; | 4094 var functions = []; |
| 4072 function processStatics(descriptor) { | 4095 function processStatics(descriptor) { |
| 4073 for (var property in descriptor) { | 4096 for (var property in descriptor) { |
| 4074 if (!hasOwnProperty.call(descriptor, property)) continue; | 4097 if (!hasOwnProperty.call(descriptor, property)) continue; |
| 4075 if (property === "") continue; | 4098 if (property === "") continue; |
| 4076 var element = descriptor[property]; | 4099 var element = descriptor[property]; |
| 4077 var firstChar = property.substring(0, 1); | 4100 var firstChar = property.substring(0, 1); |
| 4078 var previousProperty; | 4101 var previousProperty; |
| 4079 if (firstChar === "+") { | 4102 if (firstChar === "+") { |
| 4080 mangledGlobalNames[previousProperty] = property.substring(1); | 4103 mangledGlobalNames[previousProperty] = property.substring(1); |
| 4081 if (element && element.length) ''' // Breaking long line. | 4104 descriptor[previousProperty].\$reflectable = ''' // Break long line. |
| 4105 '''(descriptor[property] == 1); | |
| 4106 if (element && element.length) ''' // Break long line. | |
| 4082 '''init.interfaces[previousProperty] = element; | 4107 '''init.interfaces[previousProperty] = element; |
| 4083 } else if (firstChar === "@") { | 4108 } else if (firstChar === "@") { |
| 4084 property = property.substring(1); | 4109 property = property.substring(1); |
| 4085 ${namer.CURRENT_ISOLATE}[property][$metadataField] = element; | 4110 ${namer.CURRENT_ISOLATE}[property][$metadataField] = element; |
| 4086 } else if (typeof element === "function") { | 4111 } else if (typeof element === "function") { |
| 4087 ${namer.CURRENT_ISOLATE}[previousProperty = property] = element; | 4112 ${namer.CURRENT_ISOLATE}[previousProperty = property] = element; |
| 4088 functions.push(property); | 4113 functions.push(property); |
| 4089 } else { | 4114 } else { |
| 4090 previousProperty = property; | 4115 previousProperty = property; |
| 4091 var newDesc = {}; | 4116 var newDesc = {}; |
| 4092 var previousProp; | 4117 var previousProp; |
| 4093 for (var prop in element) { | 4118 for (var prop in element) { |
| 4094 if (!hasOwnProperty.call(element, prop)) continue; | 4119 if (!hasOwnProperty.call(element, prop)) continue; |
| 4095 firstChar = prop.substring(0, 1); | 4120 firstChar = prop.substring(0, 1); |
| 4096 if (prop === "static") { | 4121 if (prop === "static") { |
| 4097 processStatics(init.statics[property] = element[prop]); | 4122 processStatics(init.statics[property] = element[prop]); |
| 4098 } else if (firstChar === "+") { | 4123 } else if (firstChar === "+") { |
| 4099 mangledNames[previousProp] = prop.substring(1); | 4124 mangledNames[previousProp] = prop.substring(1); |
| 4125 element[previousProp].\$reflectable = ''' // Break long line. | |
| 4126 '''(element[prop] == 1); | |
| 4100 } else if (firstChar === "@" && prop !== "@") { | 4127 } else if (firstChar === "@" && prop !== "@") { |
| 4101 newDesc[prop.substring(1)][$metadataField] = element[prop]; | 4128 newDesc[prop.substring(1)][$metadataField] = element[prop]; |
| 4102 } else { | 4129 } else { |
| 4103 newDesc[previousProp = prop] = element[prop]; | 4130 newDesc[previousProp = prop] = element[prop]; |
| 4104 } | 4131 } |
| 4105 } | 4132 } |
| 4106 $classesCollector[property] = newDesc; | 4133 $classesCollector[property] = newDesc; |
| 4107 classes.push(property); | 4134 classes.push(property); |
| 4108 } | 4135 } |
| 4109 } | 4136 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 4121 | 4148 |
| 4122 const String HOOKS_API_USAGE = """ | 4149 const String HOOKS_API_USAGE = """ |
| 4123 // The code supports the following hooks: | 4150 // The code supports the following hooks: |
| 4124 // dartPrint(message) - if this function is defined it is called | 4151 // dartPrint(message) - if this function is defined it is called |
| 4125 // instead of the Dart [print] method. | 4152 // instead of the Dart [print] method. |
| 4126 // dartMainRunner(main) - if this function is defined, the Dart [main] | 4153 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 4127 // method will not be invoked directly. | 4154 // method will not be invoked directly. |
| 4128 // Instead, a closure that will invoke [main] is | 4155 // Instead, a closure that will invoke [main] is |
| 4129 // passed to [dartMainRunner]. | 4156 // passed to [dartMainRunner]. |
| 4130 """; | 4157 """; |
| OLD | NEW |