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 class NativeEmitter { | 7 class NativeEmitter { |
8 | 8 |
9 CodeEmitterTask emitter; | 9 CodeEmitterTask emitter; |
10 CodeBuffer nativeBuffer; | 10 CodeBuffer nativeBuffer; |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 } | 154 } |
155 | 155 |
156 void potentiallyConvertDartClosuresToJs(List<js.Statement> statements, | 156 void potentiallyConvertDartClosuresToJs(List<js.Statement> statements, |
157 FunctionElement member, | 157 FunctionElement member, |
158 List<js.Parameter> stubParameters) { | 158 List<js.Parameter> stubParameters) { |
159 FunctionSignature parameters = member.computeSignature(compiler); | 159 FunctionSignature parameters = member.computeSignature(compiler); |
160 Element converter = | 160 Element converter = |
161 compiler.findHelper(const SourceString('convertDartClosureToJS')); | 161 compiler.findHelper(const SourceString('convertDartClosureToJS')); |
162 String closureConverter = backend.namer.isolateAccess(converter); | 162 String closureConverter = backend.namer.isolateAccess(converter); |
163 Set<String> stubParameterNames = new Set<String>.from( | 163 Set<String> stubParameterNames = new Set<String>.from( |
164 stubParameters.map((param) => param.name)); | 164 stubParameters.mappedBy((param) => param.name)); |
165 parameters.forEachParameter((Element parameter) { | 165 parameters.forEachParameter((Element parameter) { |
166 String name = parameter.name.slowToString(); | 166 String name = parameter.name.slowToString(); |
167 // If [name] is not in [stubParameters], then the parameter is an optional | 167 // If [name] is not in [stubParameters], then the parameter is an optional |
168 // parameter that was not provided for this stub. | 168 // parameter that was not provided for this stub. |
169 for (js.Parameter stubParameter in stubParameters) { | 169 for (js.Parameter stubParameter in stubParameters) { |
170 if (stubParameter.name == name) { | 170 if (stubParameter.name == name) { |
171 DartType type = parameter.computeType(compiler).unalias(compiler); | 171 DartType type = parameter.computeType(compiler).unalias(compiler); |
172 if (type is FunctionType) { | 172 if (type is FunctionType) { |
173 // The parameter type is a function type either directly or through | 173 // The parameter type is a function type either directly or through |
174 // typedef(s). | 174 // typedef(s). |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 List<js.Parameter> parameters) { | 248 List<js.Parameter> parameters) { |
249 return js.if_( | 249 return js.if_( |
250 js.use('Object').dot('getPrototypeOf') | 250 js.use('Object').dot('getPrototypeOf') |
251 .callWith([js.use('this')]) | 251 .callWith([js.use('this')]) |
252 .dot('hasOwnProperty').callWith([js.string(methodName)]), | 252 .dot('hasOwnProperty').callWith([js.string(methodName)]), |
253 body, | 253 body, |
254 js.return_( | 254 js.return_( |
255 js.use('Object').dot('prototype').dot(methodName).dot('call') | 255 js.use('Object').dot('prototype').dot(methodName).dot('call') |
256 .callWith( | 256 .callWith( |
257 <js.Expression>[js.use('this')]..addAll( | 257 <js.Expression>[js.use('this')]..addAll( |
258 parameters.map((param) => js.use(param.name)))))); | 258 parameters.mappedBy((param) => js.use(param.name)))))); |
259 } | 259 } |
260 | 260 |
261 js.Block generateMethodBodyWithPrototypeCheckForElement( | 261 js.Block generateMethodBodyWithPrototypeCheckForElement( |
262 FunctionElement element, | 262 FunctionElement element, |
263 js.Block body, | 263 js.Block body, |
264 List<js.Parameter> parameters) { | 264 List<js.Parameter> parameters) { |
265 String methodName; | 265 String methodName; |
266 Namer namer = backend.namer; | 266 Namer namer = backend.namer; |
267 if (element.kind == ElementKind.FUNCTION) { | 267 if (element.kind == ElementKind.FUNCTION) { |
268 methodName = namer.instanceMethodName(element); | 268 methodName = namer.instanceMethodName(element); |
(...skipping 22 matching lines...) Expand all Loading... |
291 Set<ClassElement> seen = new Set<ClassElement>(); | 291 Set<ClassElement> seen = new Set<ClassElement>(); |
292 List<ClassElement> classes = <ClassElement>[]; | 292 List<ClassElement> classes = <ClassElement>[]; |
293 void visit(ClassElement cls) { | 293 void visit(ClassElement cls) { |
294 if (seen.contains(cls)) return; | 294 if (seen.contains(cls)) return; |
295 seen.add(cls); | 295 seen.add(cls); |
296 getDirectSubclasses(cls).forEach(visit); | 296 getDirectSubclasses(cls).forEach(visit); |
297 classes.add(cls); | 297 classes.add(cls); |
298 } | 298 } |
299 classesWithDynamicDispatch.forEach(visit); | 299 classesWithDynamicDispatch.forEach(visit); |
300 | 300 |
301 Collection<ClassElement> preorderDispatchClasses = classes.filter( | 301 List<ClassElement> preorderDispatchClasses = classes.where( |
302 (cls) => !getDirectSubclasses(cls).isEmpty && | 302 (cls) => !getDirectSubclasses(cls).isEmpty && |
303 classesWithDynamicDispatch.contains(cls)); | 303 classesWithDynamicDispatch.contains(cls)).toList(); |
304 | 304 |
305 if (!compiler.enableMinification) { | 305 if (!compiler.enableMinification) { |
306 nativeBuffer.add('// ${classes.length} classes\n'); | 306 nativeBuffer.add('// ${classes.length} classes\n'); |
307 } | 307 } |
308 Collection<ClassElement> classesThatHaveSubclasses = classes.filter( | 308 Iterable<ClassElement> classesThatHaveSubclasses = classes.where( |
309 (ClassElement t) => !getDirectSubclasses(t).isEmpty); | 309 (ClassElement t) => !getDirectSubclasses(t).isEmpty); |
310 if (!compiler.enableMinification) { | 310 if (!compiler.enableMinification) { |
311 nativeBuffer.add('// ${classesThatHaveSubclasses.length} !leaf\n'); | 311 nativeBuffer.add('// ${classesThatHaveSubclasses.length} !leaf\n'); |
312 } | 312 } |
313 | 313 |
314 // Generate code that builds the map from cls tags used in dynamic dispatch | 314 // Generate code that builds the map from cls tags used in dynamic dispatch |
315 // to the set of cls tags of classes that extend (TODO: or implement) those | 315 // to the set of cls tags of classes that extend (TODO: or implement) those |
316 // classes. The set is represented as a string of tags joined with '|'. | 316 // classes. The set is represented as a string of tags joined with '|'. |
317 // This is easily split into an array of tags, or converted into a regexp. | 317 // This is easily split into an array of tags, or converted into a regexp. |
318 // | 318 // |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 new js.ExpressionStatement( | 404 new js.ExpressionStatement( |
405 new js.VariableDeclarationList(initializations))); | 405 new js.VariableDeclarationList(initializations))); |
406 } | 406 } |
407 | 407 |
408 // [table] is a list of lists, each inner list of the form: | 408 // [table] is a list of lists, each inner list of the form: |
409 // [dynamic-dispatch-tag, tags-of-classes-implementing-dispatch-tag] | 409 // [dynamic-dispatch-tag, tags-of-classes-implementing-dispatch-tag] |
410 // E.g. | 410 // E.g. |
411 // [['Node', 'Text|HTMLElement|HTMLDivElement|...'], ...] | 411 // [['Node', 'Text|HTMLElement|HTMLDivElement|...'], ...] |
412 js.Expression table = | 412 js.Expression table = |
413 new js.ArrayInitializer.from( | 413 new js.ArrayInitializer.from( |
414 preorderDispatchClasses.map((cls) => | 414 preorderDispatchClasses.mappedBy((cls) => |
415 new js.ArrayInitializer.from([ | 415 new js.ArrayInitializer.from([ |
416 js.string(toNativeTag(cls)), | 416 js.string(toNativeTag(cls)), |
417 tagDefns[cls]]))); | 417 tagDefns[cls]]))); |
418 | 418 |
419 // $.dynamicSetMetadata(table); | 419 // $.dynamicSetMetadata(table); |
420 statements.add( | 420 statements.add( |
421 new js.ExpressionStatement( | 421 new js.ExpressionStatement( |
422 new js.Call( | 422 new js.Call( |
423 new js.VariableUse(dynamicSetMetadataName), | 423 new js.VariableUse(dynamicSetMetadataName), |
424 [table]))); | 424 [table]))); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 if (emitter.compiler.enableMinification) targetBuffer.add(';'); | 536 if (emitter.compiler.enableMinification) targetBuffer.add(';'); |
537 targetBuffer.add(js.prettyPrint( | 537 targetBuffer.add(js.prettyPrint( |
538 new js.ExpressionStatement(init), compiler)); | 538 new js.ExpressionStatement(init), compiler)); |
539 targetBuffer.add('\n'); | 539 targetBuffer.add('\n'); |
540 } | 540 } |
541 | 541 |
542 targetBuffer.add(nativeBuffer); | 542 targetBuffer.add(nativeBuffer); |
543 targetBuffer.add('\n'); | 543 targetBuffer.add('\n'); |
544 } | 544 } |
545 } | 545 } |
OLD | NEW |