Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 /// This class should morph into something that makes it easy to build | 7 /// This class should morph into something that makes it easy to build |
| 8 /// JavaScript representations of libraries, class-sides, and instance-sides. | 8 /// JavaScript representations of libraries, class-sides, and instance-sides. |
| 9 /// Initially, it is just a placeholder for code that is moved from | 9 /// Initially, it is just a placeholder for code that is moved from |
| 10 /// [CodeEmitterTask]. | 10 /// [CodeEmitterTask]. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 64 new List<jsAst.Parameter>(selector.argumentCount + extraArgumentCount); | 64 new List<jsAst.Parameter>(selector.argumentCount + extraArgumentCount); |
| 65 // The arguments that will be passed to the real method. | 65 // The arguments that will be passed to the real method. |
| 66 List<jsAst.Expression> argumentsBuffer = | 66 List<jsAst.Expression> argumentsBuffer = |
| 67 new List<jsAst.Expression>( | 67 new List<jsAst.Expression>( |
| 68 parameters.parameterCount + extraArgumentCount); | 68 parameters.parameterCount + extraArgumentCount); |
| 69 | 69 |
| 70 int count = 0; | 70 int count = 0; |
| 71 if (isInterceptedMethod) { | 71 if (isInterceptedMethod) { |
| 72 count++; | 72 count++; |
| 73 parametersBuffer[0] = new jsAst.Parameter(receiverArgumentName); | 73 parametersBuffer[0] = new jsAst.Parameter(receiverArgumentName); |
| 74 argumentsBuffer[0] = js(receiverArgumentName); | 74 argumentsBuffer[0] = js('#', receiverArgumentName); |
| 75 task.interceptorEmitter.interceptorInvocationNames.add(invocationName); | 75 task.interceptorEmitter.interceptorInvocationNames.add(invocationName); |
| 76 } | 76 } |
| 77 | 77 |
| 78 int optionalParameterStart = positionalArgumentCount + extraArgumentCount; | 78 int optionalParameterStart = positionalArgumentCount + extraArgumentCount; |
| 79 // Includes extra receiver argument when using interceptor convention | 79 // Includes extra receiver argument when using interceptor convention |
| 80 int indexOfLastOptionalArgumentInParameters = optionalParameterStart - 1; | 80 int indexOfLastOptionalArgumentInParameters = optionalParameterStart - 1; |
| 81 | 81 |
| 82 TreeElements elements = | 82 TreeElements elements = |
| 83 compiler.enqueuer.resolution.getCachedElements(member); | 83 compiler.enqueuer.resolution.getCachedElements(member); |
| 84 | 84 |
| 85 int parameterIndex = 0; | 85 int parameterIndex = 0; |
| 86 parameters.orderedForEachParameter((Element element) { | 86 parameters.orderedForEachParameter((Element element) { |
| 87 String jsName = backend.namer.safeName(element.name); | 87 String jsName = backend.namer.safeName(element.name); |
| 88 assert(jsName != receiverArgumentName); | 88 assert(jsName != receiverArgumentName); |
| 89 if (count < optionalParameterStart) { | 89 if (count < optionalParameterStart) { |
| 90 parametersBuffer[count] = new jsAst.Parameter(jsName); | 90 parametersBuffer[count] = new jsAst.Parameter(jsName); |
| 91 argumentsBuffer[count] = js(jsName); | 91 argumentsBuffer[count] = js('#', jsName); |
| 92 } else { | 92 } else { |
| 93 int index = names.indexOf(element.name); | 93 int index = names.indexOf(element.name); |
| 94 if (index != -1) { | 94 if (index != -1) { |
| 95 indexOfLastOptionalArgumentInParameters = count; | 95 indexOfLastOptionalArgumentInParameters = count; |
| 96 // The order of the named arguments is not the same as the | 96 // The order of the named arguments is not the same as the |
| 97 // one in the real method (which is in Dart source order). | 97 // one in the real method (which is in Dart source order). |
| 98 argumentsBuffer[count] = js(jsName); | 98 argumentsBuffer[count] = js('#', jsName); |
| 99 parametersBuffer[optionalParameterStart + index] = | 99 parametersBuffer[optionalParameterStart + index] = |
| 100 new jsAst.Parameter(jsName); | 100 new jsAst.Parameter(jsName); |
| 101 } else { | 101 } else { |
| 102 Constant value = handler.getConstantForVariable(element); | 102 Constant value = handler.getConstantForVariable(element); |
| 103 if (value == null) { | 103 if (value == null) { |
| 104 argumentsBuffer[count] = task.constantReference(new NullConstant()); | 104 argumentsBuffer[count] = task.constantReference(new NullConstant()); |
| 105 } else { | 105 } else { |
| 106 if (!value.isNull) { | 106 if (!value.isNull) { |
| 107 // If the value is the null constant, we should not pass it | 107 // If the value is the null constant, we should not pass it |
| 108 // down to the native method. | 108 // down to the native method. |
| 109 indexOfLastOptionalArgumentInParameters = count; | 109 indexOfLastOptionalArgumentInParameters = count; |
| 110 } | 110 } |
| 111 argumentsBuffer[count] = task.constantReference(value); | 111 argumentsBuffer[count] = task.constantReference(value); |
| 112 } | 112 } |
| 113 } | 113 } |
| 114 } | 114 } |
| 115 count++; | 115 count++; |
| 116 }); | 116 }); |
| 117 | 117 |
| 118 List body; | 118 var body; // List or jsAst.Statement. |
| 119 if (member.hasFixedBackendName()) { | 119 if (member.hasFixedBackendName()) { |
| 120 body = task.nativeEmitter.generateParameterStubStatements( | 120 body = task.nativeEmitter.generateParameterStubStatements( |
| 121 member, isInterceptedMethod, invocationName, | 121 member, isInterceptedMethod, invocationName, |
| 122 parametersBuffer, argumentsBuffer, | 122 parametersBuffer, argumentsBuffer, |
| 123 indexOfLastOptionalArgumentInParameters); | 123 indexOfLastOptionalArgumentInParameters); |
| 124 } else if (member.isInstanceMember()) { | 124 } else if (member.isInstanceMember()) { |
| 125 if (needsSuperGetter(member)) { | 125 if (needsSuperGetter(member)) { |
| 126 ClassElement superClass = member.getEnclosingClass(); | 126 ClassElement superClass = member.getEnclosingClass(); |
| 127 String methodName = namer.getNameOfInstanceMember(member); | 127 String methodName = namer.getNameOfInstanceMember(member); |
| 128 // When redirecting, we must ensure that we don't end up in a subclass. | 128 // When redirecting, we must ensure that we don't end up in a subclass. |
| 129 // We thus can't just invoke `this.foo$1.call(filledInArguments)`. | 129 // We thus can't just invoke `this.foo$1.call(filledInArguments)`. |
| 130 // Instead we need to call the statically resolved target. | 130 // Instead we need to call the statically resolved target. |
| 131 // `<class>.prototype.bar$1.call(this, argument0, ...)`. | 131 // `<class>.prototype.bar$1.call(this, argument0, ...)`. |
| 132 body = [js.return_( | 132 body = js.statement( |
| 133 backend.namer.elementAccess(superClass)['prototype'][methodName] | 133 'return #.prototype.#.call(this, #);', |
| 134 ["call"](["this"]..addAll(argumentsBuffer)))]; | 134 [backend.namer.elementAccess(superClass), methodName, |
| 135 argumentsBuffer]); | |
| 135 } else { | 136 } else { |
| 136 body = [js.return_( | 137 body = js.statement( |
| 137 js('this') | 138 'return this.#(#);', |
| 138 [namer.getNameOfInstanceMember(member)](argumentsBuffer))]; | 139 [namer.getNameOfInstanceMember(member), argumentsBuffer]); |
| 139 } | 140 } |
| 140 } else { | 141 } else { |
| 141 body = [js.return_(namer.elementAccess(member)(argumentsBuffer))]; | 142 body = js.statement('return #(#)', |
| 143 [namer.elementAccess(member), argumentsBuffer]); | |
| 142 } | 144 } |
| 143 | 145 |
| 144 jsAst.Fun function = js.fun(parametersBuffer, body); | 146 jsAst.Fun function = js('function(#) { #; }', [parametersBuffer, body]); |
| 145 | 147 |
| 146 addStub(selector, function); | 148 addStub(selector, function); |
| 147 } | 149 } |
| 148 | 150 |
| 149 void addParameterStubs(FunctionElement member, AddStubFunction defineStub, | 151 void addParameterStubs(FunctionElement member, AddStubFunction defineStub, |
| 150 [bool canTearOff = false]) { | 152 [bool canTearOff = false]) { |
| 151 if (member.enclosingElement.isClosure()) { | 153 if (member.enclosingElement.isClosure()) { |
| 152 ClosureClassElement cls = member.enclosingElement; | 154 ClosureClassElement cls = member.enclosingElement; |
| 153 if (cls.supertype.element == compiler.boundClosureClass) { | 155 if (cls.supertype.element == compiler.boundClosureClass) { |
| 154 compiler.internalError(cls.methodElement, 'Bound closure1.'); | 156 compiler.internalError(cls.methodElement, 'Bound closure1.'); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 260 backend.isInterceptorClass(member.getEnclosingClass()); | 262 backend.isInterceptorClass(member.getEnclosingClass()); |
| 261 | 263 |
| 262 const String receiverArgumentName = r'$receiver'; | 264 const String receiverArgumentName = r'$receiver'; |
| 263 | 265 |
| 264 jsAst.Expression buildGetter() { | 266 jsAst.Expression buildGetter() { |
| 265 jsAst.Expression receiver = | 267 jsAst.Expression receiver = |
| 266 js(isInterceptorClass ? receiverArgumentName : 'this'); | 268 js(isInterceptorClass ? receiverArgumentName : 'this'); |
| 267 if (member.isGetter()) { | 269 if (member.isGetter()) { |
| 268 String getterName = namer.getterName(member); | 270 String getterName = namer.getterName(member); |
| 269 if (isInterceptedMethod) { | 271 if (isInterceptedMethod) { |
| 270 return js('this')[getterName](<jsAst.Expression>[receiver]); | 272 //return js('this')[getterName](<jsAst.Expression>[receiver]); |
|
floitsch
2014/04/22 16:11:18
dead code.
sra1
2014/04/23 02:33:50
Done.
| |
| 273 return js('this.#(#)', [getterName, receiver]); | |
| 271 } | 274 } |
| 272 return receiver[getterName](<jsAst.Expression>[]); | 275 //return receiver[getterName](<jsAst.Expression>[]); |
|
floitsch
2014/04/22 16:11:18
ditto.
sra1
2014/04/23 02:33:50
Done.
| |
| 276 return js('#.#()', [receiver, getterName]); | |
| 273 } else { | 277 } else { |
| 274 String fieldName = namer.instanceFieldPropertyName(member); | 278 String fieldName = namer.instanceFieldPropertyName(member); |
| 275 return receiver[fieldName]; | 279 return js('#.#', [receiver, fieldName]); |
| 276 } | 280 } |
| 277 } | 281 } |
| 278 | 282 |
| 279 // Two selectors may match but differ only in type. To avoid generating | 283 // Two selectors may match but differ only in type. To avoid generating |
| 280 // identical stubs for each we track untyped selectors which already have | 284 // identical stubs for each we track untyped selectors which already have |
| 281 // stubs. | 285 // stubs. |
| 282 Set<Selector> generatedSelectors = new Set<Selector>(); | 286 Set<Selector> generatedSelectors = new Set<Selector>(); |
| 283 for (Selector selector in selectors) { | 287 for (Selector selector in selectors) { |
| 284 if (selector.applies(member, compiler)) { | 288 if (selector.applies(member, compiler)) { |
| 285 selector = selector.asUntyped; | 289 selector = selector.asUntyped; |
| 286 if (generatedSelectors.contains(selector)) continue; | 290 if (generatedSelectors.contains(selector)) continue; |
| 287 generatedSelectors.add(selector); | 291 generatedSelectors.add(selector); |
| 288 | 292 |
| 289 String invocationName = namer.invocationName(selector); | 293 String invocationName = namer.invocationName(selector); |
| 290 Selector callSelector = new Selector.callClosureFrom(selector); | 294 Selector callSelector = new Selector.callClosureFrom(selector); |
| 291 String closureCallName = namer.invocationName(callSelector); | 295 String closureCallName = namer.invocationName(callSelector); |
| 292 | 296 |
| 293 List<jsAst.Parameter> parameters = <jsAst.Parameter>[]; | 297 List<jsAst.Parameter> parameters = <jsAst.Parameter>[]; |
| 294 List<jsAst.Expression> arguments = <jsAst.Expression>[]; | 298 List<jsAst.Expression> arguments = <jsAst.Expression>[]; |
| 295 if (isInterceptedMethod) { | 299 if (isInterceptedMethod) { |
| 296 parameters.add(new jsAst.Parameter(receiverArgumentName)); | 300 parameters.add(new jsAst.Parameter(receiverArgumentName)); |
| 297 } | 301 } |
| 298 | 302 |
| 299 for (int i = 0; i < selector.argumentCount; i++) { | 303 for (int i = 0; i < selector.argumentCount; i++) { |
| 300 String name = 'arg$i'; | 304 String name = 'arg$i'; |
| 301 parameters.add(new jsAst.Parameter(name)); | 305 parameters.add(new jsAst.Parameter(name)); |
| 302 arguments.add(js(name)); | 306 arguments.add(js('#', name)); |
| 303 } | 307 } |
| 304 | 308 |
| 305 jsAst.Fun function = js.fun( | 309 jsAst.Fun function = js( |
| 306 parameters, | 310 'function(#) { return #.#(#); }', |
| 307 js.return_(buildGetter()[closureCallName](arguments))); | 311 [ parameters, buildGetter(), closureCallName, arguments]); |
| 308 | 312 |
| 309 addProperty(invocationName, function); | 313 addProperty(invocationName, function); |
| 310 } | 314 } |
| 311 } | 315 } |
| 312 } | 316 } |
| 313 | 317 |
| 314 /** | 318 /** |
| 315 * Documentation wanted -- johnniwinther | 319 * Documentation wanted -- johnniwinther |
| 316 * | 320 * |
| 317 * Invariant: [member] must be a declaration element. | 321 * Invariant: [member] must be a declaration element. |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 417 // N+4. First default argument. | 421 // N+4. First default argument. |
| 418 // ... | 422 // ... |
| 419 // O. First parameter name (if needed for reflection or Function.apply). | 423 // O. First parameter name (if needed for reflection or Function.apply). |
| 420 // ... | 424 // ... |
| 421 // P. Unmangled name (if reflectable). | 425 // P. Unmangled name (if reflectable). |
| 422 // P+1. First metadata (if reflectable). | 426 // P+1. First metadata (if reflectable). |
| 423 // ... | 427 // ... |
| 424 // TODO(ahe): Consider one of the parameter counts can be replaced by the | 428 // TODO(ahe): Consider one of the parameter counts can be replaced by the |
| 425 // length property of the JavaScript function object. | 429 // length property of the JavaScript function object. |
| 426 | 430 |
| 427 List expressions = []; | 431 List<jsAst.Expression> expressions = <jsAst.Expression>[]; |
| 428 | 432 |
| 429 String callSelectorString = 'null'; | 433 String callSelectorString = 'null'; |
| 430 if (member.isFunction()) { | 434 if (member.isFunction()) { |
| 431 Selector callSelector = | 435 Selector callSelector = |
| 432 new Selector.fromElement(member, compiler).toCallSelector(); | 436 new Selector.fromElement(member, compiler).toCallSelector(); |
| 433 callSelectorString = '"${namer.invocationName(callSelector)}"'; | 437 callSelectorString = '"${namer.invocationName(callSelector)}"'; |
| 434 } | 438 } |
| 435 | 439 |
| 436 // On [requiredParameterCount], the lower bit is set if this method can be | 440 // On [requiredParameterCount], the lower bit is set if this method can be |
| 437 // called reflectively. | 441 // called reflectively. |
| 438 int requiredParameterCount = parameters.requiredParameterCount << 1; | 442 int requiredParameterCount = parameters.requiredParameterCount << 1; |
| 439 if (member.isAccessor()) requiredParameterCount++; | 443 if (member.isAccessor()) requiredParameterCount++; |
| 440 | 444 |
| 441 int optionalParameterCount = parameters.optionalParameterCount << 1; | 445 int optionalParameterCount = parameters.optionalParameterCount << 1; |
| 442 if (parameters.optionalParametersAreNamed) optionalParameterCount++; | 446 if (parameters.optionalParametersAreNamed) optionalParameterCount++; |
| 443 | 447 |
| 444 expressions.add(code); | 448 expressions.add(code); |
| 445 | 449 |
| 450 // TODO(sra): Don't use LiteralString for non-strings. | |
| 446 List tearOffInfo = [new jsAst.LiteralString(callSelectorString)]; | 451 List tearOffInfo = [new jsAst.LiteralString(callSelectorString)]; |
| 447 | 452 |
| 448 if (needsStubs || canTearOff) { | 453 if (needsStubs || canTearOff) { |
| 449 addParameterStubs(member, (Selector selector, jsAst.Fun function) { | 454 addParameterStubs(member, (Selector selector, jsAst.Fun function) { |
| 450 expressions.add(function); | 455 expressions.add(function); |
| 451 if (member.isInstanceMember()) { | 456 if (member.isInstanceMember()) { |
| 452 Set invokedSelectors = | 457 Set invokedSelectors = |
| 453 compiler.codegenWorld.invokedNames[member.name]; | 458 compiler.codegenWorld.invokedNames[member.name]; |
| 454 expressions.add(js.string(namer.invocationName(selector))); | 459 expressions.add(js.string(namer.invocationName(selector))); |
| 455 } else { | 460 } else { |
| 456 expressions.add("null"); | 461 expressions.add(js('null')); |
| 457 // TOOD(ahe): Since we know when reading static data versus instance | 462 // TOOD(ahe): Since we know when reading static data versus instance |
| 458 // data, we can eliminate this element. | 463 // data, we can eliminate this element. |
| 459 } | 464 } |
| 460 Set<Selector> callSelectors = compiler.codegenWorld.invokedNames[ | 465 Set<Selector> callSelectors = compiler.codegenWorld.invokedNames[ |
| 461 namer.closureInvocationSelectorName]; | 466 namer.closureInvocationSelectorName]; |
| 462 Selector callSelector = selector.toCallSelector(); | 467 Selector callSelector = selector.toCallSelector(); |
| 463 String callSelectorString = 'null'; | 468 String callSelectorString = 'null'; |
| 464 if (canTearOff && callSelectors != null && | 469 if (canTearOff && callSelectors != null && |
| 465 callSelectors.contains(callSelector)) { | 470 callSelectors.contains(callSelector)) { |
| 466 callSelectorString = '"${namer.invocationName(callSelector)}"'; | 471 callSelectorString = '"${namer.invocationName(callSelector)}"'; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 477 memberType = body.constructor.type; | 482 memberType = body.constructor.type; |
| 478 } else { | 483 } else { |
| 479 memberType = member.type; | 484 memberType = member.type; |
| 480 } | 485 } |
| 481 if (memberType.containsTypeVariables) { | 486 if (memberType.containsTypeVariables) { |
| 482 jsAst.Expression thisAccess = js(r'this.$receiver'); | 487 jsAst.Expression thisAccess = js(r'this.$receiver'); |
| 483 memberTypeExpression = | 488 memberTypeExpression = |
| 484 backend.rti.getSignatureEncoding(memberType, thisAccess); | 489 backend.rti.getSignatureEncoding(memberType, thisAccess); |
| 485 } else { | 490 } else { |
| 486 memberTypeExpression = | 491 memberTypeExpression = |
| 487 js.toExpression(task.metadataEmitter.reifyType(memberType)); | 492 js.number(task.metadataEmitter.reifyType(memberType)); |
| 488 } | 493 } |
| 489 } else { | 494 } else { |
| 490 memberTypeExpression = js('null'); | 495 memberTypeExpression = js('null'); |
| 491 } | 496 } |
| 492 | 497 |
| 493 expressions | 498 expressions |
| 494 ..addAll(tearOffInfo) | 499 ..addAll(tearOffInfo) |
| 495 ..add((tearOffName == null || member.isAccessor()) | 500 ..add((tearOffName == null || member.isAccessor()) |
| 496 ? js("null") : js.string(tearOffName)) | 501 ? js("null") : js.string(tearOffName)) |
| 497 ..add(requiredParameterCount) | 502 ..add(js.number(requiredParameterCount)) |
| 498 ..add(optionalParameterCount) | 503 ..add(js.number(optionalParameterCount)) |
| 499 ..add(memberTypeExpression) | 504 ..add(memberTypeExpression) |
| 500 ..addAll(task.metadataEmitter.reifyDefaultArguments(member)); | 505 ..addAll( |
| 506 task.metadataEmitter.reifyDefaultArguments(member).map(js.number)); | |
| 501 | 507 |
| 502 if (canBeReflected || canBeApplied) { | 508 if (canBeReflected || canBeApplied) { |
| 503 parameters.forEachParameter((Element parameter) { | 509 parameters.forEachParameter((Element parameter) { |
| 504 expressions.add(task.metadataEmitter.reifyName(parameter.name)); | 510 expressions.add( |
| 511 js.number(task.metadataEmitter.reifyName(parameter.name))); | |
| 505 if (backend.mustRetainMetadata) { | 512 if (backend.mustRetainMetadata) { |
| 506 List<MetadataAnnotation> annotations = parameter.metadata.toList(); | 513 List<MetadataAnnotation> annotations = parameter.metadata.toList(); |
| 507 Iterable<int> metadataIndices = | 514 Iterable<int> metadataIndices = |
| 508 annotations.map((MetadataAnnotation annotation) { | 515 annotations.map((MetadataAnnotation annotation) { |
| 509 Constant constant = | 516 Constant constant = |
| 510 backend.constants.getConstantForMetadata(annotation); | 517 backend.constants.getConstantForMetadata(annotation); |
| 511 backend.constants.addCompileTimeConstantForEmission(constant); | 518 backend.constants.addCompileTimeConstantForEmission(constant); |
| 512 return task.metadataEmitter.reifyMetadata(annotation); | 519 return task.metadataEmitter.reifyMetadata(annotation); |
| 513 }); | 520 }); |
| 514 expressions.add(metadataIndices.isNotEmpty ? metadataIndices.toList() | 521 expressions.add( |
| 515 : js('[]')); | 522 new jsAst.ArrayInitializer.from(metadataIndices.map(js.number))); |
| 516 } | 523 } |
| 517 }); | 524 }); |
| 518 } | 525 } |
| 519 if (canBeReflected) { | 526 if (canBeReflected) { |
| 520 jsAst.LiteralString reflectionName; | 527 jsAst.LiteralString reflectionName; |
| 521 if (member.isConstructor()) { | 528 if (member.isConstructor()) { |
| 522 String reflectionNameString = task.getReflectionName(member, name); | 529 String reflectionNameString = task.getReflectionName(member, name); |
| 523 reflectionName = | 530 reflectionName = |
| 524 new jsAst.LiteralString( | 531 new jsAst.LiteralString( |
| 525 '"new ${Elements.reconstructConstructorName(member)}"'); | 532 '"new ${Elements.reconstructConstructorName(member)}"'); |
| 526 } else { | 533 } else { |
| 527 reflectionName = js.string(member.name); | 534 reflectionName = js.string(member.name); |
| 528 } | 535 } |
| 529 expressions | 536 expressions |
| 530 ..add(reflectionName) | 537 ..add(reflectionName) |
| 531 ..addAll(task.metadataEmitter.computeMetadata(member)); | 538 ..addAll(task.metadataEmitter.computeMetadata(member).map(js.number)); |
| 532 } else if (isClosure && canBeApplied) { | 539 } else if (isClosure && canBeApplied) { |
| 533 expressions.add(js.string(member.name)); | 540 expressions.add(js.string(member.name)); |
| 534 } | 541 } |
| 535 | 542 builder.addProperty(name, new jsAst.ArrayInitializer.from(expressions)); |
| 536 builder.addProperty(name, js.toExpression(expressions)); | |
| 537 } | 543 } |
| 538 | 544 |
| 539 void addMemberField(VariableElement member, ClassBuilder builder) { | 545 void addMemberField(VariableElement member, ClassBuilder builder) { |
| 540 // For now, do nothing. | 546 // For now, do nothing. |
| 541 } | 547 } |
| 542 } | 548 } |
| OLD | NEW |