OLD | NEW |
---|---|
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 import 'dart:collection' show HashMap, HashSet; | 5 import 'dart:collection' show HashMap, HashSet; |
6 import 'dart:math' show min, max; | 6 import 'dart:math' show min, max; |
7 | 7 |
8 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 8 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; | 10 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
87 | 87 |
88 // TODO(jmesserly): fuse this with notNull check. | 88 // TODO(jmesserly): fuse this with notNull check. |
89 final _privateNames = | 89 final _privateNames = |
90 new HashMap<LibraryElement, HashMap<String, JS.TemporaryId>>(); | 90 new HashMap<LibraryElement, HashMap<String, JS.TemporaryId>>(); |
91 final _initializingFormalTemps = | 91 final _initializingFormalTemps = |
92 new HashMap<ParameterElement, JS.TemporaryId>(); | 92 new HashMap<ParameterElement, JS.TemporaryId>(); |
93 | 93 |
94 final _dartxVar = new JS.Identifier('dartx'); | 94 final _dartxVar = new JS.Identifier('dartx'); |
95 final _runtimeLibVar = new JS.Identifier('dart'); | 95 final _runtimeLibVar = new JS.Identifier('dart'); |
96 final namedArgumentTemp = new JS.TemporaryId('opts'); | 96 final namedArgumentTemp = new JS.TemporaryId('opts'); |
97 final positionalArgumentsTemp = new JS.TemporaryId('positionalArgs'); | |
97 | 98 |
98 final _hasDeferredSupertype = new HashSet<ClassElement>(); | 99 final _hasDeferredSupertype = new HashSet<ClassElement>(); |
99 | 100 |
100 final _eagerTopLevelFields = new HashSet<Element>.identity(); | 101 final _eagerTopLevelFields = new HashSet<Element>.identity(); |
101 | 102 |
102 /// The type provider from the current Analysis [context]. | 103 /// The type provider from the current Analysis [context]. |
103 final TypeProvider types; | 104 final TypeProvider types; |
104 | 105 |
105 final LibraryElement dartCoreLibrary; | 106 final LibraryElement dartCoreLibrary; |
106 final LibraryElement dartJSLibrary; | 107 final LibraryElement dartJSLibrary; |
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1402 /// noSuchMethod(Invocation invocation) => 3; | 1403 /// noSuchMethod(Invocation invocation) => 3; |
1403 /// } | 1404 /// } |
1404 /// | 1405 /// |
1405 /// It will generate an `eatFood` that looks like: | 1406 /// It will generate an `eatFood` that looks like: |
1406 /// | 1407 /// |
1407 /// eatFood(food) { | 1408 /// eatFood(food) { |
1408 /// return core.bool.as(this.noSuchMethod( | 1409 /// return core.bool.as(this.noSuchMethod( |
1409 /// new dart.InvocationImpl('eatFood', [food]))); | 1410 /// new dart.InvocationImpl('eatFood', [food]))); |
1410 /// } | 1411 /// } |
1411 JS.Method _implementMockMethod(ExecutableElement method) { | 1412 JS.Method _implementMockMethod(ExecutableElement method) { |
1412 var positionalArgs = <JS.Identifier>[] | 1413 var normalArgs = <JS.Identifier>[] |
1413 ..addAll( | 1414 ..addAll( |
1414 method.type.normalParameterNames.map((a) => new JS.Identifier(a))) | 1415 method.type.normalParameterNames.map((a) => new JS.Identifier(a))); |
1416 var optionalArgs = <JS.Identifier>[] | |
1415 ..addAll( | 1417 ..addAll( |
1416 method.type.optionalParameterNames.map((a) => new JS.Identifier(a))); | 1418 method.type.optionalParameterNames.map((a) => new JS.Identifier(a))); |
1417 | 1419 var fnArgs = <JS.Identifier>[]..addAll(normalArgs)..addAll(optionalArgs); |
1418 var fnArgs = positionalArgs.toList(); | |
1419 | 1420 |
1420 var invocationProps = <JS.Property>[]; | 1421 var invocationProps = <JS.Property>[]; |
1421 addProperty(String name, JS.Expression value) { | 1422 addProperty(String name, JS.Expression value) { |
1422 invocationProps.add(new JS.Property(js.string(name), value)); | 1423 invocationProps.add(new JS.Property(js.string(name), value)); |
1423 } | 1424 } |
1424 | 1425 |
1425 if (method.type.namedParameterTypes.isNotEmpty) { | 1426 if (method.type.namedParameterTypes.isNotEmpty) { |
1426 fnArgs.add(namedArgumentTemp); | 1427 fnArgs.add(namedArgumentTemp); |
1427 addProperty('namedArguments', namedArgumentTemp); | 1428 addProperty('namedArguments', namedArgumentTemp); |
1428 } | 1429 } |
1429 | 1430 |
1430 if (method is MethodElement) { | 1431 if (method is MethodElement) { |
1431 addProperty('isMethod', js.boolean(true)); | 1432 addProperty('isMethod', js.boolean(true)); |
1432 } else { | 1433 } else { |
1433 var property = method as PropertyAccessorElement; | 1434 var property = method as PropertyAccessorElement; |
1434 if (property.isGetter) { | 1435 if (property.isGetter) { |
1435 addProperty('isGetter', js.boolean(true)); | 1436 addProperty('isGetter', js.boolean(true)); |
1436 } else if (property.isSetter) { | 1437 } else if (property.isSetter) { |
1437 addProperty('isSetter', js.boolean(true)); | 1438 addProperty('isSetter', js.boolean(true)); |
1438 } | 1439 } |
1439 } | 1440 } |
1440 | 1441 |
1441 var fnBody = | 1442 var posDecl = js.statement('let # = #;', |
1443 [positionalArgumentsTemp, new JS.ArrayInitializer(normalArgs)]); | |
1444 | |
1445 var fnBody = <JS.Statement>[posDecl]; | |
1446 | |
1447 if (optionalArgs.length > 0) { | |
1448 final argTemp = new JS.TemporaryId('arg'); | |
1449 // Optional arguments must only be passed on to noSuchMethod if they were | |
1450 // actually passed here. This code loops through them, pushing the ones | |
1451 // that were actually passed. | |
1452 var existenceCheckLoop = js.statement( | |
1453 'for (let arg of #) { if (# !== void 0) { #.push(#); } }', [ | |
srawlins
2016/08/01 18:30:38
I think I need help on this line: `arg` needs to b
| |
1454 //argTemp, | |
1455 new JS.ArrayInitializer(optionalArgs), | |
1456 argTemp, | |
1457 positionalArgumentsTemp, | |
1458 argTemp, | |
1459 ]); | |
1460 fnBody.add(existenceCheckLoop); | |
1461 } | |
1462 | |
1463 var nSMCall = | |
1442 js.call('this.noSuchMethod(new dart.InvocationImpl(#, #, #))', [ | 1464 js.call('this.noSuchMethod(new dart.InvocationImpl(#, #, #))', [ |
1443 _elementMemberName(method), | 1465 _elementMemberName(method), |
1444 new JS.ArrayInitializer(positionalArgs), | 1466 positionalArgumentsTemp, |
1445 new JS.ObjectInitializer(invocationProps) | 1467 new JS.ObjectInitializer(invocationProps) |
1446 ]); | 1468 ]); |
1447 | 1469 |
1448 if (!method.returnType.isDynamic) { | 1470 if (!method.returnType.isDynamic) { |
1449 fnBody = js.call('#._check(#)', [_emitType(method.returnType), fnBody]); | 1471 nSMCall = js.call('#._check(#)', [_emitType(method.returnType), nSMCall]); |
1450 } | 1472 } |
1451 | 1473 |
1452 var fn = new JS.Fun(fnArgs, js.statement('{ return #; }', [fnBody]), | 1474 fnBody.add(js.statement('return #', [nSMCall])); |
1475 | |
1476 var fn = new JS.Fun(fnArgs, js.statement('{ # }', [_statement(fnBody)]), | |
1453 typeParams: _emitTypeFormals(method.type.typeFormals)); | 1477 typeParams: _emitTypeFormals(method.type.typeFormals)); |
1454 | 1478 |
1455 // TODO(jmesserly): generic type arguments will get dropped. | 1479 // TODO(jmesserly): generic type arguments will get dropped. |
1456 // We have a similar issue with `dgsend` helpers. | 1480 // We have a similar issue with `dgsend` helpers. |
1457 return new JS.Method( | 1481 return new JS.Method( |
1458 _elementMemberName(method, | 1482 _elementMemberName(method, |
1459 useExtension: | 1483 useExtension: |
1460 _extensionTypes.isNativeClass(method.enclosingElement)), | 1484 _extensionTypes.isNativeClass(method.enclosingElement)), |
1461 _makeGenericFunction(fn), | 1485 _makeGenericFunction(fn), |
1462 isGetter: method is PropertyAccessorElement && method.isGetter, | 1486 isGetter: method is PropertyAccessorElement && method.isGetter, |
(...skipping 3899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5362 } | 5386 } |
5363 | 5387 |
5364 bool isLibraryPrefix(Expression node) => | 5388 bool isLibraryPrefix(Expression node) => |
5365 node is SimpleIdentifier && node.staticElement is PrefixElement; | 5389 node is SimpleIdentifier && node.staticElement is PrefixElement; |
5366 | 5390 |
5367 LibraryElement _getLibrary(AnalysisContext c, String uri) => | 5391 LibraryElement _getLibrary(AnalysisContext c, String uri) => |
5368 c.computeLibraryElement(c.sourceFactory.forUri(uri)); | 5392 c.computeLibraryElement(c.sourceFactory.forUri(uri)); |
5369 | 5393 |
5370 bool _isDartRuntime(LibraryElement l) => | 5394 bool _isDartRuntime(LibraryElement l) => |
5371 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; | 5395 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; |
OLD | NEW |