| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 /** | 5 /** |
| 6 * Top level generator object for writing code and keeping track of | 6 * Top level generator object for writing code and keeping track of |
| 7 * dependencies. | 7 * dependencies. |
| 8 * | 8 * |
| 9 * Should have two compilation models, but only one implemented so far. | 9 * Should have two compilation models, but only one implemented so far. |
| 10 * | 10 * |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 /** | 22 /** |
| 23 * Whether the app has any static fields used. Note this could still be true | 23 * Whether the app has any static fields used. Note this could still be true |
| 24 * and [globals] be empty if no static field has a default initialization. | 24 * and [globals] be empty if no static field has a default initialization. |
| 25 */ | 25 */ |
| 26 bool hasStatics = false; | 26 bool hasStatics = false; |
| 27 | 27 |
| 28 /** Global const and static field initializations. */ | 28 /** Global const and static field initializations. */ |
| 29 Map<String, GlobalValue> globals; | 29 Map<String, GlobalValue> globals; |
| 30 CoreJs corejs; | 30 CoreJs corejs; |
| 31 bool _inheritsGenerated = false; | |
| 32 | 31 |
| 33 WorldGenerator(this.main, this.writer): globals = {}, corejs = new CoreJs(); | 32 WorldGenerator(this.main, this.writer) |
| 33 : globals = {}, corejs = new CoreJs(); |
| 34 | 34 |
| 35 run() { | 35 run() { |
| 36 var metaGen = new MethodGenerator(main, null); | 36 var metaGen = new MethodGenerator(main, null); |
| 37 var mainTarget = new Value.type(main.declaringType, main.span); | 37 var mainTarget = new Value.type(main.declaringType, main.span); |
| 38 var mainCall = main.invoke(metaGen, null, mainTarget, Arguments.EMPTY); | 38 var mainCall = main.invoke(metaGen, null, mainTarget, Arguments.EMPTY); |
| 39 main.declaringType.markUsed(); | 39 main.declaringType.markUsed(); |
| 40 | 40 |
| 41 if (options.compileAll) { | 41 if (options.compileAll) { |
| 42 markLibraryUsed(world.corelib); | 42 markLibraryUsed(world.corelib); |
| 43 markLibraryUsed(main.declaringType.library); | 43 markLibraryUsed(main.declaringType.library); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 69 } | 69 } |
| 70 | 70 |
| 71 writeTypes(world.coreimpl); | 71 writeTypes(world.coreimpl); |
| 72 writeTypes(world.corelib); | 72 writeTypes(world.corelib); |
| 73 | 73 |
| 74 // Write the main library. This will cause all libraries to be written in | 74 // Write the main library. This will cause all libraries to be written in |
| 75 // the topographic sort order. | 75 // the topographic sort order. |
| 76 writeTypes(main.declaringType.library); | 76 writeTypes(main.declaringType.library); |
| 77 | 77 |
| 78 // Write out any inherited concrete members. | 78 // Write out any inherited concrete members. |
| 79 // TODO(jmesserly): this won't need to come last once we are sorting types |
| 80 // correctly. |
| 79 if (_mixins != null) writer.write(_mixins.text); | 81 if (_mixins != null) writer.write(_mixins.text); |
| 80 | 82 |
| 81 writeGlobals(); | 83 writeGlobals(); |
| 82 writer.writeln('${mainCall.code};'); | 84 writer.writeln('${mainCall.code};'); |
| 83 } | 85 } |
| 84 | 86 |
| 85 void markLibraryUsed(Library l) { | 87 void markLibraryUsed(Library l) { |
| 86 if (l.isMarked) return; | 88 if (l.isMarked) return; |
| 87 l.isMarked = true; | 89 l.isMarked = true; |
| 88 | 90 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 corejs.generate(writer); | 155 corejs.generate(writer); |
| 154 } | 156 } |
| 155 for (var file in lib.natives) { | 157 for (var file in lib.natives) { |
| 156 var filename = basename(file.filename); | 158 var filename = basename(file.filename); |
| 157 writer.comment('// ********** Natives $filename **************'); | 159 writer.comment('// ********** Natives $filename **************'); |
| 158 writer.writeln(file.text); | 160 writer.writeln(file.text); |
| 159 } | 161 } |
| 160 lib.topType.markUsed(); // TODO(jimhug): EGREGIOUS HACK | 162 lib.topType.markUsed(); // TODO(jimhug): EGREGIOUS HACK |
| 161 | 163 |
| 162 for (var type in _orderValues(lib.types)) { | 164 for (var type in _orderValues(lib.types)) { |
| 163 if (type.isUsed && type.isClass) { | 165 // TODO(jmesserly): we can't accurately track if DOM types are |
| 166 // created or not, so we need to prepare to handle them. |
| 167 if ((type.isUsed || type.isHiddenNativeType) && type.isClass) { |
| 164 writeType(type); | 168 writeType(type); |
| 165 | 169 |
| 166 if (type.isGeneric) { | 170 if (type.isGeneric) { |
| 167 for (var ct in _orderValues(type._concreteTypes)) { | 171 for (var ct in _orderValues(type._concreteTypes)) { |
| 168 writeType(ct); | 172 writeType(ct); |
| 169 } | 173 } |
| 170 } | 174 } |
| 171 } | 175 } else if (type.isFunction && type.varStubs.length > 0) { |
| 172 if (type.isFunction && type.varStubs != null) { | 176 // Emit stubs on "Function" or hidden types if needed |
| 173 // Emit stubs on "Function" if needed | |
| 174 writer.comment('// ********** Code for ${type.jsname} **************'); | 177 writer.comment('// ********** Code for ${type.jsname} **************'); |
| 175 _writeDynamicStubs(type); | 178 _writeDynamicStubs(type); |
| 176 } | 179 } |
| 177 // Type check functions for builtin JS types | 180 // Type check functions for builtin JS types |
| 178 if (type.typeCheckCode != null) { | 181 if (type.typeCheckCode != null) { |
| 179 writer.writeln(type.typeCheckCode); | 182 writer.writeln(type.typeCheckCode); |
| 180 } | 183 } |
| 181 } | 184 } |
| 182 } | 185 } |
| 183 | 186 |
| 184 genMethod(Member meth, [MethodGenerator enclosingMethod=null]) { | 187 genMethod(Member meth, [MethodGenerator enclosingMethod=null]) { |
| 185 if (!meth.isGenerated && !meth.isAbstract && meth.definition != null) { | 188 if (!meth.isGenerated && !meth.isAbstract && meth.definition != null) { |
| 186 new MethodGenerator(meth, enclosingMethod).run(); | 189 new MethodGenerator(meth, enclosingMethod).run(); |
| 187 } | 190 } |
| 188 } | 191 } |
| 189 | 192 |
| 193 String _prototypeOf(Type type, String name) { |
| 194 if (type.isHiddenNativeType) { |
| 195 corejs.ensureDynamicProto(); |
| 196 return '\$dynamic("$name").${type.jsname}'; |
| 197 } else { |
| 198 return '${type.jsname}.prototype.$name'; |
| 199 } |
| 200 } |
| 201 |
| 190 _maybeIsTest(Type onType, Type checkType) { | 202 _maybeIsTest(Type onType, Type checkType) { |
| 191 if (!checkType.isTested) return; | 203 bool isSubtype = onType.isSubtypeOf(checkType); |
| 192 | 204 if (checkType.isTested) { |
| 193 var value = 'false'; | 205 // TODO(jmesserly): cache these functions? they just return true or false. |
| 194 if (onType.isSubtypeOf(checkType)) { | 206 writer.writeln(_prototypeOf(onType, 'is\$${checkType.jsname}') |
| 195 value = 'function(){return this;}'; | 207 + ' = function(){return $isSubtype};'); |
| 196 } | 208 } |
| 197 | 209 |
| 198 writer.writeln('${onType.jsname}.prototype.is\$${checkType.jsname} = ' | 210 if (checkType.isChecked) { |
| 199 + '$value;'); | 211 String body = 'return this'; |
| 212 String checkName = 'assert\$${checkType.jsname}'; |
| 213 if (!isSubtype) { |
| 214 // Get the code to throw a TypeError. |
| 215 // TODO(jmesserly): it'd be nice not to duplicate this code, and instead |
| 216 // be able to refer to the JS function. |
| 217 body = world.objectType.varStubs[checkName].body; |
| 218 } |
| 219 writer.writeln(_prototypeOf(onType, checkName) + ' = function(){$body};'); |
| 220 } |
| 200 } | 221 } |
| 201 | 222 |
| 202 writeType(Type type) { | 223 writeType(Type type) { |
| 203 // TODO(jimhug): Workaround for problems with reified generic Array. | 224 // TODO(jimhug): Workaround for problems with reified generic Array. |
| 204 if (type.name != null && type is ConcreteType && | 225 if (type.name != null && type is ConcreteType && |
| 205 type.library == world.coreimpl && | 226 type.library == world.coreimpl && |
| 206 type.name.startsWith('ListFactory')) { | 227 type.name.startsWith('ListFactory')) { |
| 207 writer.writeln('${type.jsname} = ${type.genericType.jsname};'); | 228 writer.writeln('${type.jsname} = ${type.genericType.jsname};'); |
| 208 return; | 229 return; |
| 209 } | 230 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 240 for (var c in type.constructors.getValues()) { | 261 for (var c in type.constructors.getValues()) { |
| 241 if (c.generator != null && c != standardConstructor) { | 262 if (c.generator != null && c != standardConstructor) { |
| 242 c.generator.writeDefinition(writer, null); | 263 c.generator.writeDefinition(writer, null); |
| 243 } | 264 } |
| 244 } | 265 } |
| 245 } | 266 } |
| 246 | 267 |
| 247 if (!type.isTop) { | 268 if (!type.isTop) { |
| 248 if (type is ConcreteType) { | 269 if (type is ConcreteType) { |
| 249 ConcreteType c = type; | 270 ConcreteType c = type; |
| 250 _ensureInheritsHelper(); | 271 corejs.ensureInheritsHelper(); |
| 251 writer.writeln('\$inherits(${c.jsname}, ${c.genericType.jsname});'); | 272 writer.writeln('\$inherits(${c.jsname}, ${c.genericType.jsname});'); |
| 252 | 273 |
| 253 // Mixin members from concrete specializations of base types too. | 274 // Mixin members from concrete specializations of base types too. |
| 254 // TODO(jmesserly): emit this sooner instead of at the end. | 275 // TODO(jmesserly): emit this sooner instead of at the end. |
| 255 // But it needs to come after we've emitted both types. | 276 // But it needs to come after we've emitted both types. |
| 256 // TODO(jmesserly): HACK: using _parent instead of parent so we don't | 277 // TODO(jmesserly): HACK: using _parent instead of parent so we don't |
| 257 // try to inherit things that we didn't actually use. | 278 // try to inherit things that we didn't actually use. |
| 258 for (var p = c._parent; p is ConcreteType; p = p._parent) { | 279 for (var p = c._parent; p is ConcreteType; p = p._parent) { |
| 259 _ensureInheritMembersHelper(); | 280 _ensureInheritMembersHelper(); |
| 260 _mixins.writeln('\$inheritsMembers(${c.jsname}, ${p.jsname});'); | 281 _mixins.writeln('\$inheritsMembers(${c.jsname}, ${p.jsname});'); |
| 261 } | 282 } |
| 262 } else if (!type.isNative) { | 283 } else if (!type.isNative) { |
| 263 if (type.parent != null && !type.parent.isObject) { | 284 if (type.parent != null && !type.parent.isObject) { |
| 264 _ensureInheritsHelper(); | 285 corejs.ensureInheritsHelper(); |
| 265 writer.writeln('\$inherits(${type.jsname}, ${type.parent.jsname});'); | 286 writer.writeln('\$inherits(${type.jsname}, ${type.parent.jsname});'); |
| 266 } | 287 } |
| 267 } | 288 } |
| 268 } | 289 } |
| 269 | 290 |
| 270 // Concrete types (like List<String>) will have this already defined on | 291 // Concrete types (like List<String>) will have this already defined on |
| 271 // their prototype from the generic type (like List) | 292 // their prototype from the generic type (like List) |
| 272 if (type is! ConcreteType) { | 293 if (type is! ConcreteType) { |
| 273 _maybeIsTest(type, type); | 294 _maybeIsTest(type, type); |
| 274 } | 295 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 | 334 |
| 314 if (member.isMethod) { | 335 if (member.isMethod) { |
| 315 _writeMethod(member); | 336 _writeMethod(member); |
| 316 } | 337 } |
| 317 } | 338 } |
| 318 | 339 |
| 319 _writeDynamicStubs(type); | 340 _writeDynamicStubs(type); |
| 320 } | 341 } |
| 321 | 342 |
| 322 /** | 343 /** |
| 323 * Generates the $inherits function when it's first used. Unlike some of the | |
| 324 * other helpers in [CoreJS], we don't notice that we need this one until | |
| 325 * we're generating types. | |
| 326 */ | |
| 327 _ensureInheritsHelper() { | |
| 328 if (_inheritsGenerated) return; | |
| 329 | |
| 330 _inheritsGenerated = true; | |
| 331 writer.writeln(@""" | |
| 332 /** Implements extends for Dart classes on JavaScript prototypes. */ | |
| 333 function $inherits(child, parent) { | |
| 334 if (child.prototype.__proto__) { | |
| 335 child.prototype.__proto__ = parent.prototype; | |
| 336 } else { | |
| 337 function tmp() {}; | |
| 338 tmp.prototype = parent.prototype; | |
| 339 child.prototype = new tmp(); | |
| 340 child.prototype.constructor = child; | |
| 341 } | |
| 342 }"""); | |
| 343 } | |
| 344 | |
| 345 /** | |
| 346 * Generates the $inheritsMembers function when it's first used. | 344 * Generates the $inheritsMembers function when it's first used. |
| 347 * This is used to mix in specialized generic members from the base class. | 345 * This is used to mix in specialized generic members from the base class. |
| 348 */ | 346 */ |
| 349 _ensureInheritMembersHelper() { | 347 _ensureInheritMembersHelper() { |
| 350 if (_mixins != null) return; | 348 if (_mixins != null) return; |
| 351 _mixins = new CodeWriter(); | 349 _mixins = new CodeWriter(); |
| 352 _mixins.comment('// ********** Generic Type Inheritance **************'); | 350 _mixins.comment('// ********** Generic Type Inheritance **************'); |
| 353 _mixins.writeln(@""" | 351 _mixins.writeln(@""" |
| 354 /** Implements extends for generic types. */ | 352 /** Implements extends for generic types. */ |
| 355 function $inheritsMembers(child, parent) { | 353 function $inheritsMembers(child, parent) { |
| 356 child = child.prototype; | 354 child = child.prototype; |
| 357 parent = parent.prototype; | 355 parent = parent.prototype; |
| 358 Object.getOwnPropertyNames(parent).forEach(function(name) { | 356 Object.getOwnPropertyNames(parent).forEach(function(name) { |
| 359 if (typeof(child[name]) == 'undefined') child[name] = parent[name]; | 357 if (typeof(child[name]) == 'undefined') child[name] = parent[name]; |
| 360 }); | 358 }); |
| 361 }"""); | 359 }"""); |
| 362 } | 360 } |
| 363 | 361 |
| 364 _writeDynamicStubs(Type type) { | 362 _writeDynamicStubs(Type type) { |
| 365 if (type.varStubs != null) { | 363 for (var stub in orderValuesByKeys(type.varStubs)) { |
| 366 for (var stub in orderValuesByKeys(type.varStubs)) { | 364 stub.generate(writer); |
| 367 stub.generate(writer); | |
| 368 } | |
| 369 } | 365 } |
| 370 } | 366 } |
| 371 | 367 |
| 372 _writeStaticField(FieldMember field) { | 368 _writeStaticField(FieldMember field) { |
| 373 // Final static fields must be constants which will be folded and inlined. | 369 // Final static fields must be constants which will be folded and inlined. |
| 374 if (field.isFinal) return; | 370 if (field.isFinal) return; |
| 375 | 371 |
| 376 var fullname = "${field.declaringType.jsname}.${field.jsname}"; | 372 var fullname = "${field.declaringType.jsname}.${field.jsname}"; |
| 377 if (globals.containsKey(fullname)) { | 373 if (globals.containsKey(fullname)) { |
| 378 var value = globals[fullname]; | 374 var value = globals[fullname]; |
| 379 if (field.declaringType.isTop && !field.isNative) { | 375 if (field.declaringType.isTop && !field.isNative) { |
| 380 writer.writeln('\$globals.${field.jsname} = ${value.exp.code};'); | 376 writer.writeln('\$globals.${field.jsname} = ${value.exp.code};'); |
| 381 } else { | 377 } else { |
| 382 writer.writeln('\$globals.${field.declaringType.jsname}_${field.jsname}' | 378 writer.writeln('\$globals.${field.declaringType.jsname}_${field.jsname}' |
| 383 + ' = ${value.exp.code};'); | 379 + ' = ${value.exp.code};'); |
| 384 } | 380 } |
| 385 } | 381 } |
| 386 // No need to write code for a static class field with no initial value. | 382 // No need to write code for a static class field with no initial value. |
| 387 } | 383 } |
| 388 | 384 |
| 389 _writeField(FieldMember field) { | 385 _writeField(FieldMember field) { |
| 390 // Generate declarations for static top-level fields with no value. | 386 // Generate declarations for static top-level fields with no value. |
| 391 if (field.declaringType.isTop && !field.isNative && field.value == null) { | 387 if (field.declaringType.isTop && !field.isNative && field.value == null) { |
| 392 writer.writeln('var ${field.jsname};'); | 388 writer.writeln('var ${field.jsname};'); |
| 393 } | 389 } |
| 394 | 390 |
| 395 // generate code for instance fields | 391 // generate code for instance fields |
| 396 if (field._providePropertySyntax) { | 392 if (field._providePropertySyntax) { |
| 397 writer.writeln( | 393 writer.writeln(_prototypeOf(field.declaringType, 'get\$${field.jsname}') |
| 398 '${field.declaringType.jsname}.prototype.get\$${field.jsname} = ' + | 394 + ' = function() { return this.${field.jsname}; };'); |
| 399 'function() { return this.${field.jsname}; };'); | |
| 400 if (!field.isFinal) { | 395 if (!field.isFinal) { |
| 401 writer.writeln( | 396 writer.writeln(_prototypeOf(field.declaringType, 'set\$${field.jsname}') |
| 402 '${field.declaringType.jsname}.prototype.set\$${field.jsname} = ' + | 397 + ' = function(value) { return this.${field.jsname} = value; };'); |
| 403 'function(value) { return this.${field.jsname} = value; };'); | |
| 404 } | 398 } |
| 405 } | 399 } |
| 406 | 400 |
| 407 // TODO(jimhug): Currently choose not to initialize fields on objects, but | 401 // TODO(jimhug): Currently choose not to initialize fields on objects, but |
| 408 // instead to rely on uninitialized === null in our generated code. | 402 // instead to rely on uninitialized === null in our generated code. |
| 409 // Investigate the perf pros and cons of this. | 403 // Investigate the perf pros and cons of this. |
| 410 } | 404 } |
| 411 | 405 |
| 412 _writeProperty(PropertyMember property) { | 406 _writeProperty(PropertyMember property) { |
| 413 if (property.getter != null) _writeMethod(property.getter); | 407 if (property.getter != null) _writeMethod(property.getter); |
| 414 if (property.setter != null) _writeMethod(property.setter); | 408 if (property.setter != null) _writeMethod(property.setter); |
| 415 | 409 |
| 410 // TODO(jmesserly): make sure we don't do this on hidden native types! |
| 416 if (property._provideFieldSyntax) { | 411 if (property._provideFieldSyntax) { |
| 417 writer.enterBlock('Object.defineProperty(' + | 412 writer.enterBlock('Object.defineProperty(' + |
| 418 '${property.declaringType.jsname}.prototype, "${property.jsname}", {'); | 413 '${property.declaringType.jsname}.prototype, "${property.jsname}", {'); |
| 419 if (property.getter != null) { | 414 if (property.getter != null) { |
| 420 writer.write( | 415 writer.write( |
| 421 'get: ${property.declaringType.jsname}.prototype.${property.getter.jsn
ame}'); | 416 'get: ${property.declaringType.jsname}.prototype.${property.getter.jsn
ame}'); |
| 422 // The shenanigan below is to make IE happy -- IE 9 doesn't like a | 417 // The shenanigan below is to make IE happy -- IE 9 doesn't like a |
| 423 // trailing comma on the last element in a list. | 418 // trailing comma on the last element in a list. |
| 424 writer.writeln(property.setter == null ? '' : ','); | 419 writer.writeln(property.setter == null ? '' : ','); |
| 425 } | 420 } |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 988 initializedFields.add(f.name); | 983 initializedFields.add(f.name); |
| 989 writer.writeln('this.${f.jsname} = ${visitValue(init.y).code};'); | 984 writer.writeln('this.${f.jsname} = ${visitValue(init.y).code};'); |
| 990 } else { | 985 } else { |
| 991 world.error('invalid initializer', init.span); | 986 world.error('invalid initializer', init.span); |
| 992 } | 987 } |
| 993 } | 988 } |
| 994 } | 989 } |
| 995 writer.comment('// Initializers done'); | 990 writer.comment('// Initializers done'); |
| 996 } | 991 } |
| 997 | 992 |
| 998 if (method.isConstructor && initializerCall == null) { | 993 if (method.isConstructor && initializerCall == null && !method.isNative) { |
| 999 var parentType = method.declaringType.parent; | 994 var parentType = method.declaringType.parent; |
| 1000 if (parentType != null && !parentType.isObject) { | 995 if (parentType != null && !parentType.isObject) { |
| 1001 // TODO(jmesserly): we could omit this if all supertypes are using | 996 // TODO(jmesserly): we could omit this if all supertypes are using |
| 1002 // default constructors. | 997 // default constructors. |
| 1003 initializerCall = new CallExpression( | 998 initializerCall = new CallExpression( |
| 1004 new SuperExpression(method.span), [], method.span); | 999 new SuperExpression(method.span), [], method.span); |
| 1005 } | 1000 } |
| 1006 } | 1001 } |
| 1007 | 1002 |
| 1008 if (initializerCall != null) { | 1003 if (initializerCall != null) { |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1290 } | 1285 } |
| 1291 } | 1286 } |
| 1292 return true; | 1287 return true; |
| 1293 } | 1288 } |
| 1294 | 1289 |
| 1295 bool visitAssertStatement(AssertStatement node) { | 1290 bool visitAssertStatement(AssertStatement node) { |
| 1296 // be sure to walk test for static checking even is asserts disabled | 1291 // be sure to walk test for static checking even is asserts disabled |
| 1297 var test = visitValue(node.test); // TODO(jimhug): check bool or callable. | 1292 var test = visitValue(node.test); // TODO(jimhug): check bool or callable. |
| 1298 if (options.enableAsserts) { | 1293 if (options.enableAsserts) { |
| 1299 var err = world.corelib.types['AssertError']; | 1294 var err = world.corelib.types['AssertError']; |
| 1300 world.gen.genMethod(err.getConstructor('')); | 1295 world.gen.genMethod(err.getConstructor('_internal')); |
| 1301 world.gen.genMethod(err.members['toString']); | 1296 world.gen.genMethod(err.members['toString']); |
| 1302 var span = node.test.span; | 1297 var span = node.test.span; |
| 1303 | 1298 |
| 1304 // TODO(jmesserly): do we need to include path/line/column here? | 1299 // TODO(jmesserly): do we need to include path/line/column here? |
| 1305 // It should be captured in the stack trace. | 1300 // It should be captured in the stack trace. |
| 1306 var line = span.file.getLine(span.start); | 1301 var line = span.file.getLine(span.start); |
| 1307 var column = span.file.getColumn(line, span.start); | 1302 var column = span.file.getColumn(line, span.start); |
| 1308 writer.writeln('\$assert(${test.code}, "${_escapeString(span.text)}",' + | 1303 writer.writeln('\$assert(${test.code}, "${_escapeString(span.text)}",' + |
| 1309 ' "${basename(span.file.filename)}", ${line + 1}, ${column + 1});'); | 1304 ' "${basename(span.file.filename)}", ${line + 1}, ${column + 1});'); |
| 1310 world.gen.corejs.useAssert = true; | 1305 world.gen.corejs.useAssert = true; |
| (...skipping 1117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2428 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false)); | 2423 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false)); |
| 2429 } | 2424 } |
| 2430 for (int i = bareCount; i < length; i++) { | 2425 for (int i = bareCount; i < length; i++) { |
| 2431 var name = getName(i); | 2426 var name = getName(i); |
| 2432 if (name == null) name = '\$$i'; | 2427 if (name == null) name = '\$$i'; |
| 2433 result.add(new Value(world.varType, name, null, /*needsTemp:*/false)); | 2428 result.add(new Value(world.varType, name, null, /*needsTemp:*/false)); |
| 2434 } | 2429 } |
| 2435 return new Arguments(nodes, result); | 2430 return new Arguments(nodes, result); |
| 2436 } | 2431 } |
| 2437 } | 2432 } |
| OLD | NEW |