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

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

Issue 2988373002: Store parts in Kernel Library, resynthesize parts in Analyzer. (Closed)
Patch Set: Fixes for review comments. Created 3 years, 4 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) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, 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 'package:analyzer/dart/ast/ast.dart'; 5 import 'package:analyzer/dart/ast/ast.dart';
6 import 'package:analyzer/dart/ast/standard_ast_factory.dart'; 6 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
7 import 'package:analyzer/dart/ast/token.dart'; 7 import 'package:analyzer/dart/ast/token.dart';
8 import 'package:analyzer/dart/element/element.dart'; 8 import 'package:analyzer/dart/element/element.dart';
9 import 'package:analyzer/dart/element/type.dart'; 9 import 'package:analyzer/dart/element/type.dart';
10 import 'package:analyzer/src/dart/element/element.dart'; 10 import 'package:analyzer/src/dart/element/element.dart';
(...skipping 29 matching lines...) Expand all
40 /** 40 /**
41 * Return the [LibraryElementImpl] for the given [uriStr], or `null` if 41 * Return the [LibraryElementImpl] for the given [uriStr], or `null` if
42 * the library is not part of the Kernel libraries bundle. 42 * the library is not part of the Kernel libraries bundle.
43 */ 43 */
44 LibraryElementImpl getLibrary(String uriStr) { 44 LibraryElementImpl getLibrary(String uriStr) {
45 return _libraryMap.putIfAbsent(uriStr, () { 45 return _libraryMap.putIfAbsent(uriStr, () {
46 var kernel = _kernelMap[uriStr]; 46 var kernel = _kernelMap[uriStr];
47 if (kernel == null) return null; 47 if (kernel == null) return null;
48 48
49 var libraryContext = 49 var libraryContext =
50 new _KernelLibraryResynthesizerContextImpl(this, kernel); 50 new _KernelLibraryResynthesizerContextImpl(this, kernel, uriStr);
51 Source librarySource = _getSource(uriStr); 51 LibraryElementImpl libraryElement = libraryContext.libraryElement;
52 LibraryElementImpl libraryElement = 52
53 new LibraryElementImpl.forKernel(_analysisContext, libraryContext); 53 // Build the defining unit.
54 CompilationUnitElementImpl definingUnit = 54 var definingUnit = libraryContext._buildUnit(null).unit;
55 libraryElement.definingCompilationUnit; 55 libraryElement.definingCompilationUnit = definingUnit;
56 definingUnit.source = librarySource; 56
57 definingUnit.librarySource = librarySource; 57 // Build units for parts.
58 var parts = new List<CompilationUnitElementImpl>(kernel.parts.length);
59 for (int i = 0; i < kernel.parts.length; i++) {
60 var fileUri = kernel.parts[i].fileUri;
61 var unitContext = libraryContext._buildUnit(fileUri);
62 parts[i] = unitContext.unit;
63 }
64 libraryElement.parts = parts;
65
58 return libraryElement; 66 return libraryElement;
59 }); 67 });
60 } 68 }
61 69
62 /** 70 /**
71 * Return the [ElementImpl] that corresponds to the given [name], or `null`
72 * if the corresponding element cannot be found.
73 */
74 ElementImpl _getElement(kernel.CanonicalName name) {
75 if (name == null) return null;
76 kernel.CanonicalName parentName = name.parent;
77
78 // If the parent is the root, then this name is a library.
79 if (parentName.isRoot) {
80 return getLibrary(name.name);
81 }
82
83 // If the name is private, it is prefixed with a library URI.
ahe 2017/08/03 10:43:46 I don't understand this comment and how it relates
scheglov 2017/08/03 17:25:56 See the comment to CanonicalName. /// Qualif
84 if (name.name.startsWith('_')) {
85 parentName = parentName.parent;
86 }
87
88 // Skip qualifiers.
89 bool isGetter = false;
90 bool isSetter = false;
91 bool isField = false;
92 bool isConstructor = false;
93 bool isMethod = false;
94 if (parentName.name == '@getters') {
95 isGetter = true;
96 parentName = parentName.parent;
97 } else if (parentName.name == '@setters') {
98 isSetter = true;
99 parentName = parentName.parent;
100 } else if (parentName.name == '@fields') {
101 isField = true;
102 parentName = parentName.parent;
103 } else if (parentName.name == '@constructors') {
104 isConstructor = true;
105 parentName = parentName.parent;
106 } else if (parentName.name == '@methods') {
107 isMethod = true;
108 parentName = parentName.parent;
109 }
110
111 ElementImpl parentElement = _getElement(parentName);
112 if (parentElement == null) return null;
113
114 // Search in units of the library.
115 if (parentElement is LibraryElementImpl) {
116 for (CompilationUnitElement unit in parentElement.units) {
117 CompilationUnitElementImpl unitImpl = unit;
118 ElementImpl child = unitImpl.getChild(name.name);
119 if (child != null) {
120 return child;
121 }
122 }
123 return null;
124 }
125
126 // Search in the class.
127 if (parentElement is AbstractClassElementImpl) {
128 if (isGetter) {
129 return parentElement.getGetter(name.name) as ElementImpl;
130 } else if (isSetter) {
131 return parentElement.getSetter(name.name) as ElementImpl;
132 } else if (isField) {
133 return parentElement.getField(name.name) as ElementImpl;
134 } else if (isConstructor) {
135 if (name.name.isEmpty) {
136 return parentElement.unnamedConstructor as ConstructorElementImpl;
137 }
138 return parentElement.getNamedConstructor(name.name) as ElementImpl;
139 } else if (isMethod) {
140 return parentElement.getMethod(name.name) as ElementImpl;
141 }
142 return null;
143 }
144
145 throw new UnimplementedError('Should not be reached.');
ahe 2017/08/03 10:43:47 Consider using this message instead: "Internal er
scheglov 2017/08/03 17:25:56 Done.
146 }
147
148 /**
63 * Get the [Source] object for the given [uri]. 149 * Get the [Source] object for the given [uri].
64 */ 150 */
65 Source _getSource(String uri) { 151 Source _getSource(String uri) {
66 return _sources.putIfAbsent( 152 return _sources.putIfAbsent(
67 uri, () => _analysisContext.sourceFactory.forUri(uri)); 153 uri, () => _analysisContext.sourceFactory.forUri(uri));
68 } 154 }
69 } 155 }
70 156
71 /** 157 /**
72 * Builder of [Expression]s from [kernel.Expression]s. 158 * Builder of [Expression]s from [kernel.Expression]s.
73 */ 159 */
74 class _ExprBuilder { 160 class _ExprBuilder {
75 final _KernelLibraryResynthesizerContextImpl _context; 161 final _KernelUnitResynthesizerContextImpl _context;
76 final ElementImpl _contextElement; 162 final ElementImpl _contextElement;
77 163
78 _ExprBuilder(this._context, this._contextElement); 164 _ExprBuilder(this._context, this._contextElement);
79 165
80 Expression build(kernel.Expression expr) { 166 Expression build(kernel.Expression expr) {
81 if (expr is kernel.NullLiteral) { 167 if (expr is kernel.NullLiteral) {
82 return AstTestFactory.nullLiteral(); 168 return AstTestFactory.nullLiteral();
83 } 169 }
84 if (expr is kernel.BoolLiteral) { 170 if (expr is kernel.BoolLiteral) {
85 return AstTestFactory.booleanLiteral(expr.value); 171 return AstTestFactory.booleanLiteral(expr.value);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 List<Expression> arguments = _toArguments(expr.arguments); 275 List<Expression> arguments = _toArguments(expr.arguments);
190 MethodInvocation invocation = 276 MethodInvocation invocation =
191 AstTestFactory.methodInvocation3(null, name, null, arguments); 277 AstTestFactory.methodInvocation3(null, name, null, arguments);
192 invocation.methodName.staticElement = _getElement(target.reference); 278 invocation.methodName.staticElement = _getElement(target.reference);
193 return invocation; 279 return invocation;
194 } 280 }
195 281
196 if (expr is kernel.ConstructorInvocation) { 282 if (expr is kernel.ConstructorInvocation) {
197 var element = _getElement(expr.targetReference); 283 var element = _getElement(expr.targetReference);
198 284
199 var kernelType = expr.getStaticType(_context._resynthesizer._types); 285 var kernelType =
286 expr.getStaticType(_context.libraryContext.resynthesizer._types);
200 var type = _context.getType(_contextElement, kernelType); 287 var type = _context.getType(_contextElement, kernelType);
201 TypeName typeName = _buildType(type); 288 TypeName typeName = _buildType(type);
202 289
203 var constructorName = AstTestFactory.constructorName( 290 var constructorName = AstTestFactory.constructorName(
204 typeName, element.name.isNotEmpty ? element.name : null); 291 typeName, element.name.isNotEmpty ? element.name : null);
205 constructorName?.name?.staticElement = element; 292 constructorName?.name?.staticElement = element;
206 293
207 var keyword = expr.isConst ? Keyword.CONST : Keyword.NEW; 294 var keyword = expr.isConst ? Keyword.CONST : Keyword.NEW;
208 var arguments = _toArguments(expr.arguments); 295 var arguments = _toArguments(expr.arguments);
209 return AstTestFactory.instanceCreationExpression( 296 return AstTestFactory.instanceCreationExpression(
210 keyword, constructorName, arguments); 297 keyword, constructorName, arguments);
211 } 298 }
212 299
213 if (expr is kernel.TypeLiteral) { 300 if (expr is kernel.TypeLiteral) {
214 var type = _context.getType(_contextElement, expr.type); 301 var type = _context.getType(_contextElement, expr.type);
215 var identifier = AstTestFactory.identifier3(type.element.name); 302 var identifier = AstTestFactory.identifier3(type.element.name);
216 identifier.staticElement = type.element; 303 identifier.staticElement = type.element;
217 identifier.staticType = _context._resynthesizer.typeType; 304 identifier.staticType = _context.libraryContext.resynthesizer.typeType;
218 return identifier; 305 return identifier;
219 } 306 }
220 307
221 // TODO(scheglov): complete getExpression 308 // TODO(scheglov): complete getExpression
222 throw new UnimplementedError('kernel: (${expr.runtimeType}) $expr'); 309 throw new UnimplementedError('kernel: (${expr.runtimeType}) $expr');
223 } 310 }
224 311
225 ConstructorInitializer buildInitializer(kernel.Initializer k) { 312 ConstructorInitializer buildInitializer(kernel.Initializer k) {
226 if (k is kernel.FieldInitializer) { 313 if (k is kernel.FieldInitializer) {
227 Expression value = build(k.value); 314 Expression value = build(k.value);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 } 410 }
324 return AstTestFactory.typeArgumentList(types); 411 return AstTestFactory.typeArgumentList(types);
325 } 412 }
326 413
327 List<TypeAnnotation> _buildTypeArguments(List<DartType> types) { 414 List<TypeAnnotation> _buildTypeArguments(List<DartType> types) {
328 if (types.every((t) => t.isDynamic)) return null; 415 if (types.every((t) => t.isDynamic)) return null;
329 return types.map(_buildType).toList(); 416 return types.map(_buildType).toList();
330 } 417 }
331 418
332 ElementImpl _getElement(kernel.Reference reference) { 419 ElementImpl _getElement(kernel.Reference reference) {
333 return _context._getElement(reference?.canonicalName); 420 return _context.libraryContext.resynthesizer
421 ._getElement(reference?.canonicalName);
334 } 422 }
335 423
336 InterpolationElement _newInterpolationElement(Expression expr) { 424 InterpolationElement _newInterpolationElement(Expression expr) {
337 if (expr is SimpleStringLiteral) { 425 if (expr is SimpleStringLiteral) {
338 return astFactory.interpolationString(expr.literal, expr.value); 426 return astFactory.interpolationString(expr.literal, expr.value);
339 } else { 427 } else {
340 return AstTestFactory.interpolationExpression(expr); 428 return AstTestFactory.interpolationExpression(expr);
341 } 429 }
342 } 430 }
343 431
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 if (name == 'unary-') return TokenType.MINUS; 471 if (name == 'unary-') return TokenType.MINUS;
384 throw new ArgumentError(name); 472 throw new ArgumentError(name);
385 } 473 }
386 } 474 }
387 475
388 /** 476 /**
389 * Implementation of [KernelLibraryResynthesizerContext]. 477 * Implementation of [KernelLibraryResynthesizerContext].
390 */ 478 */
391 class _KernelLibraryResynthesizerContextImpl 479 class _KernelLibraryResynthesizerContextImpl
392 implements KernelLibraryResynthesizerContext { 480 implements KernelLibraryResynthesizerContext {
393 final KernelResynthesizer _resynthesizer; 481 final KernelResynthesizer resynthesizer;
394 482
395 @override 483 @override
396 final kernel.Library library; 484 final kernel.Library library;
397 485
398 _KernelLibraryResynthesizerContextImpl(this._resynthesizer, this.library); 486 Source librarySource;
487 LibraryElementImpl libraryElement;
488
489 _KernelLibraryResynthesizerContextImpl(
490 this.resynthesizer, this.library, String uriStr) {
491 librarySource = resynthesizer._getSource(uriStr);
ahe 2017/08/03 10:43:46 Move this line outside the constructor body.
scheglov 2017/08/03 17:25:56 Done.
492 libraryElement =
493 new LibraryElementImpl.forKernel(resynthesizer._analysisContext, this);
494 }
495
496 @override
497 LibraryElementImpl getLibrary(String uriStr) {
498 return resynthesizer.getLibrary(uriStr);
499 }
500
501 _KernelUnitResynthesizerContextImpl _buildUnit(String fileUri) {
502 var unitContext = new _KernelUnitResynthesizerContextImpl(
503 this, fileUri ?? library.fileUri);
504 var unitElement = new CompilationUnitElementImpl.forKernel(
505 libraryElement, unitContext, '<no name>');
506 unitContext.unit = unitElement;
507 unitElement.librarySource = librarySource;
508 unitElement.source =
509 fileUri != null ? resynthesizer._getSource(fileUri) : librarySource;
510 unitContext.unit = unitElement;
511 return unitContext;
512 }
513 }
514
515 /**
516 * Implementation of [KernelUnit].
517 */
518 class _KernelUnitImpl implements KernelUnit {
519 final _KernelUnitResynthesizerContextImpl context;
520
521 _KernelUnitImpl(this.context);
522
523 @override
524 Iterable<kernel.Class> get classes {
525 return context.libraryContext.library.classes
526 .where((n) => n.fileUri == context.fileUri);
ahe 2017/08/03 10:43:47 Stuff like this is potentially expensive and can t
scheglov 2017/08/03 17:25:55 Done.
527 }
528
529 @override
530 Iterable<kernel.Field> get fields {
531 return context.libraryContext.library.fields
532 .where((n) => n.fileUri == context.fileUri);
533 }
534
535 @override
536 Iterable<kernel.Procedure> get procedures {
537 return context.libraryContext.library.procedures
538 .where((n) => n.fileUri == context.fileUri);
539 }
540
541 @override
542 Iterable<kernel.Typedef> get typedefs {
543 return context.libraryContext.library.typedefs
544 .where((n) => n.fileUri == context.fileUri);
545 }
546 }
547
548 /**
549 * Implementation of [KernelUnitResynthesizerContext].
550 */
551 class _KernelUnitResynthesizerContextImpl
552 implements KernelUnitResynthesizerContext {
553 final _KernelLibraryResynthesizerContextImpl libraryContext;
554 final String fileUri;
555
556 CompilationUnitElementImpl unit;
557
558 _KernelUnitResynthesizerContextImpl(this.libraryContext, this.fileUri);
559
560 @override
561 KernelUnit get kernelUnit => new _KernelUnitImpl(this);
399 562
400 @override 563 @override
401 List<ElementAnnotation> buildAnnotations( 564 List<ElementAnnotation> buildAnnotations(
402 CompilationUnitElementImpl unit, List<kernel.Expression> expressions) { 565 List<kernel.Expression> expressions) {
403 int length = expressions.length; 566 int length = expressions.length;
404 if (length != 0) { 567 if (length != 0) {
405 var annotations = new List<ElementAnnotation>(length); 568 var annotations = new List<ElementAnnotation>(length);
406 for (int i = 0; i < length; i++) { 569 for (int i = 0; i < length; i++) {
407 annotations[i] = _buildAnnotation(unit, expressions[i]); 570 annotations[i] = _buildAnnotation(unit, expressions[i]);
408 } 571 }
409 return annotations; 572 return annotations;
410 } else { 573 } else {
411 return const <ElementAnnotation>[]; 574 return const <ElementAnnotation>[];
412 } 575 }
413 } 576 }
414 577
415 @override 578 @override
416 UnitExplicitTopLevelAccessors buildTopLevelAccessors( 579 UnitExplicitTopLevelAccessors buildTopLevelAccessors() {
417 CompilationUnitElementImpl unit) {
418 var accessorsData = new UnitExplicitTopLevelAccessors(); 580 var accessorsData = new UnitExplicitTopLevelAccessors();
419 var implicitVariables = <String, TopLevelVariableElementImpl>{}; 581 var implicitVariables = <String, TopLevelVariableElementImpl>{};
420 // Build explicit property accessors and implicit fields. 582 // Build explicit property accessors and implicit fields.
421 for (var procedure in library.procedures) { 583 for (var procedure in kernelUnit.procedures) {
422 bool isGetter = procedure.kind == kernel.ProcedureKind.Getter; 584 bool isGetter = procedure.kind == kernel.ProcedureKind.Getter;
423 bool isSetter = procedure.kind == kernel.ProcedureKind.Setter; 585 bool isSetter = procedure.kind == kernel.ProcedureKind.Setter;
424 if (isGetter || isSetter) { 586 if (isGetter || isSetter) {
425 var accessor = 587 var accessor =
426 new PropertyAccessorElementImpl.forKernel(unit, procedure); 588 new PropertyAccessorElementImpl.forKernel(unit, procedure);
427 accessorsData.accessors.add(accessor); 589 accessorsData.accessors.add(accessor);
428 590
429 // Create or update the implicit variable. 591 // Create or update the implicit variable.
430 String name = accessor.displayName; 592 String name = accessor.displayName;
431 TopLevelVariableElementImpl variable = implicitVariables[name]; 593 TopLevelVariableElementImpl variable = implicitVariables[name];
(...skipping 14 matching lines...) Expand all
446 } else { 608 } else {
447 variable.setter = accessor; 609 variable.setter = accessor;
448 } 610 }
449 } 611 }
450 } 612 }
451 accessorsData.implicitVariables.addAll(implicitVariables.values); 613 accessorsData.implicitVariables.addAll(implicitVariables.values);
452 return accessorsData; 614 return accessorsData;
453 } 615 }
454 616
455 @override 617 @override
456 UnitExplicitTopLevelVariables buildTopLevelVariables( 618 UnitExplicitTopLevelVariables buildTopLevelVariables() {
457 CompilationUnitElementImpl unit) { 619 List<kernel.Field> kernelFields = kernelUnit.fields.toList(growable: false);
ahe 2017/08/03 10:43:46 It's non-obvious that this API requires you to cal
scheglov 2017/08/03 17:25:55 Done.
458 int numberOfVariables = library.fields.length; 620 int numberOfVariables = kernelFields.length;
459 var variablesData = new UnitExplicitTopLevelVariables(numberOfVariables); 621 var variablesData = new UnitExplicitTopLevelVariables(numberOfVariables);
460 for (int i = 0; i < numberOfVariables; i++) { 622 for (int i = 0; i < numberOfVariables; i++) {
461 kernel.Field field = library.fields[i]; 623 kernel.Field field = kernelFields[i];
462 624
463 // Add the explicit variables. 625 // Add the explicit variables.
464 TopLevelVariableElementImpl variable; 626 TopLevelVariableElementImpl variable;
465 if (field.isConst && field.initializer != null) { 627 if (field.isConst && field.initializer != null) {
466 variable = new ConstTopLevelVariableElementImpl.forKernel(unit, field); 628 variable = new ConstTopLevelVariableElementImpl.forKernel(unit, field);
467 } else { 629 } else {
468 variable = new TopLevelVariableElementImpl.forKernel(unit, field); 630 variable = new TopLevelVariableElementImpl.forKernel(unit, field);
469 } 631 }
470 variablesData.variables[i] = variable; 632 variablesData.variables[i] = variable;
471 633
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 } 680 }
519 681
520 @override 682 @override
521 InterfaceType getInterfaceType( 683 InterfaceType getInterfaceType(
522 ElementImpl context, kernel.Supertype kernelType) { 684 ElementImpl context, kernel.Supertype kernelType) {
523 return _getInterfaceType( 685 return _getInterfaceType(
524 context, kernelType.className.canonicalName, kernelType.typeArguments); 686 context, kernelType.className.canonicalName, kernelType.typeArguments);
525 } 687 }
526 688
527 @override 689 @override
528 LibraryElement getLibrary(String uriStr) {
529 return _resynthesizer.getLibrary(uriStr);
530 }
531
532 @override
533 ConstructorElementImpl getRedirectedConstructor( 690 ConstructorElementImpl getRedirectedConstructor(
534 kernel.Constructor kernelConstructor, kernel.Procedure kernelFactory) { 691 kernel.Constructor kernelConstructor, kernel.Procedure kernelFactory) {
535 if (kernelConstructor != null) { 692 if (kernelConstructor != null) {
536 for (var initializer in kernelConstructor.initializers) { 693 for (var initializer in kernelConstructor.initializers) {
537 if (initializer is kernel.RedirectingInitializer) { 694 if (initializer is kernel.RedirectingInitializer) {
538 return _getElement(initializer.targetReference.canonicalName) 695 return libraryContext.resynthesizer
696 ._getElement(initializer.targetReference.canonicalName)
539 as ConstructorElementImpl; 697 as ConstructorElementImpl;
540 } 698 }
541 } 699 }
542 } 700 }
543 if (kernelFactory != null) { 701 if (kernelFactory != null) {
544 kernel.Statement body = kernelFactory.function.body; 702 kernel.Statement body = kernelFactory.function.body;
545 if (body is RedirectingFactoryBody) { 703 if (body is RedirectingFactoryBody) {
546 kernel.Member target = body.target; 704 kernel.Member target = body.target;
547 if (target != null) { 705 if (target != null) {
548 return _getElement(target.reference.canonicalName) 706 return libraryContext.resynthesizer
707 ._getElement(target.reference.canonicalName)
549 as ConstructorElementImpl; 708 as ConstructorElementImpl;
550 } 709 }
551 } 710 }
552 } 711 }
553 return null; 712 return null;
554 } 713 }
555 714
556 DartType getType(ElementImpl context, kernel.DartType kernelType) { 715 DartType getType(ElementImpl context, kernel.DartType kernelType) {
557 if (kernelType is kernel.DynamicType) return DynamicTypeImpl.instance; 716 if (kernelType is kernel.DynamicType) return DynamicTypeImpl.instance;
558 if (kernelType is kernel.VoidType) return VoidTypeImpl.instance; 717 if (kernelType is kernel.VoidType) return VoidTypeImpl.instance;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 elementAnnotation.annotationAst = AstTestFactory.annotation2( 764 elementAnnotation.annotationAst = AstTestFactory.annotation2(
606 typeName, constructorName, constExpr.argumentList) 765 typeName, constructorName, constExpr.argumentList)
607 ..element = constExpr.staticElement; 766 ..element = constExpr.staticElement;
608 } else { 767 } else {
609 throw new StateError( 768 throw new StateError(
610 'Unexpected annotation type: ${constExpr.runtimeType}'); 769 'Unexpected annotation type: ${constExpr.runtimeType}');
611 } 770 }
612 return elementAnnotation; 771 return elementAnnotation;
613 } 772 }
614 773
615 /**
616 * Return the [ElementImpl] that corresponds to the given [name], or `null`
617 * if the corresponding element cannot be found.
618 */
619 ElementImpl _getElement(kernel.CanonicalName name) {
ahe 2017/08/03 10:43:46 It would have been quicker for me to review this i
620 if (name == null) return null;
621 kernel.CanonicalName parentName = name.parent;
622
623 // If the parent is the root, then this name is a library.
624 if (parentName.isRoot) {
625 return _resynthesizer.getLibrary(name.name);
626 }
627
628 // If the name is private, it is prefixed with a library URI.
629 if (name.name.startsWith('_')) {
630 parentName = parentName.parent;
631 }
632
633 // Skip qualifiers.
634 bool isGetter = false;
635 bool isSetter = false;
636 bool isField = false;
637 bool isConstructor = false;
638 bool isMethod = false;
639 if (parentName.name == '@getters') {
640 isGetter = true;
641 parentName = parentName.parent;
642 } else if (parentName.name == '@setters') {
643 isSetter = true;
644 parentName = parentName.parent;
645 } else if (parentName.name == '@fields') {
646 isField = true;
647 parentName = parentName.parent;
648 } else if (parentName.name == '@constructors') {
649 isConstructor = true;
650 parentName = parentName.parent;
651 } else if (parentName.name == '@methods') {
652 isMethod = true;
653 parentName = parentName.parent;
654 }
655
656 ElementImpl parentElement = _getElement(parentName);
657 if (parentElement == null) return null;
658
659 // Search in units of the library.
660 if (parentElement is LibraryElementImpl) {
661 for (CompilationUnitElement unit in parentElement.units) {
662 CompilationUnitElementImpl unitImpl = unit;
663 ElementImpl child = unitImpl.getChild(name.name);
664 if (child != null) {
665 return child;
666 }
667 }
668 return null;
669 }
670
671 // Search in the class.
672 if (parentElement is AbstractClassElementImpl) {
673 if (isGetter) {
674 return parentElement.getGetter(name.name) as ElementImpl;
675 } else if (isSetter) {
676 return parentElement.getSetter(name.name) as ElementImpl;
677 } else if (isField) {
678 return parentElement.getField(name.name) as ElementImpl;
679 } else if (isConstructor) {
680 if (name.name.isEmpty) {
681 return parentElement.unnamedConstructor as ConstructorElementImpl;
682 }
683 return parentElement.getNamedConstructor(name.name) as ElementImpl;
684 } else if (isMethod) {
685 return parentElement.getMethod(name.name) as ElementImpl;
686 }
687 return null;
688 }
689
690 throw new UnimplementedError('Should not be reached.');
691 }
692
693 InterfaceType _getInterfaceType(ElementImpl context, 774 InterfaceType _getInterfaceType(ElementImpl context,
694 kernel.CanonicalName className, List<kernel.DartType> kernelArguments) { 775 kernel.CanonicalName className, List<kernel.DartType> kernelArguments) {
695 var libraryName = className.parent; 776 var libraryName = className.parent;
696 var libraryElement = _resynthesizer.getLibrary(libraryName.name); 777 var libraryElement = libraryContext.getLibrary(libraryName.name);
697 ClassElement classElement = libraryElement.getType(className.name); 778 ClassElement classElement = libraryElement.getType(className.name);
698 classElement ??= libraryElement.getEnum(className.name); 779 classElement ??= libraryElement.getEnum(className.name);
699 780
700 if (kernelArguments.isEmpty) { 781 if (kernelArguments.isEmpty) {
701 return classElement.type; 782 return classElement.type;
702 } 783 }
703 784
704 return new InterfaceTypeImpl.elementWithNameAndArgs( 785 return new InterfaceTypeImpl.elementWithNameAndArgs(
705 classElement, classElement.name, () { 786 classElement, classElement.name, () {
706 List<DartType> arguments = kernelArguments 787 List<DartType> arguments = kernelArguments
(...skipping 12 matching lines...) Expand all
719 for (var typeParameter in ctx.typeParameters) { 800 for (var typeParameter in ctx.typeParameters) {
720 if (typeParameter.name == name) { 801 if (typeParameter.name == name) {
721 return typeParameter; 802 return typeParameter;
722 } 803 }
723 } 804 }
724 } 805 }
725 } 806 }
726 throw new StateError('Not found $kernelTypeParameter in $context'); 807 throw new StateError('Not found $kernelTypeParameter in $context');
727 } 808 }
728 } 809 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698