| 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"; |
| 302 String reflectableField = namer.reflectableField; |
| 301 | 303 |
| 302 // function generateAccessor(field, prototype) { | 304 // function generateAccessor(field, prototype) { |
| 303 jsAst.Fun fun = js.fun(['field', 'prototype'], [ | 305 jsAst.Fun fun = js.fun(['field', 'prototype'], [ |
| 304 js('var len = field.length'), | 306 js('var len = field.length'), |
| 305 js('var code = field.charCodeAt(len - 1)'), | 307 js('var code = field.charCodeAt(len - 1)'), |
| 308 js('var reflectable = false'), |
| 309 js.if_('code == $REFLECTION_MARKER', [ |
| 310 js('len--'), |
| 311 js('code = field.charCodeAt(len - 1)'), |
| 312 js('field = field.substring(0, len)'), |
| 313 js('reflectable = true') |
| 314 ]), |
| 306 js('code = ((code >= $RANGE1_FIRST) && (code <= $RANGE1_LAST))' | 315 js('code = ((code >= $RANGE1_FIRST) && (code <= $RANGE1_LAST))' |
| 307 ' ? code - $RANGE1_ADJUST' | 316 ' ? code - $RANGE1_ADJUST' |
| 308 ' : ((code >= $RANGE2_FIRST) && (code <= $RANGE2_LAST))' | 317 ' : ((code >= $RANGE2_FIRST) && (code <= $RANGE2_LAST))' |
| 309 ' ? code - $RANGE2_ADJUST' | 318 ' ? code - $RANGE2_ADJUST' |
| 310 ' : ((code >= $RANGE3_FIRST) && (code <= $RANGE3_LAST))' | 319 ' : ((code >= $RANGE3_FIRST) && (code <= $RANGE3_LAST))' |
| 311 ' ? code - $RANGE3_ADJUST' | 320 ' ? code - $RANGE3_ADJUST' |
| 312 ' : $NO_FIELD_CODE'), | 321 ' : $NO_FIELD_CODE'), |
| 313 | 322 |
| 314 // if (needsAccessor) { | 323 // if (needsAccessor) { |
| 315 js.if_('code', [ | 324 js.if_('code', [ |
| 316 js('var getterCode = code & 3'), | 325 js('var getterCode = code & 3'), |
| 317 js('var setterCode = code >> 2'), | 326 js('var setterCode = code >> 2'), |
| 318 js('var accessorName = field = field.substring(0, len - 1)'), | 327 js('var accessorName = field = field.substring(0, len - 1)'), |
| 319 | 328 |
| 320 js('var divider = field.indexOf(":")'), | 329 js('var divider = field.indexOf(":")'), |
| 321 js.if_('divider > 0', [ // Colon never in first position. | 330 js.if_('divider > 0', [ // Colon never in first position. |
| 322 js('accessorName = field.substring(0, divider)'), | 331 js('accessorName = field.substring(0, divider)'), |
| 323 js('field = field.substring(divider + 1)') | 332 js('field = field.substring(divider + 1)') |
| 324 ]), | 333 ]), |
| 325 | 334 |
| 326 // if (needsGetter) { | 335 // if (needsGetter) { |
| 327 js.if_('getterCode', [ | 336 js.if_('getterCode', [ |
| 328 js('var args = (getterCode & 2) ? "$receiverParamName" : ""'), | 337 js('var args = (getterCode & 2) ? "$receiverParamName" : ""'), |
| 329 js('var receiver = (getterCode & 1) ? "this" : "$receiverParamName"'), | 338 js('var receiver = (getterCode & 1) ? "this" : "$receiverParamName"'), |
| 330 js('var body = "return " + receiver + "." + field'), | 339 js('var body = "return " + receiver + "." + field'), |
| 331 js('prototype["${namer.getterPrefix}" + accessorName] = ' | 340 js('prototype["${namer.getterPrefix}" + accessorName] = ' |
| 332 'new Function(args, body)') | 341 'new Function(args, body)'), |
| 342 js.if_('!reflectable', [ |
| 343 js('prototype["${namer.getterPrefix}" + accessorName].' |
| 344 '$reflectableField = false')]) |
| 333 ]), | 345 ]), |
| 334 | 346 |
| 335 // if (needsSetter) { | 347 // if (needsSetter) { |
| 336 js.if_('setterCode', [ | 348 js.if_('setterCode', [ |
| 337 js('var args = (setterCode & 2)' | 349 js('var args = (setterCode & 2)' |
| 338 ' ? "$receiverParamName,${_}$valueParamName"' | 350 ' ? "$receiverParamName,${_}$valueParamName"' |
| 339 ' : "$valueParamName"'), | 351 ' : "$valueParamName"'), |
| 340 js('var receiver = (setterCode & 1) ? "this" : "$receiverParamName"'), | 352 js('var receiver = (setterCode & 1) ? "this" : "$receiverParamName"'), |
| 341 js('var body = receiver + "." + field + "$_=$_$valueParamName"'), | 353 js('var body = receiver + "." + field + "$_=$_$valueParamName"'), |
| 342 js('prototype["${namer.setterPrefix}" + accessorName] = ' | 354 js('prototype["${namer.setterPrefix}" + accessorName] = ' |
| 343 'new Function(args, body)') | 355 'new Function(args, body)'), |
| 356 js.if_('!reflectable', [ |
| 357 js('prototype["${namer.setterPrefix}" + accessorName].' |
| 358 '$reflectableField = false')]) |
| 344 ]), | 359 ]), |
| 345 | 360 |
| 346 ]), | 361 ]), |
| 347 | 362 |
| 348 // return field; | 363 // return field; |
| 349 js.return_('field') | 364 js.return_('field') |
| 350 ]); | 365 ]); |
| 351 | 366 |
| 352 return new jsAst.FunctionDeclaration( | 367 return new jsAst.FunctionDeclaration( |
| 353 new jsAst.VariableDeclaration('generateAccessor'), | 368 new jsAst.VariableDeclaration('generateAccessor'), |
| (...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1092 } else { | 1107 } else { |
| 1093 body = [js.return_(js('this')[namer.getName(member)](argumentsBuffer))]; | 1108 body = [js.return_(js('this')[namer.getName(member)](argumentsBuffer))]; |
| 1094 } | 1109 } |
| 1095 | 1110 |
| 1096 jsAst.Fun function = js.fun(parametersBuffer, body); | 1111 jsAst.Fun function = js.fun(parametersBuffer, body); |
| 1097 | 1112 |
| 1098 defineStub(invocationName, function); | 1113 defineStub(invocationName, function); |
| 1099 | 1114 |
| 1100 String reflectionName = getReflectionName(selector, invocationName); | 1115 String reflectionName = getReflectionName(selector, invocationName); |
| 1101 if (reflectionName != null) { | 1116 if (reflectionName != null) { |
| 1102 defineStub('+$reflectionName', js('0')); | 1117 var reflectable = |
| 1118 js(backend.isAccessibleByReflection(member) ? '1' : '0'); |
| 1119 defineStub('+$reflectionName', reflectable); |
| 1103 } | 1120 } |
| 1104 } | 1121 } |
| 1105 | 1122 |
| 1106 void addParameterStubs(FunctionElement member, | 1123 void addParameterStubs(FunctionElement member, |
| 1107 DefineStubFunction defineStub) { | 1124 DefineStubFunction defineStub) { |
| 1108 // We fill the lists depending on the selector. For example, | 1125 // We fill the lists depending on the selector. For example, |
| 1109 // take method foo: | 1126 // take method foo: |
| 1110 // foo(a, b, {c, d}); | 1127 // foo(a, b, {c, d}); |
| 1111 // | 1128 // |
| 1112 // We may have multiple ways of calling foo: | 1129 // 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]; | 1280 jsAst.Expression code = backend.generatedCode[member]; |
| 1264 if (code == null) return; | 1281 if (code == null) return; |
| 1265 String name = namer.getName(member); | 1282 String name = namer.getName(member); |
| 1266 if (backend.isInterceptedMethod(member)) { | 1283 if (backend.isInterceptedMethod(member)) { |
| 1267 interceptorInvocationNames.add(name); | 1284 interceptorInvocationNames.add(name); |
| 1268 } | 1285 } |
| 1269 code = extendWithMetadata(member, code); | 1286 code = extendWithMetadata(member, code); |
| 1270 builder.addProperty(name, code); | 1287 builder.addProperty(name, code); |
| 1271 String reflectionName = getReflectionName(member, name); | 1288 String reflectionName = getReflectionName(member, name); |
| 1272 if (reflectionName != null) { | 1289 if (reflectionName != null) { |
| 1273 builder.addProperty('+$reflectionName', js('0')); | 1290 var reflectable = |
| 1291 js(backend.isAccessibleByReflection(member) ? '1' : '0'); |
| 1292 builder.addProperty('+$reflectionName', reflectable); |
| 1274 } | 1293 } |
| 1275 code = backend.generatedBailoutCode[member]; | 1294 code = backend.generatedBailoutCode[member]; |
| 1276 if (code != null) { | 1295 if (code != null) { |
| 1277 builder.addProperty(namer.getBailoutName(member), code); | 1296 builder.addProperty(namer.getBailoutName(member), code); |
| 1278 } | 1297 } |
| 1279 FunctionElement function = member; | 1298 FunctionElement function = member; |
| 1280 FunctionSignature parameters = function.computeSignature(compiler); | 1299 FunctionSignature parameters = function.computeSignature(compiler); |
| 1281 if (!parameters.optionalParameters.isEmpty) { | 1300 if (!parameters.optionalParameters.isEmpty) { |
| 1282 addParameterStubs(member, builder.addProperty); | 1301 addParameterStubs(member, builder.addProperty); |
| 1283 } | 1302 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1318 | 1337 |
| 1319 String getReflectionNameInternal(elementOrSelector, String mangledName) { | 1338 String getReflectionNameInternal(elementOrSelector, String mangledName) { |
| 1320 String name = elementOrSelector.name.slowToString(); | 1339 String name = elementOrSelector.name.slowToString(); |
| 1321 if (elementOrSelector.isGetter()) return name; | 1340 if (elementOrSelector.isGetter()) return name; |
| 1322 if (elementOrSelector.isSetter()) { | 1341 if (elementOrSelector.isSetter()) { |
| 1323 if (!mangledName.startsWith(namer.setterPrefix)) return '$name='; | 1342 if (!mangledName.startsWith(namer.setterPrefix)) return '$name='; |
| 1324 String base = mangledName.substring(namer.setterPrefix.length); | 1343 String base = mangledName.substring(namer.setterPrefix.length); |
| 1325 String getter = '${namer.getterPrefix}$base'; | 1344 String getter = '${namer.getterPrefix}$base'; |
| 1326 mangledFieldNames[getter] = name; | 1345 mangledFieldNames[getter] = name; |
| 1327 recordedMangledNames.add(getter); | 1346 recordedMangledNames.add(getter); |
| 1328 return null; | 1347 // TODO(karlklose,ahe): we do not actually need to store information |
| 1348 // about the name of this setter in the output, but it is needed for |
| 1349 // marking the function as invokable by reflection. |
| 1350 return '$name='; |
| 1329 } | 1351 } |
| 1330 if (elementOrSelector is Selector | 1352 if (elementOrSelector is Selector |
| 1331 || elementOrSelector.isFunction() | 1353 || elementOrSelector.isFunction() |
| 1332 || elementOrSelector.isConstructor()) { | 1354 || elementOrSelector.isConstructor()) { |
| 1333 int requiredParameterCount; | 1355 int requiredParameterCount; |
| 1334 int optionalParameterCount; | 1356 int optionalParameterCount; |
| 1335 String namedArguments = ''; | 1357 String namedArguments = ''; |
| 1336 bool isConstructor = false; | 1358 bool isConstructor = false; |
| 1337 if (elementOrSelector is Selector) { | 1359 if (elementOrSelector is Selector) { |
| 1338 Selector selector = elementOrSelector; | 1360 Selector selector = elementOrSelector; |
| (...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1854 } | 1876 } |
| 1855 } | 1877 } |
| 1856 int code = getterCode + (setterCode << 2); | 1878 int code = getterCode + (setterCode << 2); |
| 1857 if (code == 0) { | 1879 if (code == 0) { |
| 1858 compiler.reportInternalError( | 1880 compiler.reportInternalError( |
| 1859 field, 'Internal error: code is 0 ($element/$field)'); | 1881 field, 'Internal error: code is 0 ($element/$field)'); |
| 1860 } else { | 1882 } else { |
| 1861 buffer.write(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]); | 1883 buffer.write(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]); |
| 1862 } | 1884 } |
| 1863 } | 1885 } |
| 1886 if (backend.isAccessibleByReflection(field)) { |
| 1887 buffer.write(new String.fromCharCode(REFLECTION_MARKER)); |
| 1888 } |
| 1864 } | 1889 } |
| 1865 }); | 1890 }); |
| 1866 } | 1891 } |
| 1867 | 1892 |
| 1868 bool fieldsAdded = buffer.length > bufferClassLength; | 1893 bool fieldsAdded = buffer.length > bufferClassLength; |
| 1869 String compactClassData = buffer.toString(); | 1894 String compactClassData = buffer.toString(); |
| 1870 jsAst.Expression classDataNode = js.string(compactClassData); | 1895 jsAst.Expression classDataNode = js.string(compactClassData); |
| 1871 if (hasMetadata) { | 1896 if (hasMetadata) { |
| 1872 fieldMetadata.insert(0, classDataNode); | 1897 fieldMetadata.insert(0, classDataNode); |
| 1873 classDataNode = new jsAst.ArrayInitializer.from(fieldMetadata); | 1898 classDataNode = new jsAst.ArrayInitializer.from(fieldMetadata); |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2293 .toSet(); | 2318 .toSet(); |
| 2294 | 2319 |
| 2295 for (Element element in Elements.sortedByPosition(elements)) { | 2320 for (Element element in Elements.sortedByPosition(elements)) { |
| 2296 CodeBuffer buffer = bufferForElement(element, eagerBuffer); | 2321 CodeBuffer buffer = bufferForElement(element, eagerBuffer); |
| 2297 jsAst.Expression code = backend.generatedCode[element]; | 2322 jsAst.Expression code = backend.generatedCode[element]; |
| 2298 String name = namer.getName(element); | 2323 String name = namer.getName(element); |
| 2299 code = extendWithMetadata(element, code); | 2324 code = extendWithMetadata(element, code); |
| 2300 emitStaticFunction(buffer, name, code); | 2325 emitStaticFunction(buffer, name, code); |
| 2301 String reflectionName = getReflectionName(element, name); | 2326 String reflectionName = getReflectionName(element, name); |
| 2302 if (reflectionName != null) { | 2327 if (reflectionName != null) { |
| 2303 buffer.write(',$n$n"+$reflectionName":${_}0'); | 2328 var reflectable = backend.isAccessibleByReflection(element) ? 1 : 0; |
| 2329 buffer.write(',$n$n"+$reflectionName":${_}$reflectable'); |
| 2304 } | 2330 } |
| 2305 jsAst.Expression bailoutCode = backend.generatedBailoutCode[element]; | 2331 jsAst.Expression bailoutCode = backend.generatedBailoutCode[element]; |
| 2306 if (bailoutCode != null) { | 2332 if (bailoutCode != null) { |
| 2307 pendingElementsWithBailouts.remove(element); | 2333 pendingElementsWithBailouts.remove(element); |
| 2308 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode); | 2334 emitStaticFunction(buffer, namer.getBailoutName(element), bailoutCode); |
| 2309 } | 2335 } |
| 2310 } | 2336 } |
| 2311 | 2337 |
| 2312 if (!pendingElementsWithBailouts.isEmpty) { | 2338 if (!pendingElementsWithBailouts.isEmpty) { |
| 2313 addComment('pendingElementsWithBailouts', eagerBuffer); | 2339 addComment('pendingElementsWithBailouts', eagerBuffer); |
| (...skipping 1709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4023 // TODO(ahe): Remove this when deferred loading is fully implemented. | 4049 // TODO(ahe): Remove this when deferred loading is fully implemented. |
| 4024 void warnNotImplemented(Element element, String message) { | 4050 void warnNotImplemented(Element element, String message) { |
| 4025 compiler.reportMessage(compiler.spanFromSpannable(element), | 4051 compiler.reportMessage(compiler.spanFromSpannable(element), |
| 4026 MessageKind.GENERIC.error({'text': message}), | 4052 MessageKind.GENERIC.error({'text': message}), |
| 4027 api.Diagnostic.WARNING); | 4053 api.Diagnostic.WARNING); |
| 4028 } | 4054 } |
| 4029 | 4055 |
| 4030 // TODO(ahe): This code should be integrated in finishClasses. | 4056 // TODO(ahe): This code should be integrated in finishClasses. |
| 4031 String getReflectionDataParser() { | 4057 String getReflectionDataParser() { |
| 4032 String metadataField = '"${namer.metadataField}"'; | 4058 String metadataField = '"${namer.metadataField}"'; |
| 4059 String reflectableField = namer.reflectableField; |
| 4033 return ''' | 4060 return ''' |
| 4034 (function (reflectionData) { | 4061 (function (reflectionData) { |
| 4035 ''' | 4062 ''' |
| 4036 // [map] returns an object literal that V8 shouldn't try to optimize with a | 4063 // [map] returns an object literal that V8 shouldn't try to optimize with a |
| 4037 // hidden class. This prevents a potential performance problem where V8 tries | 4064 // hidden class. This prevents a potential performance problem where V8 tries |
| 4038 // to build a hidden class for an object used as a hashMap. | 4065 // to build a hidden class for an object used as a hashMap. |
| 4039 ''' | 4066 ''' |
| 4040 function map(x){x={x:x};delete x.x;return x} | 4067 function map(x){x={x:x};delete x.x;return x} |
| 4041 if (!init.libraries) init.libraries = []; | 4068 if (!init.libraries) init.libraries = []; |
| 4042 if (!init.mangledNames) init.mangledNames = map(); | 4069 if (!init.mangledNames) init.mangledNames = map(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 4071 var functions = []; | 4098 var functions = []; |
| 4072 function processStatics(descriptor) { | 4099 function processStatics(descriptor) { |
| 4073 for (var property in descriptor) { | 4100 for (var property in descriptor) { |
| 4074 if (!hasOwnProperty.call(descriptor, property)) continue; | 4101 if (!hasOwnProperty.call(descriptor, property)) continue; |
| 4075 if (property === "") continue; | 4102 if (property === "") continue; |
| 4076 var element = descriptor[property]; | 4103 var element = descriptor[property]; |
| 4077 var firstChar = property.substring(0, 1); | 4104 var firstChar = property.substring(0, 1); |
| 4078 var previousProperty; | 4105 var previousProperty; |
| 4079 if (firstChar === "+") { | 4106 if (firstChar === "+") { |
| 4080 mangledGlobalNames[previousProperty] = property.substring(1); | 4107 mangledGlobalNames[previousProperty] = property.substring(1); |
| 4081 if (element && element.length) ''' // Breaking long line. | 4108 descriptor[previousProperty].''' // Break long line. |
| 4109 '''$reflectableField = (descriptor[property] == 1); |
| 4110 if (element && element.length) ''' // Break long line. |
| 4082 '''init.interfaces[previousProperty] = element; | 4111 '''init.interfaces[previousProperty] = element; |
| 4083 } else if (firstChar === "@") { | 4112 } else if (firstChar === "@") { |
| 4084 property = property.substring(1); | 4113 property = property.substring(1); |
| 4085 ${namer.CURRENT_ISOLATE}[property][$metadataField] = element; | 4114 ${namer.CURRENT_ISOLATE}[property][$metadataField] = element; |
| 4086 } else if (typeof element === "function") { | 4115 } else if (typeof element === "function") { |
| 4087 ${namer.CURRENT_ISOLATE}[previousProperty = property] = element; | 4116 ${namer.CURRENT_ISOLATE}[previousProperty = property] = element; |
| 4088 functions.push(property); | 4117 functions.push(property); |
| 4089 } else { | 4118 } else { |
| 4090 previousProperty = property; | 4119 previousProperty = property; |
| 4091 var newDesc = {}; | 4120 var newDesc = {}; |
| 4092 var previousProp; | 4121 var previousProp; |
| 4093 for (var prop in element) { | 4122 for (var prop in element) { |
| 4094 if (!hasOwnProperty.call(element, prop)) continue; | 4123 if (!hasOwnProperty.call(element, prop)) continue; |
| 4095 firstChar = prop.substring(0, 1); | 4124 firstChar = prop.substring(0, 1); |
| 4096 if (prop === "static") { | 4125 if (prop === "static") { |
| 4097 processStatics(init.statics[property] = element[prop]); | 4126 processStatics(init.statics[property] = element[prop]); |
| 4098 } else if (firstChar === "+") { | 4127 } else if (firstChar === "+") { |
| 4099 mangledNames[previousProp] = prop.substring(1); | 4128 mangledNames[previousProp] = prop.substring(1); |
| 4129 element[previousProp].''' // Break long line. |
| 4130 '''$reflectableField = (element[prop] == 1); |
| 4100 } else if (firstChar === "@" && prop !== "@") { | 4131 } else if (firstChar === "@" && prop !== "@") { |
| 4101 newDesc[prop.substring(1)][$metadataField] = element[prop]; | 4132 newDesc[prop.substring(1)][$metadataField] = element[prop]; |
| 4102 } else { | 4133 } else { |
| 4103 newDesc[previousProp = prop] = element[prop]; | 4134 newDesc[previousProp = prop] = element[prop]; |
| 4104 } | 4135 } |
| 4105 } | 4136 } |
| 4106 $classesCollector[property] = newDesc; | 4137 $classesCollector[property] = newDesc; |
| 4107 classes.push(property); | 4138 classes.push(property); |
| 4108 } | 4139 } |
| 4109 } | 4140 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4121 | 4152 |
| 4122 const String HOOKS_API_USAGE = """ | 4153 const String HOOKS_API_USAGE = """ |
| 4123 // The code supports the following hooks: | 4154 // The code supports the following hooks: |
| 4124 // dartPrint(message) - if this function is defined it is called | 4155 // dartPrint(message) - if this function is defined it is called |
| 4125 // instead of the Dart [print] method. | 4156 // instead of the Dart [print] method. |
| 4126 // dartMainRunner(main) - if this function is defined, the Dart [main] | 4157 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 4127 // method will not be invoked directly. | 4158 // method will not be invoked directly. |
| 4128 // Instead, a closure that will invoke [main] is | 4159 // Instead, a closure that will invoke [main] is |
| 4129 // passed to [dartMainRunner]. | 4160 // passed to [dartMainRunner]. |
| 4130 """; | 4161 """; |
| OLD | NEW |