Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(266)

Side by Side Diff: lib/src/compiler/code_generator.dart

Issue 1930323004: instantiate generic tear-offs, fixes #525 (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/runtime/dart_sdk.js ('k') | test/codegen/language/generic_tearoff_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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';
OLDNEW
« no previous file with comments | « lib/runtime/dart_sdk.js ('k') | test/codegen/language/generic_tearoff_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698