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

Side by Side Diff: pkg/analyzer/lib/src/summary/resynthesize.dart

Issue 1859493002: Replace 'length' with more generic 'extractProperty' operation. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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
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 library summary_resynthesizer; 5 library summary_resynthesizer;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'package:analyzer/dart/ast/ast.dart'; 9 import 'package:analyzer/dart/ast/ast.dart';
10 import 'package:analyzer/dart/ast/token.dart'; 10 import 'package:analyzer/dart/ast/token.dart';
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 break; 431 break;
432 case UnlinkedConstOperation.makeUntypedMap: 432 case UnlinkedConstOperation.makeUntypedMap:
433 _pushMap(null); 433 _pushMap(null);
434 break; 434 break;
435 case UnlinkedConstOperation.makeTypedMap: 435 case UnlinkedConstOperation.makeTypedMap:
436 TypeName keyType = _newTypeName(); 436 TypeName keyType = _newTypeName();
437 TypeName valueType = _newTypeName(); 437 TypeName valueType = _newTypeName();
438 _pushMap(AstFactory.typeArgumentList(<TypeName>[keyType, valueType])); 438 _pushMap(AstFactory.typeArgumentList(<TypeName>[keyType, valueType]));
439 break; 439 break;
440 case UnlinkedConstOperation.pushReference: 440 case UnlinkedConstOperation.pushReference:
441 EntityRef ref = uc.references[refPtr++]; 441 _pushReference();
442 _ReferenceInfo info = resynthesizer.referenceInfos[ref.reference]; 442 break;
443 if (info.enclosing != null && 443 case UnlinkedConstOperation.extractProperty:
444 info.enclosing.element != null && 444 _pushExtractProperty();
445 info.enclosing.element is! ClassElement) {
446 SimpleIdentifier prefix = AstFactory.identifier3(
447 info.enclosing.name)..staticElement = info.enclosing.element;
448 SimpleIdentifier name = AstFactory.identifier3(info.name)
449 ..staticElement = info.element;
450 PrefixedIdentifier node = AstFactory.identifier(prefix, name);
451 _push(node);
452 } else {
453 SimpleIdentifier node = AstFactory.identifier3(info.name);
454 node.staticElement = info.element;
455 _push(node);
456 }
457 break; 445 break;
458 case UnlinkedConstOperation.invokeConstructor: 446 case UnlinkedConstOperation.invokeConstructor:
459 _pushInstanceCreation(); 447 _pushInstanceCreation();
460 break; 448 break;
461 case UnlinkedConstOperation.length:
462 Expression target = _pop();
463 SimpleIdentifier property = AstFactory.identifier3('length');
464 property.staticElement =
465 resynthesizer._buildStringLengthPropertyAccessorElement();
466 _push(AstFactory.propertyAccess(target, property));
467 break;
468 case UnlinkedConstOperation.pushConstructorParameter: 449 case UnlinkedConstOperation.pushConstructorParameter:
469 String name = uc.strings[stringPtr++]; 450 String name = uc.strings[stringPtr++];
470 SimpleIdentifier identifier = AstFactory.identifier3(name); 451 SimpleIdentifier identifier = AstFactory.identifier3(name);
471 identifier.staticElement = resynthesizer.currentConstructor.parameters 452 identifier.staticElement = resynthesizer.currentConstructor.parameters
472 .firstWhere((parameter) => parameter.name == name, 453 .firstWhere((parameter) => parameter.name == name,
473 orElse: () => throw new StateError( 454 orElse: () => throw new StateError(
474 'Unable to resolve constructor parameter: $name')); 455 'Unable to resolve constructor parameter: $name'));
475 _push(identifier); 456 _push(identifier);
476 break; 457 break;
477 } 458 }
478 } 459 }
479 return stack.single; 460 return stack.single;
480 } 461 }
481 462
463 /**
464 * Build the identifier sequence (a single or prefixed identifier, or a
465 * property access) corresponding to the given reference [info].
466 */
467 Expression _buildIdentifierSequence(_ReferenceInfo info) {
468 Expression enclosing;
469 if (info.enclosing != null) {
470 enclosing = _buildIdentifierSequence(info.enclosing);
471 }
472 Element element = info.element;
473 if (element == null && info.name == 'length') {
474 element = _getStringLengthElement();
475 }
476 if (enclosing == null) {
477 return AstFactory.identifier3(info.name)..staticElement = element;
478 }
479 if (enclosing is SimpleIdentifier) {
480 SimpleIdentifier identifier = AstFactory.identifier3(info.name)
481 ..staticElement = element;
482 return AstFactory.identifier(enclosing, identifier);
483 }
484 SimpleIdentifier property = AstFactory.identifier3(info.name)
485 ..staticElement = element;
486 return AstFactory.propertyAccess(enclosing, property);
487 }
488
482 TypeName _buildTypeAst(DartType type) { 489 TypeName _buildTypeAst(DartType type) {
483 List<TypeName> argumentNodes; 490 List<TypeName> argumentNodes;
484 if (type is ParameterizedType) { 491 if (type is ParameterizedType) {
485 List<DartType> typeArguments = type.typeArguments; 492 List<DartType> typeArguments = type.typeArguments;
486 argumentNodes = typeArguments.every((a) => a.isDynamic) 493 argumentNodes = typeArguments.every((a) => a.isDynamic)
487 ? null 494 ? null
488 : typeArguments.map(_buildTypeAst).toList(); 495 : typeArguments.map(_buildTypeAst).toList();
489 } 496 }
490 TypeName node = AstFactory.typeName4(type.name, argumentNodes); 497 TypeName node = AstFactory.typeName4(type.name, argumentNodes);
491 node.type = type; 498 node.type = type;
492 (node.name as SimpleIdentifier).staticElement = type.element; 499 (node.name as SimpleIdentifier).staticElement = type.element;
493 return node; 500 return node;
494 } 501 }
495 502
503 PropertyAccessorElement _getStringLengthElement() =>
504 resynthesizer.typeProvider.stringType.getGetter('length');
505
496 InterpolationElement _newInterpolationElement(Expression expr) { 506 InterpolationElement _newInterpolationElement(Expression expr) {
497 if (expr is SimpleStringLiteral) { 507 if (expr is SimpleStringLiteral) {
498 return new InterpolationString(expr.literal, expr.value); 508 return new InterpolationString(expr.literal, expr.value);
499 } else { 509 } else {
500 return new InterpolationExpression( 510 return new InterpolationExpression(
501 TokenFactory.tokenFromType(TokenType.STRING_INTERPOLATION_EXPRESSION), 511 TokenFactory.tokenFromType(TokenType.STRING_INTERPOLATION_EXPRESSION),
502 expr, 512 expr,
503 TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET)); 513 TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET));
504 } 514 }
505 } 515 }
(...skipping 13 matching lines...) Expand all
519 void _push(Expression expr) { 529 void _push(Expression expr) {
520 stack.add(expr); 530 stack.add(expr);
521 } 531 }
522 532
523 void _pushBinary(TokenType operator) { 533 void _pushBinary(TokenType operator) {
524 Expression right = _pop(); 534 Expression right = _pop();
525 Expression left = _pop(); 535 Expression left = _pop();
526 _push(AstFactory.binaryExpression(left, operator, right)); 536 _push(AstFactory.binaryExpression(left, operator, right));
527 } 537 }
528 538
539 void _pushExtractProperty() {
540 Expression target = _pop();
541 String name = uc.strings[stringPtr++];
542 // TODO(scheglov) Only String.length property access is supported.
543 assert(name == 'length');
544 _push(AstFactory.propertyAccess(
545 target,
546 AstFactory.identifier3('length')
547 ..staticElement = _getStringLengthElement()));
548 }
549
529 void _pushInstanceCreation() { 550 void _pushInstanceCreation() {
530 EntityRef ref = uc.references[refPtr++]; 551 EntityRef ref = uc.references[refPtr++];
531 _ReferenceInfo info = resynthesizer.referenceInfos[ref.reference]; 552 _ReferenceInfo info = resynthesizer.referenceInfos[ref.reference];
532 // prepare ConstructorElement 553 // prepare ConstructorElement
533 TypeName typeNode; 554 TypeName typeNode;
534 String constructorName; 555 String constructorName;
535 ConstructorElement constructorElement; 556 ConstructorElement constructorElement;
536 if (info.element != null) { 557 if (info.element != null) {
537 if (info.element is ConstructorElement) { 558 if (info.element is ConstructorElement) {
538 constructorName = info.name; 559 constructorName = info.name;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 entries.insert(0, AstFactory.mapLiteralEntry2(key, value)); 644 entries.insert(0, AstFactory.mapLiteralEntry2(key, value));
624 } 645 }
625 _push(AstFactory.mapLiteral(Keyword.CONST, typeArguments, entries)); 646 _push(AstFactory.mapLiteral(Keyword.CONST, typeArguments, entries));
626 } 647 }
627 648
628 void _pushPrefix(TokenType operator) { 649 void _pushPrefix(TokenType operator) {
629 Expression operand = _pop(); 650 Expression operand = _pop();
630 _push(AstFactory.prefixExpression(operator, operand)); 651 _push(AstFactory.prefixExpression(operator, operand));
631 } 652 }
632 653
654 void _pushReference() {
655 EntityRef ref = uc.references[refPtr++];
656 _ReferenceInfo info = resynthesizer.referenceInfos[ref.reference];
657 Expression node = _buildIdentifierSequence(info);
658 _push(node);
659 }
660
633 List<Expression> _removeTopItems(int count) { 661 List<Expression> _removeTopItems(int count) {
634 int start = stack.length - count; 662 int start = stack.length - count;
635 int end = stack.length; 663 int end = stack.length;
636 List<Expression> items = stack.getRange(start, end).toList(); 664 List<Expression> items = stack.getRange(start, end).toList();
637 stack.removeRange(start, end); 665 stack.removeRange(start, end);
638 return items; 666 return items;
639 } 667 }
640 } 668 }
641 669
642 /** 670 /**
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 summaryResynthesizer, location); 986 summaryResynthesizer, location);
959 case ReferenceKind.topLevelFunction: 987 case ReferenceKind.topLevelFunction:
960 return new FunctionElementHandle(summaryResynthesizer, location); 988 return new FunctionElementHandle(summaryResynthesizer, location);
961 case ReferenceKind.topLevelPropertyAccessor: 989 case ReferenceKind.topLevelPropertyAccessor:
962 return new PropertyAccessorElementHandle( 990 return new PropertyAccessorElementHandle(
963 summaryResynthesizer, location); 991 summaryResynthesizer, location);
964 case ReferenceKind.constructor: 992 case ReferenceKind.constructor:
965 case ReferenceKind.function: 993 case ReferenceKind.function:
966 case ReferenceKind.propertyAccessor: 994 case ReferenceKind.propertyAccessor:
967 case ReferenceKind.method: 995 case ReferenceKind.method:
968 case ReferenceKind.length:
969 case ReferenceKind.prefix: 996 case ReferenceKind.prefix:
970 case ReferenceKind.unresolved: 997 case ReferenceKind.unresolved:
971 case ReferenceKind.variable: 998 case ReferenceKind.variable:
972 // Should never happen. Exported names never refer to import prefixes, 999 // Should never happen. Exported names never refer to import prefixes,
973 // and they always refer to defined top-level entities. 1000 // and they always refer to defined top-level entities.
974 throw new StateError('Unexpected export name kind: ${exportName.kind}'); 1001 throw new StateError('Unexpected export name kind: ${exportName.kind}');
975 } 1002 }
976 } 1003 }
977 1004
978 /** 1005 /**
(...skipping 1020 matching lines...) Expand 10 before | Expand all | Expand 10 after
1999 serializedLabel.nameOffset, 2026 serializedLabel.nameOffset,
2000 serializedLabel.isOnSwitchStatement, 2027 serializedLabel.isOnSwitchStatement,
2001 serializedLabel.isOnSwitchMember); 2028 serializedLabel.isOnSwitchMember);
2002 } 2029 }
2003 2030
2004 /** 2031 /**
2005 * Resynthesize a [LocalVariableElement]. 2032 * Resynthesize a [LocalVariableElement].
2006 */ 2033 */
2007 LocalVariableElement buildLocalVariable(UnlinkedVariable serializedVariable) { 2034 LocalVariableElement buildLocalVariable(UnlinkedVariable serializedVariable) {
2008 LocalVariableElementImpl element; 2035 LocalVariableElementImpl element;
2009 if (serializedVariable.constExpr != null) { 2036 if (serializedVariable.constExpr != null && serializedVariable.isConst) {
2010 ConstLocalVariableElementImpl constElement = 2037 ConstLocalVariableElementImpl constElement =
2011 new ConstLocalVariableElementImpl( 2038 new ConstLocalVariableElementImpl(
2012 serializedVariable.name, serializedVariable.nameOffset); 2039 serializedVariable.name, serializedVariable.nameOffset);
2013 element = constElement; 2040 element = constElement;
2014 constElement.constantInitializer = 2041 constElement.constantInitializer =
2015 _buildConstExpression(serializedVariable.constExpr); 2042 _buildConstExpression(serializedVariable.constExpr);
2016 } else { 2043 } else {
2017 element = new LocalVariableElementImpl( 2044 element = new LocalVariableElementImpl(
2018 serializedVariable.name, serializedVariable.nameOffset); 2045 serializedVariable.name, serializedVariable.nameOffset);
2019 } 2046 }
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
2226 return typeParameters; 2253 return typeParameters;
2227 } 2254 }
2228 2255
2229 /** 2256 /**
2230 * Resynthesize a [TopLevelVariableElement] or [FieldElement]. 2257 * Resynthesize a [TopLevelVariableElement] or [FieldElement].
2231 */ 2258 */
2232 void buildVariable(UnlinkedVariable serializedVariable, 2259 void buildVariable(UnlinkedVariable serializedVariable,
2233 [ElementHolder holder]) { 2260 [ElementHolder holder]) {
2234 if (holder == null) { 2261 if (holder == null) {
2235 TopLevelVariableElementImpl element; 2262 TopLevelVariableElementImpl element;
2236 if (serializedVariable.constExpr != null) { 2263 if (serializedVariable.constExpr != null && serializedVariable.isConst) {
2237 ConstTopLevelVariableElementImpl constElement = 2264 ConstTopLevelVariableElementImpl constElement =
2238 new ConstTopLevelVariableElementImpl( 2265 new ConstTopLevelVariableElementImpl(
2239 serializedVariable.name, serializedVariable.nameOffset); 2266 serializedVariable.name, serializedVariable.nameOffset);
2240 element = constElement; 2267 element = constElement;
2241 constElement.constantInitializer = 2268 constElement.constantInitializer =
2242 _buildConstExpression(serializedVariable.constExpr); 2269 _buildConstExpression(serializedVariable.constExpr);
2243 } else { 2270 } else {
2244 element = new TopLevelVariableElementImpl( 2271 element = new TopLevelVariableElementImpl(
2245 serializedVariable.name, serializedVariable.nameOffset); 2272 serializedVariable.name, serializedVariable.nameOffset);
2246 } 2273 }
2247 buildPropertyIntroducingElementCommonParts(element, serializedVariable); 2274 buildPropertyIntroducingElementCommonParts(element, serializedVariable);
2248 unitHolder.addTopLevelVariable(element); 2275 unitHolder.addTopLevelVariable(element);
2249 buildImplicitAccessors(element, unitHolder); 2276 buildImplicitAccessors(element, unitHolder);
2250 } else { 2277 } else {
2251 FieldElementImpl element; 2278 FieldElementImpl element;
2252 if (serializedVariable.constExpr != null) { 2279 if (serializedVariable.constExpr != null &&
2280 (serializedVariable.isConst ||
2281 serializedVariable.isFinal && !serializedVariable.isStatic)) {
2253 ConstFieldElementImpl constElement = new ConstFieldElementImpl( 2282 ConstFieldElementImpl constElement = new ConstFieldElementImpl(
2254 serializedVariable.name, serializedVariable.nameOffset); 2283 serializedVariable.name, serializedVariable.nameOffset);
2255 element = constElement; 2284 element = constElement;
2256 constElement.constantInitializer = 2285 constElement.constantInitializer =
2257 _buildConstExpression(serializedVariable.constExpr); 2286 _buildConstExpression(serializedVariable.constExpr);
2258 } else { 2287 } else {
2259 element = new FieldElementImpl( 2288 element = new FieldElementImpl(
2260 serializedVariable.name, serializedVariable.nameOffset); 2289 serializedVariable.name, serializedVariable.nameOffset);
2261 } 2290 }
2262 buildPropertyIntroducingElementCommonParts(element, serializedVariable); 2291 buildPropertyIntroducingElementCommonParts(element, serializedVariable);
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
2402 } 2431 }
2403 switch (linkedReference.kind) { 2432 switch (linkedReference.kind) {
2404 case ReferenceKind.classOrEnum: 2433 case ReferenceKind.classOrEnum:
2405 element = new ClassElementHandle(summaryResynthesizer, location); 2434 element = new ClassElementHandle(summaryResynthesizer, location);
2406 break; 2435 break;
2407 case ReferenceKind.constructor: 2436 case ReferenceKind.constructor:
2408 assert(location.components.length == 4); 2437 assert(location.components.length == 4);
2409 element = 2438 element =
2410 new ConstructorElementHandle(summaryResynthesizer, location); 2439 new ConstructorElementHandle(summaryResynthesizer, location);
2411 break; 2440 break;
2412 case ReferenceKind.length:
2413 element = _buildStringLengthPropertyAccessorElement();
2414 break;
2415 case ReferenceKind.method: 2441 case ReferenceKind.method:
2416 assert(location.components.length == 4); 2442 assert(location.components.length == 4);
2417 element = new MethodElementHandle(summaryResynthesizer, location); 2443 element = new MethodElementHandle(summaryResynthesizer, location);
2418 break; 2444 break;
2419 case ReferenceKind.propertyAccessor: 2445 case ReferenceKind.propertyAccessor:
2420 assert(location.components.length == 4); 2446 assert(location.components.length == 4);
2421 element = new PropertyAccessorElementHandle( 2447 element = new PropertyAccessorElementHandle(
2422 summaryResynthesizer, location); 2448 summaryResynthesizer, location);
2423 break; 2449 break;
2424 case ReferenceKind.topLevelFunction: 2450 case ReferenceKind.topLevelFunction:
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2532 } 2558 }
2533 } 2559 }
2534 } 2560 }
2535 } 2561 }
2536 2562
2537 Expression _buildConstExpression(UnlinkedConst uc) { 2563 Expression _buildConstExpression(UnlinkedConst uc) {
2538 return new _ConstExprBuilder(this, uc).build(); 2564 return new _ConstExprBuilder(this, uc).build();
2539 } 2565 }
2540 2566
2541 /** 2567 /**
2542 * Return the new handle of the `String.length` getter element.
2543 */
2544 PropertyAccessorElementHandle _buildStringLengthPropertyAccessorElement() =>
2545 new PropertyAccessorElementHandle(
2546 summaryResynthesizer,
2547 new ElementLocationImpl.con3(
2548 <String>['dart:core', 'dart:core', 'String', 'length?']));
2549
2550 /**
2551 * Return the defining type for a [ConstructorElement] by applying 2568 * Return the defining type for a [ConstructorElement] by applying
2552 * [typeArgumentRefs] to the given linked [info]. 2569 * [typeArgumentRefs] to the given linked [info].
2553 */ 2570 */
2554 InterfaceType _createConstructorDefiningType( 2571 InterfaceType _createConstructorDefiningType(
2555 _ReferenceInfo info, List<EntityRef> typeArgumentRefs) { 2572 _ReferenceInfo info, List<EntityRef> typeArgumentRefs) {
2556 bool isClass = info.element is ClassElement; 2573 bool isClass = info.element is ClassElement;
2557 _ReferenceInfo classInfo = isClass ? info : info.enclosing; 2574 _ReferenceInfo classInfo = isClass ? info : info.enclosing;
2558 List<DartType> typeArguments = typeArgumentRefs.map(buildType).toList(); 2575 List<DartType> typeArguments = typeArgumentRefs.map(buildType).toList();
2559 return classInfo.buildType((i) { 2576 return classInfo.buildType((i) {
2560 if (i < typeArguments.length) { 2577 if (i < typeArguments.length) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2592 static String _getElementIdentifier(String name, ReferenceKind kind) { 2609 static String _getElementIdentifier(String name, ReferenceKind kind) {
2593 if (kind == ReferenceKind.topLevelPropertyAccessor || 2610 if (kind == ReferenceKind.topLevelPropertyAccessor ||
2594 kind == ReferenceKind.propertyAccessor) { 2611 kind == ReferenceKind.propertyAccessor) {
2595 if (!name.endsWith('=')) { 2612 if (!name.endsWith('=')) {
2596 return name + '?'; 2613 return name + '?';
2597 } 2614 }
2598 } 2615 }
2599 return name; 2616 return name;
2600 } 2617 }
2601 } 2618 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698