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 | 6 |
7 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 7 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
8 import 'package:analyzer/dart/ast/ast.dart'; | 8 import 'package:analyzer/dart/ast/ast.dart'; |
9 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; | 9 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType; |
10 import 'package:analyzer/dart/element/element.dart'; | 10 import 'package:analyzer/dart/element/element.dart'; |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
467 var typeFormals = element.typeParameters; | 467 var typeFormals = element.typeParameters; |
468 if (typeFormals.isNotEmpty) { | 468 if (typeFormals.isNotEmpty) { |
469 return _defineClassTypeArguments(element, typeFormals, | 469 return _defineClassTypeArguments(element, typeFormals, |
470 js.statement('const # = #;', [element.name, body])); | 470 js.statement('const # = #;', [element.name, body])); |
471 } else { | 471 } else { |
472 return js.statement('# = #;', [_emitTopLevelName(element), body]); | 472 return js.statement('# = #;', [_emitTopLevelName(element), body]); |
473 } | 473 } |
474 } | 474 } |
475 | 475 |
476 @override | 476 @override |
477 JS.Expression visitTypeName(TypeName node) => _emitTypeName(node.type); | 477 JS.Expression visitTypeName(TypeName node) { |
478 // TODO(jmesserly): should only happen for erroneous code. | |
479 if (node.type == null) return js.call('dart.dynamic'); | |
480 return _emitTypeName(node.type); | |
481 } | |
478 | 482 |
479 @override | 483 @override |
480 JS.Statement visitClassTypeAlias(ClassTypeAlias node) { | 484 JS.Statement visitClassTypeAlias(ClassTypeAlias node) { |
481 ClassElement element = node.element; | 485 ClassElement element = node.element; |
482 | 486 |
483 // Forward all generative constructors from the base class. | 487 // Forward all generative constructors from the base class. |
484 var methods = <JS.Method>[]; | 488 var methods = <JS.Method>[]; |
485 | 489 |
486 var supertype = element.supertype; | 490 var supertype = element.supertype; |
487 if (!supertype.isObject) { | 491 if (!supertype.isObject) { |
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1471 fields[element as FieldElement] = _visitInitializer(fieldNode); | 1475 fields[element as FieldElement] = _visitInitializer(fieldNode); |
1472 } | 1476 } |
1473 } | 1477 } |
1474 } | 1478 } |
1475 | 1479 |
1476 // Initialize fields from `this.fieldName` parameters. | 1480 // Initialize fields from `this.fieldName` parameters. |
1477 if (ctor != null) { | 1481 if (ctor != null) { |
1478 for (var p in ctor.parameters.parameters) { | 1482 for (var p in ctor.parameters.parameters) { |
1479 var element = p.element; | 1483 var element = p.element; |
1480 if (element is FieldFormalParameterElement) { | 1484 if (element is FieldFormalParameterElement) { |
1481 fields[element.field] = visitSimpleIdentifier(p.identifier); | 1485 fields[element.field] = _emitSimpleIdentifier(p.identifier); |
1482 } | 1486 } |
1483 } | 1487 } |
1484 | 1488 |
1485 // Run constructor field initializers such as `: foo = bar.baz` | 1489 // Run constructor field initializers such as `: foo = bar.baz` |
1486 for (var init in ctor.initializers) { | 1490 for (var init in ctor.initializers) { |
1487 if (init is ConstructorFieldInitializer) { | 1491 if (init is ConstructorFieldInitializer) { |
1488 fields[init.fieldName.staticElement as FieldElement] = | 1492 fields[init.fieldName.staticElement as FieldElement] = |
1489 _visit(init.expression); | 1493 _visit(init.expression); |
1490 } | 1494 } |
1491 } | 1495 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1534 JS.Statement _emitArgumentInitializers(node, {bool constructor: false}) { | 1538 JS.Statement _emitArgumentInitializers(node, {bool constructor: false}) { |
1535 // Constructor argument initializers are emitted earlier in the code, rather | 1539 // Constructor argument initializers are emitted earlier in the code, rather |
1536 // than always when we visit the function body, so we control it explicitly. | 1540 // than always when we visit the function body, so we control it explicitly. |
1537 if (node is ConstructorDeclaration != constructor) return null; | 1541 if (node is ConstructorDeclaration != constructor) return null; |
1538 | 1542 |
1539 var parameters = _parametersOf(node); | 1543 var parameters = _parametersOf(node); |
1540 if (parameters == null) return null; | 1544 if (parameters == null) return null; |
1541 | 1545 |
1542 var body = <JS.Statement>[]; | 1546 var body = <JS.Statement>[]; |
1543 for (var param in parameters.parameters) { | 1547 for (var param in parameters.parameters) { |
1544 var jsParam = visitSimpleIdentifier(param.identifier); | 1548 var jsParam = _emitSimpleIdentifier(param.identifier); |
1545 | 1549 |
1546 if (!options.destructureNamedParams) { | 1550 if (!options.destructureNamedParams) { |
1547 if (param.kind == ParameterKind.NAMED) { | 1551 if (param.kind == ParameterKind.NAMED) { |
1548 // Parameters will be passed using their real names, not the (possibly | 1552 // Parameters will be passed using their real names, not the (possibly |
1549 // renamed) local variable. | 1553 // renamed) local variable. |
1550 var paramName = js.string(param.identifier.name, "'"); | 1554 var paramName = js.string(param.identifier.name, "'"); |
1551 | 1555 |
1552 // TODO(ochafik): Fix `'prop' in obj` to please Closure's renaming. | 1556 // TODO(ochafik): Fix `'prop' in obj` to please Closure's renaming. |
1553 body.add(js.statement('let # = # && # in # ? #.# : #;', [ | 1557 body.add(js.statement('let # = # && # in # ? #.# : #;', [ |
1554 jsParam, | 1558 jsParam, |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1969 declareFn = new JS.FunctionDeclaration(name, fn); | 1973 declareFn = new JS.FunctionDeclaration(name, fn); |
1970 } | 1974 } |
1971 declareFn = annotate(declareFn, node, node.functionDeclaration.element); | 1975 declareFn = annotate(declareFn, node, node.functionDeclaration.element); |
1972 | 1976 |
1973 return new JS.Block([ | 1977 return new JS.Block([ |
1974 declareFn, | 1978 declareFn, |
1975 _emitFunctionTagged(name, func.element.type).toStatement() | 1979 _emitFunctionTagged(name, func.element.type).toStatement() |
1976 ]); | 1980 ]); |
1977 } | 1981 } |
1978 | 1982 |
1979 /// Writes a simple identifier. This can handle implicit `this` as well as | 1983 /// Emits a simple identifier, including handling an inferred generic |
1980 /// going through the qualified library name if necessary. | 1984 /// function instantiation. |
1981 @override | 1985 @override |
1982 JS.Expression visitSimpleIdentifier(SimpleIdentifier node) { | 1986 JS.Expression visitSimpleIdentifier(SimpleIdentifier node) { |
1987 return _applyFunctionTypeArguments( | |
1988 _emitSimpleIdentifier(node), node.staticElement, node.staticType); | |
1989 } | |
1990 | |
1991 /// Emits a simple identifier, handling implicit `this` as well as | |
1992 /// going through the qualified library name if necessary, but *not* handling | |
1993 /// inferred generic function instantiation. | |
1994 JS.Expression _emitSimpleIdentifier(SimpleIdentifier node) { | |
1983 var accessor = node.staticElement; | 1995 var accessor = node.staticElement; |
1984 if (accessor == null) { | 1996 if (accessor == null) { |
1985 return js.commentExpression( | 1997 return js.commentExpression( |
1986 'Unimplemented unknown name', new JS.Identifier(node.name)); | 1998 'Unimplemented unknown name', new JS.Identifier(node.name)); |
1987 } | 1999 } |
1988 | 2000 |
1989 // Get the original declaring element. If we had a property accessor, this | 2001 // Get the original declaring element. If we had a property accessor, this |
1990 // indirects back to a (possibly synthetic) field. | 2002 // indirects back to a (possibly synthetic) field. |
1991 var element = accessor; | 2003 var element = accessor; |
1992 if (accessor is PropertyAccessorElement) element = accessor.variable; | 2004 if (accessor is PropertyAccessorElement) element = accessor.variable; |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2325 var name = node.methodName.name; | 2337 var name = node.methodName.name; |
2326 var element = node.methodName.staticElement; | 2338 var element = node.methodName.staticElement; |
2327 bool isStatic = element is ExecutableElement && element.isStatic; | 2339 bool isStatic = element is ExecutableElement && element.isStatic; |
2328 var memberName = _emitMemberName(name, type: type, isStatic: isStatic); | 2340 var memberName = _emitMemberName(name, type: type, isStatic: isStatic); |
2329 | 2341 |
2330 JS.Expression jsTarget = _visit(target); | 2342 JS.Expression jsTarget = _visit(target); |
2331 var typeArgs = _emitInvokeTypeArguments(node); | 2343 var typeArgs = _emitInvokeTypeArguments(node); |
2332 List<JS.Expression> args = _visit(node.argumentList); | 2344 List<JS.Expression> args = _visit(node.argumentList); |
2333 if (DynamicInvoke.get(target)) { | 2345 if (DynamicInvoke.get(target)) { |
2334 if (typeArgs != null) { | 2346 if (typeArgs != null) { |
2335 return js.call('dart.dgsend(#, [#], #, #)', | 2347 return js.call('dart.dgsend(#, #, #, #)', |
2336 [jsTarget, typeArgs, memberName, args]); | 2348 [jsTarget, new JS.ArrayInitializer(typeArgs), memberName, args]); |
2337 } else { | 2349 } else { |
2338 return js.call('dart.dsend(#, #, #)', [jsTarget, memberName, args]); | 2350 return js.call('dart.dsend(#, #, #)', [jsTarget, memberName, args]); |
2339 } | 2351 } |
2340 } | 2352 } |
2341 if (_isObjectMemberCall(target, name)) { | 2353 if (_isObjectMemberCall(target, name)) { |
2342 // Object methods require a helper for null checks & native types. | 2354 // Object methods require a helper for null checks & native types. |
2343 assert(typeArgs == null); // Object methods don't take type args. | 2355 assert(typeArgs == null); // Object methods don't take type args. |
2344 return js.call('dart.#(#, #)', [memberName, jsTarget, args]); | 2356 return js.call('dart.#(#, #)', [memberName, jsTarget, args]); |
2345 } | 2357 } |
2346 | 2358 |
(...skipping 11 matching lines...) Expand all Loading... | |
2358 } | 2370 } |
2359 | 2371 |
2360 /// Emits a function call, to a top-level function, local function, or | 2372 /// Emits a function call, to a top-level function, local function, or |
2361 /// an expression. | 2373 /// an expression. |
2362 JS.Expression _emitFunctionCall(InvocationExpression node) { | 2374 JS.Expression _emitFunctionCall(InvocationExpression node) { |
2363 var fn = _visit(node.function); | 2375 var fn = _visit(node.function); |
2364 var args = _visit(node.argumentList); | 2376 var args = _visit(node.argumentList); |
2365 if (DynamicInvoke.get(node.function)) { | 2377 if (DynamicInvoke.get(node.function)) { |
2366 var typeArgs = _emitInvokeTypeArguments(node); | 2378 var typeArgs = _emitInvokeTypeArguments(node); |
2367 if (typeArgs != null) { | 2379 if (typeArgs != null) { |
2368 return js.call('dart.dgcall(#, [#], #)', [fn, typeArgs, args]); | 2380 return js.call('dart.dgcall(#, #, #)', |
2381 [fn, new JS.ArrayInitializer(typeArgs), args]); | |
2369 } else { | 2382 } else { |
2370 return js.call('dart.dcall(#, #)', [fn, args]); | 2383 return js.call('dart.dcall(#, #)', [fn, args]); |
2371 } | 2384 } |
2372 } else { | 2385 } else { |
2373 return new JS.Call(_applyInvokeTypeArguments(fn, node), args); | 2386 return new JS.Call(_applyInvokeTypeArguments(fn, node), args); |
2374 } | 2387 } |
2375 } | 2388 } |
2376 | 2389 |
2377 JS.Expression _applyInvokeTypeArguments( | 2390 JS.Expression _applyInvokeTypeArguments( |
2378 JS.Expression target, InvocationExpression node) { | 2391 JS.Expression target, InvocationExpression node) { |
2379 var typeArgs = _emitInvokeTypeArguments(node); | 2392 var typeArgs = _emitInvokeTypeArguments(node); |
2380 if (typeArgs == null) return target; | 2393 if (typeArgs == null) return target; |
2381 return new JS.Call(target, typeArgs); | 2394 return new JS.Call(target, typeArgs); |
2382 } | 2395 } |
2383 | 2396 |
2384 List<JS.Expression> _emitInvokeTypeArguments(InvocationExpression node) { | 2397 List<JS.Expression> _emitInvokeTypeArguments(InvocationExpression node) { |
2385 return _emitFunctionTypeArguments( | 2398 return _emitFunctionTypeArguments( |
2386 node.function.staticType, node.staticInvokeType); | 2399 node.function.staticType, node.staticInvokeType, node.typeArguments); |
2387 } | 2400 } |
2388 | 2401 |
2389 /// If `g` is a generic function type, and `f` is an instantiation of it, | 2402 /// If `g` is a generic function type, and `f` is an instantiation of it, |
2390 /// then this will return the type arguments to apply, otherwise null. | 2403 /// then this will return the type arguments to apply, otherwise null. |
2391 List<JS.Expression> _emitFunctionTypeArguments(DartType g, DartType f) { | 2404 List<JS.Expression> _emitFunctionTypeArguments(DartType g, DartType f, |
2405 [TypeArgumentList typeArgs]) { | |
2392 if (g is FunctionType && | 2406 if (g is FunctionType && |
2393 g.typeFormals.isNotEmpty && | 2407 g.typeFormals.isNotEmpty && |
2394 f is FunctionType && | 2408 f is FunctionType && |
2395 f.typeFormals.isEmpty) { | 2409 f.typeFormals.isEmpty) { |
2396 return _recoverTypeArguments(g, f) | 2410 return _recoverTypeArguments(g, f) |
2397 .map(_emitTypeName) | 2411 .map(_emitTypeName) |
2398 .toList(growable: false); | 2412 .toList(growable: false); |
2413 } else if (typeArgs != null) { | |
2414 // Dynamic calls may have type arguments, even though the function types | |
2415 // are not known. | |
2416 // TODO(jmesserly): seems to be mostly broken in Analyzer at the moment: | |
2417 // https://github.com/dart-lang/sdk/issues/26368 | |
2418 return typeArgs.arguments.map(visitTypeName).toList(growable: false); | |
Harry Terkelsen
2016/04/29 23:04:11
why visitTypeName here and _emitTypeName above? Is
Jennifer Messerly
2016/04/29 23:08:14
_emitTypeName ... probably should be renamed _emit
| |
2399 } | 2419 } |
2400 return null; | 2420 return null; |
2401 } | 2421 } |
2402 | 2422 |
2403 /// Given a generic function type [g] and an instantiated function type [f], | 2423 /// Given a generic function type [g] and an instantiated function type [f], |
2404 /// find a list of type arguments TArgs such that `g<TArgs> == f`, | 2424 /// find a list of type arguments TArgs such that `g<TArgs> == f`, |
2405 /// and return TArgs. | 2425 /// and return TArgs. |
2406 /// | 2426 /// |
2407 /// This function must be called with type [f] that was instantiated from [g]. | 2427 /// This function must be called with type [f] that was instantiated from [g]. |
2408 Iterable<DartType> _recoverTypeArguments(FunctionType g, FunctionType f) { | 2428 Iterable<DartType> _recoverTypeArguments(FunctionType g, FunctionType f) { |
(...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3230 JS.This visitThisExpression(ThisExpression node) => new JS.This(); | 3250 JS.This visitThisExpression(ThisExpression node) => new JS.This(); |
3231 | 3251 |
3232 @override | 3252 @override |
3233 JS.Super visitSuperExpression(SuperExpression node) => new JS.Super(); | 3253 JS.Super visitSuperExpression(SuperExpression node) => new JS.Super(); |
3234 | 3254 |
3235 @override | 3255 @override |
3236 visitPrefixedIdentifier(PrefixedIdentifier node) { | 3256 visitPrefixedIdentifier(PrefixedIdentifier node) { |
3237 if (isLibraryPrefix(node.prefix)) { | 3257 if (isLibraryPrefix(node.prefix)) { |
3238 return _visit(node.identifier); | 3258 return _visit(node.identifier); |
3239 } else { | 3259 } else { |
3240 return _emitAccess(node.prefix, node.identifier); | 3260 return _emitAccess(node.prefix, node.identifier, node.staticType); |
3241 } | 3261 } |
3242 } | 3262 } |
3243 | 3263 |
3244 @override | 3264 @override |
3245 visitPropertyAccess(PropertyAccess node) { | 3265 visitPropertyAccess(PropertyAccess node) { |
3246 if (node.operator.lexeme == '?.') { | 3266 if (node.operator.lexeme == '?.') { |
3247 return _emitNullSafe(node); | 3267 return _emitNullSafe(node); |
3248 } | 3268 } |
3249 return _emitAccess(_getTarget(node), node.propertyName); | 3269 return _emitAccess(_getTarget(node), node.propertyName, node.staticType); |
3250 } | 3270 } |
3251 | 3271 |
3252 JS.Expression _emitNullSafe(Expression node) { | 3272 JS.Expression _emitNullSafe(Expression node) { |
3253 // Desugar ?. sequence by passing a sequence of callbacks that applies | 3273 // Desugar ?. sequence by passing a sequence of callbacks that applies |
3254 // each operation in sequence: | 3274 // each operation in sequence: |
3255 // | 3275 // |
3256 // obj?.foo()?.bar | 3276 // obj?.foo()?.bar |
3257 // --> | 3277 // --> |
3258 // nullSafe(obj, _ => _.foo(), _ => _.bar); | 3278 // nullSafe(obj, _ => _.foo(), _ => _.bar); |
3259 // | 3279 // |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3316 | 3336 |
3317 // Check if the target could be `null`, is dynamic, or may be an extension | 3337 // Check if the target could be `null`, is dynamic, or may be an extension |
3318 // native type. In all of those cases we need defensive code generation. | 3338 // native type. In all of those cases we need defensive code generation. |
3319 var type = getStaticType(target); | 3339 var type = getStaticType(target); |
3320 return isNullable(target) || | 3340 return isNullable(target) || |
3321 type.isDynamic || | 3341 type.isDynamic || |
3322 (_extensionTypes.contains(type.element) && target is! SuperExpression); | 3342 (_extensionTypes.contains(type.element) && target is! SuperExpression); |
3323 } | 3343 } |
3324 | 3344 |
3325 /// Shared code for [PrefixedIdentifier] and [PropertyAccess]. | 3345 /// Shared code for [PrefixedIdentifier] and [PropertyAccess]. |
3326 JS.Expression _emitAccess(Expression target, SimpleIdentifier memberId) { | 3346 JS.Expression _emitAccess(Expression target, SimpleIdentifier memberId, DartTy pe resultType) { |
Harry Terkelsen
2016/04/29 23:04:11
long line
Jennifer Messerly
2016/04/29 23:08:14
huh, format must've not run, I'll see about that.
| |
3327 var member = memberId.staticElement; | 3347 Element member = memberId.staticElement; |
3328 if (member is PropertyAccessorElement) { | 3348 if (member is PropertyAccessorElement) { |
3329 member = (member as PropertyAccessorElement).variable; | 3349 member = (member as PropertyAccessorElement).variable; |
3330 } | 3350 } |
3331 bool isStatic = member is ClassMemberElement && member.isStatic; | 3351 bool isStatic = member is ClassMemberElement && member.isStatic; |
3332 var name = _emitMemberName(memberId.name, | 3352 var name = _emitMemberName(memberId.name, |
3333 type: getStaticType(target), isStatic: isStatic); | 3353 type: getStaticType(target), isStatic: isStatic); |
3334 if (DynamicInvoke.get(target)) { | 3354 if (DynamicInvoke.get(target)) { |
3335 return js.call('dart.dload(#, #)', [_visit(target), name]); | 3355 return js.call('dart.dload(#, #)', [_visit(target), name]); |
3336 } | 3356 } |
3337 | 3357 |
3338 if (target is SuperExpression && | 3358 var jsTarget = _visit(target); |
3339 member is FieldElement && | 3359 bool isSuper = jsTarget is JS.Super; |
3340 !member.isSynthetic) { | 3360 |
3361 if (isSuper && member is FieldElement && !member.isSynthetic) { | |
3341 // If super.x is actually a field, then x is an instance property since | 3362 // If super.x is actually a field, then x is an instance property since |
3342 // subclasses cannot override x. | 3363 // subclasses cannot override x. |
3343 return js.call('this.#', [name]); | 3364 jsTarget = new JS.This(); |
3344 } | 3365 } |
3345 | 3366 |
3346 String code; | 3367 JS.Expression result; |
3347 if (member != null && member is MethodElement && !isStatic) { | 3368 if (member != null && member is MethodElement && !isStatic) { |
3348 // Tear-off methods: explicitly bind it. | 3369 // Tear-off methods: explicitly bind it. |
3349 if (target is SuperExpression) { | 3370 if (isSuper) { |
3350 return js.call('dart.bind(this, #, #.#)', [name, _visit(target), name]); | 3371 result = js.call('dart.bind(this, #, #.#)', [name, jsTarget, name]); |
3351 } else if (_isObjectMemberCall(target, memberId.name)) { | 3372 } else if (_isObjectMemberCall(target, memberId.name)) { |
3352 return js.call('dart.bind(#, #, dart.#)', [_visit(target), name, name]); | 3373 result = js.call('dart.bind(#, #, dart.#)', [jsTarget, name, name]); |
3374 } else { | |
3375 result = js.call('dart.bind(#, #)', [jsTarget, name]); | |
3353 } | 3376 } |
3354 code = 'dart.bind(#, #)'; | |
3355 } else if (_isObjectMemberCall(target, memberId.name)) { | 3377 } else if (_isObjectMemberCall(target, memberId.name)) { |
3356 return js.call('dart.#(#)', [name, _visit(target)]); | 3378 result = js.call('dart.#(#)', [name, jsTarget]); |
3357 } else { | 3379 } else { |
3358 code = '#.#'; | 3380 result = js.call('#.#', [jsTarget, name]); |
3381 } | |
3382 return _applyFunctionTypeArguments(result, member, resultType); | |
3383 } | |
3384 | |
3385 /// If this is an inferred instantiation of a generic function/method, this | |
3386 /// will add the inferred type arguments. | |
3387 JS.Expression _applyFunctionTypeArguments( | |
3388 JS.Expression result, Element member, DartType instantiated) { | |
3389 | |
Harry Terkelsen
2016/04/29 23:04:11
unnecessary blank lines
| |
3390 | |
3391 DartType type; | |
3392 if (member is ExecutableElement) { | |
3393 type = member.type; | |
3394 } else if (member is VariableElement) { | |
3395 type = member.type; | |
3359 } | 3396 } |
3360 | 3397 |
3361 return js.call(code, [_visit(target), name]); | 3398 // TODO(jmesserly): handle explicitly passed type args. |
3399 if (type == null) return result; | |
3400 var typeArgs = _emitFunctionTypeArguments(type, instantiated); | |
3401 if (typeArgs == null) return result; | |
3402 return js.call('dart.gbind(#, #)', [result, typeArgs]); | |
3362 } | 3403 } |
3363 | 3404 |
3364 /// Emits a generic send, like an operator method. | 3405 /// Emits a generic send, like an operator method. |
3365 /// | 3406 /// |
3366 /// **Please note** this function does not support method invocation syntax | 3407 /// **Please note** this function does not support method invocation syntax |
3367 /// `obj.name(args)` because that could be a getter followed by a call. | 3408 /// `obj.name(args)` because that could be a getter followed by a call. |
3368 /// See [visitMethodInvocation]. | 3409 /// See [visitMethodInvocation]. |
3369 JS.Expression _emitSend( | 3410 JS.Expression _emitSend( |
3370 Expression target, String name, List<Expression> args) { | 3411 Expression target, String name, List<Expression> args) { |
3371 var type = getStaticType(target); | 3412 var type = getStaticType(target); |
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4057 } | 4098 } |
4058 | 4099 |
4059 bool isLibraryPrefix(Expression node) => | 4100 bool isLibraryPrefix(Expression node) => |
4060 node is SimpleIdentifier && node.staticElement is PrefixElement; | 4101 node is SimpleIdentifier && node.staticElement is PrefixElement; |
4061 | 4102 |
4062 LibraryElement _getLibrary(AnalysisContext c, String uri) => | 4103 LibraryElement _getLibrary(AnalysisContext c, String uri) => |
4063 c.computeLibraryElement(c.sourceFactory.forUri(uri)); | 4104 c.computeLibraryElement(c.sourceFactory.forUri(uri)); |
4064 | 4105 |
4065 bool _isDartRuntime(LibraryElement l) => | 4106 bool _isDartRuntime(LibraryElement l) => |
4066 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; | 4107 l.isInSdk && l.source.uri.toString() == 'dart:_runtime'; |
OLD | NEW |