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

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

Issue 1845403003: Begin implementing type inference for AST summaries. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Break a long line. 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
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/task/dart.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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 /** 5 /**
6 * This library is capable of producing linked summaries from unlinked 6 * This library is capable of producing linked summaries from unlinked
7 * ones (or prelinked ones). It functions by building a miniature 7 * ones (or prelinked ones). It functions by building a miniature
8 * element model to represent the contents of the summaries, and then 8 * element model to represent the contents of the summaries, and then
9 * scanning the element model to gather linked information and adding 9 * scanning the element model to gather linked information and adding
10 * it to the summary data structures. 10 * it to the summary data structures.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 * use Tarjan's strongly connected components algorithm to detect 51 * use Tarjan's strongly connected components algorithm to detect
52 * cycles. 52 * cycles.
53 * 53 *
54 * - As much as possible, bookkeeping data is pointed to directly by 54 * - As much as possible, bookkeeping data is pointed to directly by
55 * the element objects, rather than being stored in maps. 55 * the element objects, rather than being stored in maps.
56 * 56 *
57 * - Where possible, we favor method dispatch instead of "is" and "as" 57 * - Where possible, we favor method dispatch instead of "is" and "as"
58 * checks. E.g. see [ReferenceableElementForLink.asConstructor]. 58 * checks. E.g. see [ReferenceableElementForLink.asConstructor].
59 */ 59 */
60 60
61 import 'package:analyzer/dart/ast/ast.dart';
61 import 'package:analyzer/dart/element/element.dart'; 62 import 'package:analyzer/dart/element/element.dart';
62 import 'package:analyzer/dart/element/type.dart'; 63 import 'package:analyzer/dart/element/type.dart';
64 import 'package:analyzer/src/dart/constant/value.dart';
65 import 'package:analyzer/src/dart/element/element.dart';
63 import 'package:analyzer/src/dart/element/type.dart'; 66 import 'package:analyzer/src/dart/element/type.dart';
67 import 'package:analyzer/src/generated/resolver.dart';
64 import 'package:analyzer/src/generated/utilities_dart.dart'; 68 import 'package:analyzer/src/generated/utilities_dart.dart';
65 import 'package:analyzer/src/summary/format.dart'; 69 import 'package:analyzer/src/summary/format.dart';
66 import 'package:analyzer/src/summary/idl.dart'; 70 import 'package:analyzer/src/summary/idl.dart';
67 import 'package:analyzer/src/summary/prelink.dart'; 71 import 'package:analyzer/src/summary/prelink.dart';
72 import 'package:analyzer/src/task/strong_mode.dart';
68 73
69 /** 74 /**
70 * Link together the build unit consisting of [libraryUris], using 75 * Link together the build unit consisting of [libraryUris], using
71 * [getDependency] to fetch the [LinkedLibrary] objects from other 76 * [getDependency] to fetch the [LinkedLibrary] objects from other
72 * build units, and [getUnit] to fetch the [UnlinkedUnit] objects from 77 * build units, and [getUnit] to fetch the [UnlinkedUnit] objects from
73 * both this build unit and other build units. 78 * both this build unit and other build units.
74 * 79 *
80 * The [strong] flag controls whether type inference is performed in strong
81 * mode or spec mode. Note that in spec mode, the only types that are inferred
82 * are the types of initializing formals, which are inferred from the types of
83 * the corresponding fields.
84 *
75 * A map is returned whose keys are the URIs of the libraries in this 85 * A map is returned whose keys are the URIs of the libraries in this
76 * build unit, and whose values are the corresponding 86 * build unit, and whose values are the corresponding
77 * [LinkedLibraryBuilder]s. 87 * [LinkedLibraryBuilder]s.
78 */ 88 */
79 Map<String, LinkedLibraryBuilder> link(Set<String> libraryUris, 89 Map<String, LinkedLibraryBuilder> link(Set<String> libraryUris,
80 GetDependencyCallback getDependency, GetUnitCallback getUnit) { 90 GetDependencyCallback getDependency, GetUnitCallback getUnit, bool strong) {
81 Map<String, LinkedLibraryBuilder> linkedLibraries = 91 Map<String, LinkedLibraryBuilder> linkedLibraries =
82 <String, LinkedLibraryBuilder>{}; 92 <String, LinkedLibraryBuilder>{};
83 for (String absoluteUri in libraryUris) { 93 for (String absoluteUri in libraryUris) {
84 Uri uri = Uri.parse(absoluteUri); 94 Uri uri = Uri.parse(absoluteUri);
85 UnlinkedUnit getRelativeUnit(String relativeUri) => 95 UnlinkedUnit getRelativeUnit(String relativeUri) =>
86 getUnit(resolveRelativeUri(uri, Uri.parse(relativeUri)).toString()); 96 getUnit(resolveRelativeUri(uri, Uri.parse(relativeUri)).toString());
87 linkedLibraries[absoluteUri] = prelink( 97 linkedLibraries[absoluteUri] = prelink(
88 getUnit(absoluteUri), 98 getUnit(absoluteUri),
89 getRelativeUnit, 99 getRelativeUnit,
90 (String relativeUri) => getRelativeUnit(relativeUri)?.publicNamespace); 100 (String relativeUri) => getRelativeUnit(relativeUri)?.publicNamespace);
91 } 101 }
92 relink(linkedLibraries, getDependency, getUnit); 102 relink(linkedLibraries, getDependency, getUnit, strong);
93 return linkedLibraries; 103 return linkedLibraries;
94 } 104 }
95 105
96 /** 106 /**
97 * Given [libraries] (a map from URI to [LinkedLibraryBuilder] 107 * Given [libraries] (a map from URI to [LinkedLibraryBuilder]
98 * containing correct prelinked information), rebuild linked 108 * containing correct prelinked information), rebuild linked
99 * information, using [getDependency] to fetch the [LinkedLibrary] 109 * information, using [getDependency] to fetch the [LinkedLibrary]
100 * objects from other build units, and [getUnit] to fetch the 110 * objects from other build units, and [getUnit] to fetch the
101 * [UnlinkedUnit] objects from both this build unit and other build 111 * [UnlinkedUnit] objects from both this build unit and other build
102 * units. 112 * units.
113 *
114 * The [strong] flag controls whether type inference is performed in strong
115 * mode or spec mode. Note that in spec mode, the only types that are inferred
116 * are the types of initializing formals, which are inferred from the types of
117 * the corresponding fields.
103 */ 118 */
104 void relink(Map<String, LinkedLibraryBuilder> libraries, 119 void relink(Map<String, LinkedLibraryBuilder> libraries,
105 GetDependencyCallback getDependency, GetUnitCallback getUnit) { 120 GetDependencyCallback getDependency, GetUnitCallback getUnit, bool strong) {
106 new _Linker(libraries, getDependency, getUnit).link(); 121 new _Linker(libraries, getDependency, getUnit, strong).link();
107 } 122 }
108 123
109 /** 124 /**
125 * Create an [EntityRefBuilder] representing the given [type], in a form
126 * suitable for inclusion in [LinkedUnit.types]. [compilationUnit] is the
127 * compilation unit in which the type will be used. If [slot] is provided, it
128 * is stored in [EntityRefBuilder.slot].
129 */
130 EntityRefBuilder _createLinkedType(
131 DartType type, CompilationUnitElementInBuildUnit compilationUnit,
132 {int slot}) {
133 EntityRefBuilder result = new EntityRefBuilder(slot: slot);
134 if (type is InterfaceType) {
135 ClassElementForLink element = type.element;
136 int dependency = compilationUnit.library.addDependency(element.library);
137 result.reference = compilationUnit.addReference(dependency, element.name,
138 element.typeParameters.length, element.enclosingElement.unitNum);
139 if (element.typeParameters.isNotEmpty) {
140 // TODO(paulberry): implement.
141 throw new UnimplementedError();
142 }
143 return result;
144 }
145 throw new UnimplementedError('${type.runtimeType}');
146 }
147
148 /**
110 * Type of the callback used by [link] and [relink] to request 149 * Type of the callback used by [link] and [relink] to request
111 * [LinkedLibrary] objects from other build units. 150 * [LinkedLibrary] objects from other build units.
112 */ 151 */
113 typedef LinkedLibrary GetDependencyCallback(String absoluteUri); 152 typedef LinkedLibrary GetDependencyCallback(String absoluteUri);
114 153
115 /** 154 /**
116 * Type of the callback used by [link] and [relink] to request 155 * Type of the callback used by [link] and [relink] to request
117 * [UnlinkedUnit] objects. 156 * [UnlinkedUnit] objects.
118 */ 157 */
119 typedef UnlinkedUnit GetUnitCallback(String absoluteUri); 158 typedef UnlinkedUnit GetUnitCallback(String absoluteUri);
120 159
121 /** 160 /**
122 * Element representing a class or enum resynthesized from a summary 161 * Element representing a class or enum resynthesized from a summary
123 * during linking. 162 * during linking.
124 */ 163 */
125 abstract class ClassElementForLink 164 abstract class ClassElementForLink
126 implements ClassElement, ReferenceableElementForLink { 165 implements ClassElementImpl, ReferenceableElementForLink {
127 Map<String, ReferenceableElementForLink> _containedNames; 166 Map<String, ReferenceableElementForLink> _containedNames;
128 167
129 @override 168 @override
169 final CompilationUnitElementForLink enclosingElement;
170
171 @override
172 bool hasBeenInferred = false;
173
174 ClassElementForLink(this.enclosingElement);
175
176 @override
130 ConstructorElementForLink get asConstructor => unnamedConstructor; 177 ConstructorElementForLink get asConstructor => unnamedConstructor;
131 178
132 @override 179 @override
133 ConstVariableNode get asConstVariable { 180 ConstVariableNode get asConstVariable {
134 // When a class name is used as a constant variable, it doesn't depend on 181 // When a class name is used as a constant variable, it doesn't depend on
135 // anything, so it is not necessary to include it in the constant 182 // anything, so it is not necessary to include it in the constant
136 // dependency graph. 183 // dependency graph.
137 return null; 184 return null;
138 } 185 }
139 186
140 @override 187 @override
141 List<ConstructorElementForLink> get constructors; 188 List<ConstructorElementForLink> get constructors;
142 189
143 @override 190 @override
144 List<FieldElementForLink> get fields; 191 List<FieldElementForLink> get fields;
145 192
146 /** 193 /**
147 * Indicates whether this is the core class `Object`. 194 * Indicates whether this is the core class `Object`.
148 */ 195 */
149 bool get isObject; 196 bool get isObject;
150 197
151 @override 198 @override
199 LibraryElementForLink get library => enclosingElement.library;
200
201 @override
152 String get name; 202 String get name;
153 203
154 @override 204 @override
155 ConstructorElementForLink get unnamedConstructor; 205 ConstructorElementForLink get unnamedConstructor;
156 206
157 @override 207 @override
158 ReferenceableElementForLink getContainedName(String name) { 208 ReferenceableElementForLink getContainedName(String name) {
159 if (_containedNames == null) { 209 if (_containedNames == null) {
160 _containedNames = <String, ReferenceableElementForLink>{}; 210 _containedNames = <String, ReferenceableElementForLink>{};
161 // TODO(paulberry): what's the correct way to handle name conflicts? 211 // TODO(paulberry): what's the correct way to handle name conflicts?
(...skipping 14 matching lines...) Expand all
176 } 226 }
177 227
178 /** 228 /**
179 * Perform type inference and cycle detection on this class and 229 * Perform type inference and cycle detection on this class and
180 * store the resulting information in the enclosing elements. 230 * store the resulting information in the enclosing elements.
181 */ 231 */
182 void link(LinkedUnitBuilder linkedUnit); 232 void link(LinkedUnitBuilder linkedUnit);
183 233
184 @override 234 @override
185 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); 235 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
236
237 /**
238 * Throw away any information produced by a previous call to [link].
239 */
240 void unlink();
186 } 241 }
187 242
188 /** 243 /**
189 * Element representing a class resynthesized from a summary during 244 * Element representing a class resynthesized from a summary during
190 * linking. 245 * linking.
191 */ 246 */
192 class ClassElementForLink_Class extends ClassElementForLink 247 class ClassElementForLink_Class extends ClassElementForLink
193 implements TypeParameterContext { 248 implements TypeParameterContext {
194 /** 249 /**
195 * The unlinked representation of the class in the summary. 250 * The unlinked representation of the class in the summary.
196 */ 251 */
197 final UnlinkedClass _unlinkedClass; 252 final UnlinkedClass _unlinkedClass;
198 253
199 @override
200 final CompilationUnitElementForLink enclosingElement;
201
202 List<ConstructorElementForLink> _constructors; 254 List<ConstructorElementForLink> _constructors;
203 ConstructorElementForLink _unnamedConstructor; 255 ConstructorElementForLink _unnamedConstructor;
204 bool _unnamedConstructorComputed = false; 256 bool _unnamedConstructorComputed = false;
205 List<FieldElementForLink_ClassField> _fields; 257 List<FieldElementForLink_ClassField> _fields;
206 InterfaceType _supertype; 258 InterfaceType _supertype;
207 InterfaceType _type; 259 InterfaceType _type;
260 List<TypeParameterElementForLink> _typeParameters;
208 List<TypeParameterType> _typeParameterTypes; 261 List<TypeParameterType> _typeParameterTypes;
262 List<MethodElementForLink> _methods;
263 List<InterfaceType> _mixins;
264 List<InterfaceType> _interfaces;
209 265
210 ClassElementForLink_Class(this.enclosingElement, this._unlinkedClass); 266 ClassElementForLink_Class(
267 CompilationUnitElementForLink enclosingElement, this._unlinkedClass)
268 : super(enclosingElement);
269
270 @override
271 List<PropertyAccessorElement> get accessors {
272 // TODO(paulberry): implement
273 return const [];
274 }
211 275
212 @override 276 @override
213 List<ConstructorElementForLink> get constructors { 277 List<ConstructorElementForLink> get constructors {
214 if (_constructors == null) { 278 if (_constructors == null) {
215 _constructors = <ConstructorElementForLink>[]; 279 _constructors = <ConstructorElementForLink>[];
216 for (UnlinkedExecutable unlinkedExecutable 280 for (UnlinkedExecutable unlinkedExecutable
217 in _unlinkedClass.executables) { 281 in _unlinkedClass.executables) {
218 if (unlinkedExecutable.kind == UnlinkedExecutableKind.constructor) { 282 if (unlinkedExecutable.kind == UnlinkedExecutableKind.constructor) {
219 _constructors 283 _constructors
220 .add(new ConstructorElementForLink(this, unlinkedExecutable)); 284 .add(new ConstructorElementForLink(this, unlinkedExecutable));
(...skipping 11 matching lines...) Expand all
232 if (_fields == null) { 296 if (_fields == null) {
233 _fields = <FieldElementForLink_ClassField>[]; 297 _fields = <FieldElementForLink_ClassField>[];
234 for (UnlinkedVariable field in _unlinkedClass.fields) { 298 for (UnlinkedVariable field in _unlinkedClass.fields) {
235 _fields.add(new FieldElementForLink_ClassField(this, field)); 299 _fields.add(new FieldElementForLink_ClassField(this, field));
236 } 300 }
237 } 301 }
238 return _fields; 302 return _fields;
239 } 303 }
240 304
241 @override 305 @override
306 List<InterfaceType> get interfaces => _interfaces ??=
307 _unlinkedClass.interfaces.map(_computeInterfaceType).toList();
308
309 @override
242 bool get isObject => _unlinkedClass.hasNoSupertype; 310 bool get isObject => _unlinkedClass.hasNoSupertype;
243 311
244 @override 312 @override
313 LibraryElementForLink get library => enclosingElement.library;
314
315 @override
316 List<MethodElementForLink> get methods {
317 if (_methods == null) {
318 _methods = <MethodElementForLink>[];
319 for (UnlinkedExecutable unlinkedExecutable
320 in _unlinkedClass.executables) {
321 if (unlinkedExecutable.kind ==
322 UnlinkedExecutableKind.functionOrMethod) {
323 _methods.add(new MethodElementForLink(this, unlinkedExecutable));
324 }
325 }
326 }
327 return _methods;
328 }
329
330 @override
331 List<InterfaceType> get mixins =>
332 _mixins ??= _unlinkedClass.mixins.map(_computeInterfaceType).toList();
333
334 @override
245 String get name => _unlinkedClass.name; 335 String get name => _unlinkedClass.name;
246 336
247 @override 337 @override
248 InterfaceType get supertype { 338 InterfaceType get supertype {
249 if (isObject) { 339 if (isObject) {
250 return null; 340 return null;
251 } 341 }
252 return _supertype ??= _computeSupertype(); 342 return _supertype ??= _computeInterfaceType(_unlinkedClass.supertype);
343 }
344
345 @override
346 List<TypeParameterElementForLink> get typeParameters {
347 if (_typeParameters == null) {
348 _typeParameters = _unlinkedClass.typeParameters
349 .map((UnlinkedTypeParam p) => new TypeParameterElementForLink(p))
350 .toList();
351 }
352 return _typeParameters;
253 } 353 }
254 354
255 /** 355 /**
256 * Get a list of [TypeParameterType] objects corresponding to the 356 * Get a list of [TypeParameterType] objects corresponding to the
257 * class's type parameters. 357 * class's type parameters.
258 */ 358 */
259 List<TypeParameterType> get typeParameterTypes { 359 List<TypeParameterType> get typeParameterTypes {
260 if (_typeParameterTypes == null) { 360 if (_typeParameterTypes == null) {
261 _typeParameterTypes = _unlinkedClass.typeParameters 361 _typeParameterTypes = typeParameters
262 .map((UnlinkedTypeParam p) => 362 .map((TypeParameterElementForLink e) => new TypeParameterTypeImpl(e))
263 new TypeParameterTypeImpl(new TypeParameterElementForLink(p)))
264 .toList(); 363 .toList();
265 } 364 }
266 return _typeParameterTypes; 365 return _typeParameterTypes;
267 } 366 }
268 367
269 @override 368 @override
270 ConstructorElementForLink get unnamedConstructor { 369 ConstructorElementForLink get unnamedConstructor {
271 if (!_unnamedConstructorComputed) { 370 if (!_unnamedConstructorComputed) {
272 for (ConstructorElementForLink constructor in constructors) { 371 for (ConstructorElementForLink constructor in constructors) {
273 if (constructor.name.isEmpty) { 372 if (constructor.name.isEmpty) {
(...skipping 29 matching lines...) Expand all
303 TypeParameterType getTypeParameterType(int index) { 402 TypeParameterType getTypeParameterType(int index) {
304 List<TypeParameterType> types = typeParameterTypes; 403 List<TypeParameterType> types = typeParameterTypes;
305 return types[types.length - index]; 404 return types[types.length - index];
306 } 405 }
307 406
308 @override 407 @override
309 void link(LinkedUnitBuilder linkedUnit) { 408 void link(LinkedUnitBuilder linkedUnit) {
310 for (ConstructorElementForLink constructorElement in constructors) { 409 for (ConstructorElementForLink constructorElement in constructors) {
311 constructorElement.link(linkedUnit); 410 constructorElement.link(linkedUnit);
312 } 411 }
412 for (MethodElementForLink methodElement in methods) {
413 methodElement.link(linkedUnit);
414 }
313 } 415 }
314 416
315 InterfaceType _computeSupertype() { 417 @override
418 void unlink() {
419 hasBeenInferred = false;
420 for (MethodElementForLink methodElement in methods) {
421 methodElement.unlink();
422 }
423 }
424
425 /**
426 * Convert [typeRef] into an [InterfaceType].
427 */
428 InterfaceType _computeInterfaceType(EntityRef typeRef) {
316 if (_unlinkedClass.supertype != null) { 429 if (_unlinkedClass.supertype != null) {
317 DartType supertype = 430 DartType supertype = enclosingElement._resolveTypeRef(typeRef, this);
318 enclosingElement._resolveTypeRef(_unlinkedClass.supertype, this);
319 if (supertype is InterfaceType) { 431 if (supertype is InterfaceType) {
320 return supertype; 432 return supertype;
321 } 433 }
322 // In the event that the supertype isn't an interface type (which may 434 // In the event that the supertype isn't an interface type (which may
323 // happen in the event of erroneous code) just fall through and pretend 435 // happen in the event of erroneous code) just fall through and pretend
324 // the supertype is `Object`. 436 // the supertype is `Object`.
325 } 437 }
326 return enclosingElement.enclosingElement._linker.objectType; 438 return enclosingElement.enclosingElement._linker.typeProvider.objectType;
327 } 439 }
328 } 440 }
329 441
330 /** 442 /**
331 * Element representing an enum resynthesized from a summary during 443 * Element representing an enum resynthesized from a summary during
332 * linking. 444 * linking.
333 */ 445 */
334 class ClassElementForLink_Enum extends ClassElementForLink { 446 class ClassElementForLink_Enum extends ClassElementForLink {
335 /** 447 /**
336 * The unlinked representation of the enum in the summary. 448 * The unlinked representation of the enum in the summary.
337 */ 449 */
338 final UnlinkedEnum _unlinkedEnum; 450 final UnlinkedEnum _unlinkedEnum;
339 451
340 InterfaceType _type; 452 InterfaceType _type;
341 List<FieldElementForLink_EnumField> _fields; 453 List<FieldElementForLink_EnumField> _fields;
342 454
343 ClassElementForLink_Enum(this._unlinkedEnum); 455 ClassElementForLink_Enum(
456 CompilationUnitElementForLink enclosingElement, this._unlinkedEnum)
457 : super(enclosingElement);
458
459 @override
460 List<PropertyAccessorElement> get accessors {
461 // TODO(paulberry): do we need to include synthetic accessors?
462 return const [];
463 }
344 464
345 @override 465 @override
346 List<ConstructorElementForLink> get constructors => const []; 466 List<ConstructorElementForLink> get constructors => const [];
347 467
348 @override 468 @override
349 String get displayName => _unlinkedEnum.name; 469 String get displayName => _unlinkedEnum.name;
350 470
351 @override 471 @override
352 List<FieldElementForLink_EnumField> get fields { 472 List<FieldElementForLink_EnumField> get fields {
353 if (_fields == null) { 473 if (_fields == null) {
354 _fields = <FieldElementForLink_EnumField>[]; 474 _fields = <FieldElementForLink_EnumField>[];
355 _fields.add(new FieldElementForLink_EnumField(null)); 475 _fields.add(new FieldElementForLink_EnumField(null));
356 for (UnlinkedEnumValue value in _unlinkedEnum.values) { 476 for (UnlinkedEnumValue value in _unlinkedEnum.values) {
357 _fields.add(new FieldElementForLink_EnumField(value)); 477 _fields.add(new FieldElementForLink_EnumField(value));
358 } 478 }
359 } 479 }
360 return _fields; 480 return _fields;
361 } 481 }
362 482
363 @override 483 @override
484 List<InterfaceType> get interfaces => const [];
485
486 @override
364 bool get isObject => false; 487 bool get isObject => false;
365 488
366 @override 489 @override
490 List<MethodElement> get methods => const [];
491
492 @override
493 List<InterfaceType> get mixins => const [];
494
495 @override
367 String get name => _unlinkedEnum.name; 496 String get name => _unlinkedEnum.name;
368 497
369 @override 498 @override
499 InterfaceType get supertype => library._linker.typeProvider.objectType;
500
501 @override
370 ConstructorElementForLink get unnamedConstructor => null; 502 ConstructorElementForLink get unnamedConstructor => null;
371 503
372 @override 504 @override
373 DartType buildType(DartType getTypeArgument(int i), 505 DartType buildType(DartType getTypeArgument(int i),
374 List<int> implicitFunctionTypeIndices) => 506 List<int> implicitFunctionTypeIndices) =>
375 _type ??= new InterfaceTypeImpl(this); 507 _type ??= new InterfaceTypeImpl(this);
376 508
377 @override 509 @override
378 void link(LinkedUnitBuilder linkedUnit) {} 510 void link(LinkedUnitBuilder linkedUnit) {}
511
512 @override
513 void unlink() {}
379 } 514 }
380 515
381 /** 516 /**
382 * Element representing a compilation unit resynthesized from a 517 * Element representing a compilation unit resynthesized from a
383 * summary during linking. 518 * summary during linking.
384 */ 519 */
385 abstract class CompilationUnitElementForLink implements CompilationUnitElement { 520 abstract class CompilationUnitElementForLink implements CompilationUnitElement {
386 /** 521 /**
387 * The unlinked representation of the compilation unit in the 522 * The unlinked representation of the compilation unit in the
388 * summary. 523 * summary.
389 */ 524 */
390 final UnlinkedUnit _unlinkedUnit; 525 final UnlinkedUnit _unlinkedUnit;
391 526
392 /** 527 /**
393 * For each entry in [UnlinkedUnit.references], the element referred 528 * For each entry in [UnlinkedUnit.references], the element referred
394 * to by the reference, or `null` if it hasn't been located yet. 529 * to by the reference, or `null` if it hasn't been located yet.
395 */ 530 */
396 final List<ReferenceableElementForLink> _references; 531 final List<ReferenceableElementForLink> _references;
397 532
398 List<ClassElementForLink_Class> _types; 533 List<ClassElementForLink_Class> _types;
534
399 Map<String, ReferenceableElementForLink> _containedNames; 535 Map<String, ReferenceableElementForLink> _containedNames;
400 List<TopLevelVariableElementForLink> _topLevelVariables; 536 List<TopLevelVariableElementForLink> _topLevelVariables;
401 List<ClassElementForLink_Enum> _enums; 537 List<ClassElementForLink_Enum> _enums;
402 538
403 @override 539 /**
404 final LibraryElementForLink enclosingElement; 540 * Index of this unit in the list of units in the enclosing library.
541 */
542 final int unitNum;
405 543
406 CompilationUnitElementForLink( 544 CompilationUnitElementForLink(UnlinkedUnit unlinkedUnit, this.unitNum)
407 this.enclosingElement, UnlinkedUnit unlinkedUnit)
408 : _references = new List<ReferenceableElementForLink>( 545 : _references = new List<ReferenceableElementForLink>(
409 unlinkedUnit.references.length), 546 unlinkedUnit.references.length),
410 _unlinkedUnit = unlinkedUnit; 547 _unlinkedUnit = unlinkedUnit;
411 548
412 @override 549 @override
550 LibraryElementForLink get enclosingElement;
551
552 @override
413 List<ClassElementForLink_Enum> get enums { 553 List<ClassElementForLink_Enum> get enums {
414 if (_enums == null) { 554 if (_enums == null) {
415 _enums = <ClassElementForLink_Enum>[]; 555 _enums = <ClassElementForLink_Enum>[];
416 for (UnlinkedEnum unlinkedEnum in _unlinkedUnit.enums) { 556 for (UnlinkedEnum unlinkedEnum in _unlinkedUnit.enums) {
417 _enums.add(new ClassElementForLink_Enum(unlinkedEnum)); 557 _enums.add(new ClassElementForLink_Enum(this, unlinkedEnum));
418 } 558 }
419 } 559 }
420 return _enums; 560 return _enums;
421 } 561 }
422 562
423 /** 563 /**
424 * Indicates whether this compilation element is part of the build unit 564 * Indicates whether this compilation element is part of the build unit
425 * currently being linked. 565 * currently being linked.
426 */ 566 */
427 bool get isInBuildUnit; 567 bool get isInBuildUnit;
428 568
429 @override 569 @override
570 LibraryElementForLink get library => enclosingElement;
571
572 @override
430 List<TopLevelVariableElementForLink> get topLevelVariables { 573 List<TopLevelVariableElementForLink> get topLevelVariables {
431 if (_topLevelVariables == null) { 574 if (_topLevelVariables == null) {
432 _topLevelVariables = <TopLevelVariableElementForLink>[]; 575 _topLevelVariables = <TopLevelVariableElementForLink>[];
433 for (UnlinkedVariable unlinkedVariable in _unlinkedUnit.variables) { 576 for (UnlinkedVariable unlinkedVariable in _unlinkedUnit.variables) {
434 _topLevelVariables 577 _topLevelVariables
435 .add(new TopLevelVariableElementForLink(this, unlinkedVariable)); 578 .add(new TopLevelVariableElementForLink(this, unlinkedVariable));
436 } 579 }
437 } 580 }
438 return _topLevelVariables; 581 return _topLevelVariables;
439 } 582 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 } 690 }
548 691
549 /** 692 /**
550 * Element representing a compilation unit which is part of the build 693 * Element representing a compilation unit which is part of the build
551 * unit being linked. 694 * unit being linked.
552 */ 695 */
553 class CompilationUnitElementInBuildUnit extends CompilationUnitElementForLink { 696 class CompilationUnitElementInBuildUnit extends CompilationUnitElementForLink {
554 @override 697 @override
555 final LinkedUnitBuilder _linkedUnit; 698 final LinkedUnitBuilder _linkedUnit;
556 699
557 CompilationUnitElementInBuildUnit(LibraryElementInBuildUnit libraryElement, 700 @override
558 UnlinkedUnit unlinkedUnit, this._linkedUnit) 701 final LibraryElementInBuildUnit enclosingElement;
559 : super(libraryElement, unlinkedUnit); 702
703 CompilationUnitElementInBuildUnit(this.enclosingElement,
704 UnlinkedUnit unlinkedUnit, this._linkedUnit, int unitNum)
705 : super(unlinkedUnit, unitNum);
560 706
561 @override 707 @override
562 bool get isInBuildUnit => true; 708 bool get isInBuildUnit => true;
563 709
710 @override
711 LibraryElementInBuildUnit get library => enclosingElement;
712
713 /**
714 * If this compilation unit already has a reference in its references table
715 * matching [dependency], [name], [numTypeParameters], and [unitNum], return
716 * its index. Otherwise add a new reference to table and return its index.
717 */
718 int addReference(
719 int dependency, String name, int numTypeParameters, int unitNum) {
720 List<LinkedReferenceBuilder> linkedReferences = _linkedUnit.references;
721 List<UnlinkedReference> unlinkedReferences = _unlinkedUnit.references;
722 for (int i = 0; i < linkedReferences.length; i++) {
723 LinkedReferenceBuilder linkedReference = linkedReferences[i];
724 if (linkedReference.dependency == dependency &&
725 (i < unlinkedReferences.length
726 ? unlinkedReferences[i].name
727 : linkedReference.name) ==
728 name &&
729 linkedReference.numTypeParameters == numTypeParameters &&
730 linkedReference.unit == unitNum) {
731 return i;
732 }
733 }
734 int result = linkedReferences.length;
735 linkedReferences.add(new LinkedReferenceBuilder(
736 dependency: dependency,
737 name: name,
738 numTypeParameters: numTypeParameters,
739 unit: unitNum));
740 return result;
741 }
742
564 /** 743 /**
565 * Perform type inference and const cycle detection on this 744 * Perform type inference and const cycle detection on this
566 * compilation unit. 745 * compilation unit.
567 */ 746 */
568 void link() { 747 void link() {
748 if (library._linker.strongMode) {
749 new InstanceMemberInferrer(enclosingElement._linker.typeProvider,
750 enclosingElement.inheritanceManager)
751 .inferCompilationUnit(this);
752 }
569 for (ClassElementForLink classElement in types) { 753 for (ClassElementForLink classElement in types) {
570 classElement.link(_linkedUnit); 754 classElement.link(_linkedUnit);
571 } 755 }
572 } 756 }
573 757
574 /** 758 /**
575 * Throw away any information produced by a previous call to [link]. 759 * Throw away any information produced by a previous call to [link].
576 */ 760 */
577 void unlink() { 761 void unlink() {
578 _linkedUnit.constCycles.clear(); 762 _linkedUnit.constCycles.clear();
579 _linkedUnit.references.length = _unlinkedUnit.references.length; 763 _linkedUnit.references.length = _unlinkedUnit.references.length;
580 _linkedUnit.types.clear(); 764 _linkedUnit.types.clear();
765 for (ClassElementForLink classElement in types) {
766 classElement.unlink();
767 }
581 } 768 }
582 } 769 }
583 770
584 /** 771 /**
585 * Element representing a compilation unit which is depended upon 772 * Element representing a compilation unit which is depended upon
586 * (either directly or indirectly) by the build unit being linked. 773 * (either directly or indirectly) by the build unit being linked.
587 */ 774 */
588 class CompilationUnitElementInDependency extends CompilationUnitElementForLink { 775 class CompilationUnitElementInDependency extends CompilationUnitElementForLink {
589 @override 776 @override
590 final LinkedUnit _linkedUnit; 777 final LinkedUnit _linkedUnit;
591 778
592 CompilationUnitElementInDependency(LibraryElementInDependency libraryElement, 779 @override
593 UnlinkedUnit unlinkedUnit, this._linkedUnit) 780 final LibraryElementInDependency enclosingElement;
594 : super(libraryElement, unlinkedUnit); 781
782 CompilationUnitElementInDependency(this.enclosingElement,
783 UnlinkedUnit unlinkedUnit, this._linkedUnit, int unitNum)
784 : super(unlinkedUnit, unitNum);
595 785
596 @override 786 @override
597 bool get isInBuildUnit => false; 787 bool get isInBuildUnit => false;
598 } 788 }
599 789
600 /** 790 /**
601 * Instance of [ConstNode] representing a constant constructor. 791 * Instance of [ConstNode] representing a constant constructor.
602 */ 792 */
603 class ConstConstructorNode extends ConstNode { 793 class ConstConstructorNode extends ConstNode {
604 /** 794 /**
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 parameterElement.compilationUnit); 1001 parameterElement.compilationUnit);
812 return dependencies; 1002 return dependencies;
813 } 1003 }
814 } 1004 }
815 1005
816 /** 1006 /**
817 * Element representing a constructor resynthesized from a summary 1007 * Element representing a constructor resynthesized from a summary
818 * during linking. 1008 * during linking.
819 */ 1009 */
820 class ConstructorElementForLink 1010 class ConstructorElementForLink
821 implements ConstructorElement, ReferenceableElementForLink { 1011 implements ConstructorElementImpl, ReferenceableElementForLink {
822 /** 1012 /**
823 * The unlinked representation of the constructor in the summary. 1013 * The unlinked representation of the constructor in the summary.
824 */ 1014 */
825 final UnlinkedExecutable _unlinkedExecutable; 1015 final UnlinkedExecutable _unlinkedExecutable;
826 1016
827 /** 1017 /**
828 * If this is a `const` constructor and the enclosing library is 1018 * If this is a `const` constructor and the enclosing library is
829 * part of the build unit being linked, the constructor's node in 1019 * part of the build unit being linked, the constructor's node in
830 * the constant evaluation dependency graph. Otherwise `null`. 1020 * the constant evaluation dependency graph. Otherwise `null`.
831 */ 1021 */
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 // Even though enum fields are constants, there is no need to include them 1279 // Even though enum fields are constants, there is no need to include them
1090 // in the const dependency graph because they can't participate in a 1280 // in the const dependency graph because they can't participate in a
1091 // circularity. 1281 // circularity.
1092 return null; 1282 return null;
1093 } 1283 }
1094 1284
1095 @override 1285 @override
1096 bool get isStatic => true; 1286 bool get isStatic => true;
1097 1287
1098 @override 1288 @override
1289 bool get isSynthetic => false;
1290
1291 @override
1099 String get name => 1292 String get name =>
1100 unlinkedEnumValue == null ? 'values' : unlinkedEnumValue.name; 1293 unlinkedEnumValue == null ? 'values' : unlinkedEnumValue.name;
1101 1294
1102 @override 1295 @override
1103 DartType buildType(DartType getTypeArgument(int i), 1296 DartType buildType(DartType getTypeArgument(int i),
1104 List<int> implicitFunctionTypeIndices) => 1297 List<int> implicitFunctionTypeIndices) =>
1105 DynamicTypeImpl.instance; 1298 DynamicTypeImpl.instance;
1106 1299
1107 @override 1300 @override
1108 ReferenceableElementForLink getContainedName(String name) => 1301 ReferenceableElementForLink getContainedName(String name) =>
1109 UndefinedElementForLink.instance; 1302 UndefinedElementForLink.instance;
1110 1303
1111 @override 1304 @override
1112 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); 1305 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
1113 } 1306 }
1114 1307
1308 class FunctionElementForLink_Initializer implements FunctionElementImpl {
1309 @override
1310 DartType get returnType {
1311 // TODO(paulberry): for type inference, compute and return the type of the
1312 // initializer expression.
1313 return DynamicTypeImpl.instance;
1314 }
1315
1316 @override
1317 void set returnType(DartType newType) {
1318 // TODO(paulberry): store inferred type.
1319 }
1320
1321 @override
1322 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
1323 }
1324
1115 /** 1325 /**
1116 * Element representing a library resynthesied from a summary during 1326 * Element representing a library resynthesied from a summary during
1117 * linking. The type parameter, [UnitElement], represents the type 1327 * linking. The type parameter, [UnitElement], represents the type
1118 * that will be used for the compilation unit elements. 1328 * that will be used for the compilation unit elements.
1119 */ 1329 */
1120 abstract class LibraryElementForLink< 1330 abstract class LibraryElementForLink<
1121 UnitElement extends CompilationUnitElementForLink> 1331 UnitElement extends CompilationUnitElementForLink>
1122 implements LibraryElement { 1332 implements LibraryElement {
1123 /** 1333 /**
1124 * Pointer back to the linker. 1334 * Pointer back to the linker.
1125 */ 1335 */
1126 final _Linker _linker; 1336 final _Linker _linker;
1127 1337
1128 /** 1338 /**
1129 * The absolute URI of this library. 1339 * The absolute URI of this library.
1130 */ 1340 */
1131 final Uri _absoluteUri; 1341 final Uri _absoluteUri;
1132 1342
1133 List<UnitElement> _units; 1343 List<UnitElement> _units;
1134 final Map<String, ReferenceableElementForLink> _containedNames = 1344 final Map<String, ReferenceableElementForLink> _containedNames =
1135 <String, ReferenceableElementForLink>{}; 1345 <String, ReferenceableElementForLink>{};
1136 final List<LibraryElementForLink> _dependencies = <LibraryElementForLink>[]; 1346 final List<LibraryElementForLink> _dependencies = <LibraryElementForLink>[];
1347 UnlinkedUnit _definingUnlinkedUnit;
1137 1348
1138 LibraryElementForLink(this._linker, this._absoluteUri) { 1349 LibraryElementForLink(this._linker, this._absoluteUri) {
1139 _dependencies.length = _linkedLibrary.dependencies.length; 1350 _dependencies.length = _linkedLibrary.dependencies.length;
1140 } 1351 }
1141 1352
1353 /**
1354 * Get the [UnlinkedUnit] for the defining compilation unit of this library.
1355 */
1356 UnlinkedUnit get definingUnlinkedUnit =>
1357 _definingUnlinkedUnit ??= _linker.getUnit(_absoluteUri.toString());
1358
1359 @override
1360 Element get enclosingElement => null;
1361
1142 @override 1362 @override
1143 List<UnitElement> get units { 1363 List<UnitElement> get units {
1144 if (_units == null) { 1364 if (_units == null) {
1145 UnlinkedUnit definingUnit = _linker.getUnit(_absoluteUri.toString()); 1365 UnlinkedUnit definingUnit = definingUnlinkedUnit;
1146 _units = <UnitElement>[_makeUnitElement(definingUnit, 0)]; 1366 _units = <UnitElement>[_makeUnitElement(definingUnit, 0)];
1147 int numParts = definingUnit.parts.length; 1367 int numParts = definingUnit.parts.length;
1148 for (int i = 0; i < numParts; i++) { 1368 for (int i = 0; i < numParts; i++) {
1149 // TODO(paulberry): make sure we handle the case where Uri.parse fails. 1369 // TODO(paulberry): make sure we handle the case where Uri.parse fails.
1150 // TODO(paulberry): make sure we handle the case where 1370 // TODO(paulberry): make sure we handle the case where
1151 // resolveRelativeUri fails. 1371 // resolveRelativeUri fails.
1152 UnlinkedUnit partUnit = _linker.getUnit(resolveRelativeUri( 1372 UnlinkedUnit partUnit = _linker.getUnit(resolveRelativeUri(
1153 _absoluteUri, Uri.parse(definingUnit.publicNamespace.parts[i])) 1373 _absoluteUri, Uri.parse(definingUnit.publicNamespace.parts[i]))
1154 .toString()); 1374 .toString());
1155 _units.add( 1375 _units.add(
1156 _makeUnitElement(partUnit ?? new UnlinkedUnitBuilder(), i + 1)); 1376 _makeUnitElement(partUnit ?? new UnlinkedUnitBuilder(), i + 1));
1157 } 1377 }
1158 } 1378 }
1159 return _units; 1379 return _units;
1160 } 1380 }
1161 1381
1162 /** 1382 /**
1163 * The linked representation of the library in the summary. 1383 * The linked representation of the library in the summary.
1164 */ 1384 */
1165 LinkedLibrary get _linkedLibrary; 1385 LinkedLibrary get _linkedLibrary;
1166 1386
1167 /** 1387 /**
1168 * Search all the units for a top level element with the given 1388 * Search all the units for a top level element with the given
1169 * [name]. If no name is found, return the singleton instance of 1389 * [name]. If no name is found, return the singleton instance of
1170 * [UndefinedElementForLink]. 1390 * [UndefinedElementForLink].
1171 */ 1391 */
1172 ReferenceableElementForLink getContainedName(name) => 1392 ReferenceableElementForLink getContainedName(String name) =>
1173 _containedNames.putIfAbsent(name, () { 1393 _containedNames.putIfAbsent(name, () {
1174 for (UnitElement unit in units) { 1394 for (UnitElement unit in units) {
1175 ReferenceableElementForLink element = unit.getContainedName(name); 1395 ReferenceableElementForLink element = unit.getContainedName(name);
1176 if (!identical(element, UndefinedElementForLink.instance)) { 1396 if (!identical(element, UndefinedElementForLink.instance)) {
1177 return element; 1397 return element;
1178 } 1398 }
1179 } 1399 }
1180 return UndefinedElementForLink.instance; 1400 return UndefinedElementForLink.instance;
1181 }); 1401 });
1182 1402
(...skipping 17 matching lines...) Expand all
1200 1420
1201 /** 1421 /**
1202 * Element representing a library which is part of the build unit 1422 * Element representing a library which is part of the build unit
1203 * being linked. 1423 * being linked.
1204 */ 1424 */
1205 class LibraryElementInBuildUnit 1425 class LibraryElementInBuildUnit
1206 extends LibraryElementForLink<CompilationUnitElementInBuildUnit> { 1426 extends LibraryElementForLink<CompilationUnitElementInBuildUnit> {
1207 @override 1427 @override
1208 final LinkedLibraryBuilder _linkedLibrary; 1428 final LinkedLibraryBuilder _linkedLibrary;
1209 1429
1430 InheritanceManager _inheritanceManager;
1431
1210 LibraryElementInBuildUnit( 1432 LibraryElementInBuildUnit(
1211 _Linker linker, Uri absoluteUri, this._linkedLibrary) 1433 _Linker linker, Uri absoluteUri, this._linkedLibrary)
1212 : super(linker, absoluteUri); 1434 : super(linker, absoluteUri);
1213 1435
1214 /** 1436 /**
1437 * Get the inheritance manager for this library (creating it if necessary).
1438 */
1439 InheritanceManager get inheritanceManager =>
1440 _inheritanceManager ??= new InheritanceManager(this);
1441
1442 /**
1443 * If this library already has a dependency in its dependencies table matching
1444 * [library], return its index. Otherwise add a new dependency to table and
1445 * return its index.
1446 */
1447 int addDependency(LibraryElementForLink library) {
1448 for (int i = 0; i < _linkedLibrary.dependencies.length; i++) {
1449 if (identical(_getDependency(i), library)) {
1450 return i;
1451 }
1452 }
1453 int result = _linkedLibrary.dependencies.length;
1454 _linkedLibrary.dependencies.add(new LinkedDependencyBuilder(
1455 parts: library.definingUnlinkedUnit.publicNamespace.parts,
1456 uri: library._absoluteUri.toString()));
1457 _dependencies.add(library);
1458 return result;
1459 }
1460
1461 /**
1215 * Perform type inference and const cycle detection on this library. 1462 * Perform type inference and const cycle detection on this library.
1216 */ 1463 */
1217 void link() { 1464 void link() {
1218 for (CompilationUnitElementInBuildUnit unit in units) { 1465 for (CompilationUnitElementInBuildUnit unit in units) {
1219 unit.link(); 1466 unit.link();
1220 } 1467 }
1221 } 1468 }
1222 1469
1223 /** 1470 /**
1224 * Throw away any information produced by a previous call to [link]. 1471 * Throw away any information produced by a previous call to [link].
1225 */ 1472 */
1226 void unlink() { 1473 void unlink() {
1227 _linkedLibrary.dependencies.length = 1474 _linkedLibrary.dependencies.length =
1228 _linkedLibrary.numPrelinkedDependencies; 1475 _linkedLibrary.numPrelinkedDependencies;
1229 for (CompilationUnitElementInBuildUnit unit in units) { 1476 for (CompilationUnitElementInBuildUnit unit in units) {
1230 unit.link(); 1477 unit.link();
1231 } 1478 }
1232 } 1479 }
1233 1480
1234 @override 1481 @override
1235 CompilationUnitElementInBuildUnit _makeUnitElement( 1482 CompilationUnitElementInBuildUnit _makeUnitElement(
1236 UnlinkedUnit unlinkedUnit, int i) => 1483 UnlinkedUnit unlinkedUnit, int i) =>
1237 new CompilationUnitElementInBuildUnit( 1484 new CompilationUnitElementInBuildUnit(
1238 this, unlinkedUnit, _linkedLibrary.units[i]); 1485 this, unlinkedUnit, _linkedLibrary.units[i], i);
1239 } 1486 }
1240 1487
1241 /** 1488 /**
1242 * Element representing a library which is depended upon (either 1489 * Element representing a library which is depended upon (either
1243 * directly or indirectly) by the build unit being linked. 1490 * directly or indirectly) by the build unit being linked.
1244 */ 1491 */
1245 class LibraryElementInDependency 1492 class LibraryElementInDependency
1246 extends LibraryElementForLink<CompilationUnitElementInDependency> { 1493 extends LibraryElementForLink<CompilationUnitElementInDependency> {
1247 @override 1494 @override
1248 final LinkedLibrary _linkedLibrary; 1495 final LinkedLibrary _linkedLibrary;
1249 1496
1250 LibraryElementInDependency( 1497 LibraryElementInDependency(
1251 _Linker linker, Uri absoluteUri, this._linkedLibrary) 1498 _Linker linker, Uri absoluteUri, this._linkedLibrary)
1252 : super(linker, absoluteUri); 1499 : super(linker, absoluteUri);
1253 1500
1254 @override 1501 @override
1255 CompilationUnitElementInDependency _makeUnitElement( 1502 CompilationUnitElementInDependency _makeUnitElement(
1256 UnlinkedUnit unlinkedUnit, int i) => 1503 UnlinkedUnit unlinkedUnit, int i) =>
1257 new CompilationUnitElementInDependency( 1504 new CompilationUnitElementInDependency(
1258 this, unlinkedUnit, _linkedLibrary.units[i]); 1505 this, unlinkedUnit, _linkedLibrary.units[i], i);
1259 } 1506 }
1260 1507
1261 /** 1508 /**
1509 * Element representing a method resynthesized from a summary during linking.
1510 */
1511 class MethodElementForLink implements MethodElementImpl, TypeParameterContext {
1512 /**
1513 * The unlinked representation of the method in the summary.
1514 */
1515 final UnlinkedExecutable _unlinkedExecutable;
1516
1517 DartType _declaredReturnType;
1518 DartType _inferredReturnType;
1519 FunctionTypeImpl _type;
1520 List<TypeParameterElementForLink> _typeParameters;
1521
1522 @override
1523 final ClassElementForLink_Class enclosingElement;
1524
1525 MethodElementForLink(this.enclosingElement, this._unlinkedExecutable);
1526
1527 @override
1528 bool get hasImplicitReturnType => _unlinkedExecutable.returnType == null;
1529
1530 @override
1531 bool get isStatic => _unlinkedExecutable.isStatic;
1532
1533 @override
1534 bool get isSynthetic => false;
1535
1536 @override
1537 ElementKind get kind => ElementKind.METHOD;
1538
1539 @override
1540 LibraryElementForLink get library => enclosingElement.library;
1541
1542 @override
1543 String get name => _unlinkedExecutable.name;
1544
1545 @override
1546 List<ParameterElementForLink> get parameters {
1547 // TODO(paulberry): implement.
1548 return const [];
1549 }
1550
1551 @override
1552 DartType get returnType {
1553 if (_inferredReturnType != null) {
1554 return _inferredReturnType;
1555 } else if (_declaredReturnType == null) {
1556 if (_unlinkedExecutable.returnType == null) {
1557 _declaredReturnType = DynamicTypeImpl.instance;
1558 } else {
1559 _declaredReturnType = enclosingElement.enclosingElement
1560 ._resolveTypeRef(_unlinkedExecutable.returnType, this);
1561 }
1562 }
1563 return _declaredReturnType;
1564 }
1565
1566 @override
1567 void set returnType(DartType inferredType) {
1568 assert(_inferredReturnType == null);
1569 _inferredReturnType = inferredType;
1570 }
1571
1572 @override
1573 FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this);
1574
1575 @override
1576 List<TypeParameterElementForLink> get typeParameters {
1577 if (_typeParameters == null) {
1578 _typeParameters = _unlinkedExecutable.typeParameters
1579 .map((UnlinkedTypeParam p) => new TypeParameterElementForLink(p))
1580 .toList();
1581 }
1582 return _typeParameters;
1583 }
1584
1585 @override
1586 TypeParameterType getTypeParameterType(int index) {
1587 // TODO(paulberry): implement.
1588 throw new UnimplementedError();
1589 }
1590
1591 @override
1592 bool isAccessibleIn(LibraryElement library) =>
1593 !Identifier.isPrivateName(name) || identical(this.library, library);
1594
1595 /**
1596 * Store the results of type inference for this method in [linkedUnit].
1597 */
1598 void link(LinkedUnitBuilder linkedUnit) {
1599 int slot = _unlinkedExecutable.inferredReturnTypeSlot;
1600 if (slot != 0) {
1601 DartType inferredReturnType = returnType;
1602 if (!inferredReturnType.isDynamic) {
1603 linkedUnit.types.add(_createLinkedType(
1604 inferredReturnType, enclosingElement.enclosingElement,
1605 slot: slot));
1606 }
1607 }
1608 }
1609
1610 @override
1611 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
1612
1613 /**
1614 * Throw away any information produced by type inference.
1615 */
1616 void unlink() {
1617 _inferredReturnType = null;
1618 }
1619 }
1620
1621 /**
1262 * Instances of [Node] represent nodes in a dependency graph. The 1622 * Instances of [Node] represent nodes in a dependency graph. The
1263 * type parameter, [NodeType], is the derived type (this affords some 1623 * type parameter, [NodeType], is the derived type (this affords some
1264 * extra type safety by making it difficult to accidentally construct 1624 * extra type safety by making it difficult to accidentally construct
1265 * bridges between unrelated dependency graphs). 1625 * bridges between unrelated dependency graphs).
1266 */ 1626 */
1267 abstract class Node<NodeType> { 1627 abstract class Node<NodeType> {
1268 /** 1628 /**
1269 * Index used by Tarjan's strongly connected components algorithm. 1629 * Index used by Tarjan's strongly connected components algorithm.
1270 * Zero means the node has not been visited yet; a nonzero value 1630 * Zero means the node has not been visited yet; a nonzero value
1271 * counts the order in which the node was visited. 1631 * counts the order in which the node was visited.
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1432 1792
1433 TypeParameterElementForLink(this._unlinkedTypeParam); 1793 TypeParameterElementForLink(this._unlinkedTypeParam);
1434 1794
1435 @override 1795 @override
1436 String get name => _unlinkedTypeParam.name; 1796 String get name => _unlinkedTypeParam.name;
1437 1797
1438 @override 1798 @override
1439 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); 1799 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
1440 } 1800 }
1441 1801
1802 class TypeProviderForLink implements TypeProvider {
1803 final _Linker _linker;
1804
1805 InterfaceType _boolType;
1806 InterfaceType _deprecatedType;
1807 InterfaceType _doubleType;
1808 InterfaceType _functionType;
1809 InterfaceType _futureDynamicType;
1810 InterfaceType _futureNullType;
1811 InterfaceType _futureType;
1812 InterfaceType _intType;
1813 InterfaceType _iterableDynamicType;
1814 InterfaceType _iterableType;
1815 InterfaceType _listType;
1816 InterfaceType _mapType;
1817 InterfaceType _nullType;
1818 InterfaceType _numType;
1819 InterfaceType _objectType;
1820 InterfaceType _stackTraceType;
1821 InterfaceType _streamDynamicType;
1822 InterfaceType _streamType;
1823 InterfaceType _stringType;
1824 InterfaceType _symbolType;
1825 InterfaceType _typeType;
1826
1827 TypeProviderForLink(this._linker);
1828
1829 @override
1830 InterfaceType get boolType =>
1831 _boolType ??= _buildInterfaceType(_linker.coreLibrary, 'bool');
1832
1833 @override
1834 DartType get bottomType => BottomTypeImpl.instance;
1835
1836 @override
1837 InterfaceType get deprecatedType => _deprecatedType ??=
1838 _buildInterfaceType(_linker.coreLibrary, 'Deprecated');
1839
1840 @override
1841 InterfaceType get doubleType =>
1842 _doubleType ??= _buildInterfaceType(_linker.coreLibrary, 'double');
1843
1844 @override
1845 DartType get dynamicType => DynamicTypeImpl.instance;
1846
1847 @override
1848 InterfaceType get functionType =>
1849 _functionType ??= _buildInterfaceType(_linker.coreLibrary, 'Function');
1850
1851 @override
1852 InterfaceType get futureDynamicType =>
1853 _futureDynamicType ??= futureType.instantiate(<DartType>[dynamicType]);
1854
1855 @override
1856 InterfaceType get futureNullType =>
1857 _futureNullType ??= futureType.instantiate(<DartType>[nullType]);
1858
1859 @override
1860 InterfaceType get futureType =>
1861 _futureType ??= _buildInterfaceType(_linker.asyncLibrary, 'Future');
1862
1863 @override
1864 InterfaceType get intType =>
1865 _intType ??= _buildInterfaceType(_linker.coreLibrary, 'int');
1866
1867 @override
1868 InterfaceType get iterableDynamicType => _iterableDynamicType ??=
1869 iterableType.instantiate(<DartType>[dynamicType]);
1870
1871 @override
1872 InterfaceType get iterableType =>
1873 _iterableType ??= _buildInterfaceType(_linker.coreLibrary, 'Iterable');
1874
1875 @override
1876 InterfaceType get listType =>
1877 _listType ??= _buildInterfaceType(_linker.coreLibrary, 'List');
1878
1879 @override
1880 InterfaceType get mapType =>
1881 _mapType ??= _buildInterfaceType(_linker.coreLibrary, 'Map');
1882
1883 @override
1884 List<InterfaceType> get nonSubtypableTypes => <InterfaceType>[
1885 nullType,
1886 numType,
1887 intType,
1888 doubleType,
1889 boolType,
1890 stringType
1891 ];
1892
1893 @override
1894 DartObjectImpl get nullObject {
1895 // TODO(paulberry): implement if needed
1896 throw new UnimplementedError();
1897 }
1898
1899 @override
1900 InterfaceType get nullType =>
1901 _nullType ??= _buildInterfaceType(_linker.coreLibrary, 'Null');
1902
1903 @override
1904 InterfaceType get numType =>
1905 _numType ??= _buildInterfaceType(_linker.coreLibrary, 'num');
1906
1907 @override
1908 InterfaceType get objectType =>
1909 _objectType ??= _buildInterfaceType(_linker.coreLibrary, 'Object');
1910
1911 @override
1912 InterfaceType get stackTraceType => _stackTraceType ??=
1913 _buildInterfaceType(_linker.coreLibrary, 'StackTrace');
1914
1915 @override
1916 InterfaceType get streamDynamicType =>
1917 _streamDynamicType ??= streamType.instantiate(<DartType>[dynamicType]);
1918
1919 @override
1920 InterfaceType get streamType =>
1921 _streamType ??= _buildInterfaceType(_linker.asyncLibrary, 'Stream');
1922
1923 @override
1924 InterfaceType get stringType =>
1925 _stringType ??= _buildInterfaceType(_linker.coreLibrary, 'String');
1926
1927 @override
1928 InterfaceType get symbolType =>
1929 _symbolType ??= _buildInterfaceType(_linker.coreLibrary, 'Symbol');
1930
1931 @override
1932 InterfaceType get typeType =>
1933 _typeType ??= _buildInterfaceType(_linker.coreLibrary, 'Type');
1934
1935 @override
1936 DartType get undefinedType => UndefinedTypeImpl.instance;
1937
1938 InterfaceType _buildInterfaceType(
1939 LibraryElementForLink library, String name) {
1940 return library
1941 .getContainedName(name)
1942 .buildType((int i) => DynamicTypeImpl.instance, const []);
1943 }
1944 }
1945
1442 /** 1946 /**
1443 * Singleton element used for unresolved references. 1947 * Singleton element used for unresolved references.
1444 */ 1948 */
1445 class UndefinedElementForLink implements ReferenceableElementForLink { 1949 class UndefinedElementForLink implements ReferenceableElementForLink {
1446 static const UndefinedElementForLink instance = 1950 static const UndefinedElementForLink instance =
1447 const UndefinedElementForLink._(); 1951 const UndefinedElementForLink._();
1448 1952
1449 const UndefinedElementForLink._(); 1953 const UndefinedElementForLink._();
1450 1954
1451 @override 1955 @override
1452 ConstructorElementForLink get asConstructor => null; 1956 ConstructorElementForLink get asConstructor => null;
1453 1957
1454 @override 1958 @override
1455 ConstVariableNode get asConstVariable => null; 1959 ConstVariableNode get asConstVariable => null;
1456 1960
1457 @override 1961 @override
1458 DartType buildType(DartType getTypeArgument(int i), 1962 DartType buildType(DartType getTypeArgument(int i),
1459 List<int> implicitFunctionTypeIndices) => 1963 List<int> implicitFunctionTypeIndices) =>
1460 DynamicTypeImpl.instance; 1964 DynamicTypeImpl.instance;
1461 1965
1462 @override 1966 @override
1463 ReferenceableElementForLink getContainedName(String name) => this; 1967 ReferenceableElementForLink getContainedName(String name) => this;
1464 } 1968 }
1465 1969
1466 /** 1970 /**
1467 * Element representing a top level variable resynthesized from a 1971 * Element representing a top level variable resynthesized from a
1468 * summary during linking. 1972 * summary during linking.
1469 */ 1973 */
1470 class VariableElementForLink 1974 class VariableElementForLink
1471 implements VariableElement, ReferenceableElementForLink { 1975 implements VariableElementImpl, ReferenceableElementForLink {
1472 /** 1976 /**
1473 * The unlinked representation of the variable in the summary. 1977 * The unlinked representation of the variable in the summary.
1474 */ 1978 */
1475 final UnlinkedVariable unlinkedVariable; 1979 final UnlinkedVariable unlinkedVariable;
1476 1980
1477 /** 1981 /**
1478 * If this variable is declared `const` and the enclosing library is 1982 * If this variable is declared `const` and the enclosing library is
1479 * part of the build unit being linked, the variable's node in the 1983 * part of the build unit being linked, the variable's node in the
1480 * constant evaluation dependency graph. Otherwise `null`. 1984 * constant evaluation dependency graph. Otherwise `null`.
1481 */ 1985 */
1482 ConstNode _constNode; 1986 ConstNode _constNode;
1483 1987
1988 FunctionElementForLink_Initializer _initializer;
1989
1484 /** 1990 /**
1485 * The compilation unit in which this variable appears. 1991 * The compilation unit in which this variable appears.
1486 */ 1992 */
1487 final CompilationUnitElementForLink compilationUnit; 1993 final CompilationUnitElementForLink compilationUnit;
1488 1994
1489 VariableElementForLink(this.unlinkedVariable, this.compilationUnit) { 1995 VariableElementForLink(this.unlinkedVariable, this.compilationUnit) {
1490 if (compilationUnit.isInBuildUnit && unlinkedVariable.constExpr != null) { 1996 if (compilationUnit.isInBuildUnit && unlinkedVariable.constExpr != null) {
1491 _constNode = new ConstVariableNode(this); 1997 _constNode = new ConstVariableNode(this);
1492 } 1998 }
1493 } 1999 }
1494 2000
1495 @override 2001 @override
1496 ConstructorElementForLink get asConstructor => null; 2002 ConstructorElementForLink get asConstructor => null;
1497 2003
1498 @override 2004 @override
1499 ConstVariableNode get asConstVariable => _constNode; 2005 ConstVariableNode get asConstVariable => _constNode;
1500 2006
1501 @override 2007 @override
2008 bool get hasImplicitType => unlinkedVariable.type != null;
2009
2010 @override
2011 FunctionElementForLink_Initializer get initializer =>
2012 _initializer ??= new FunctionElementForLink_Initializer();
2013
2014 @override
1502 bool get isConst => unlinkedVariable.isConst; 2015 bool get isConst => unlinkedVariable.isConst;
1503 2016
1504 @override 2017 @override
1505 bool get isFinal => unlinkedVariable.isFinal; 2018 bool get isFinal => unlinkedVariable.isFinal;
1506 2019
1507 @override 2020 @override
1508 bool get isStatic; 2021 bool get isStatic;
1509 2022
1510 @override 2023 @override
2024 bool get isSynthetic => false;
2025
2026 @override
1511 String get name => unlinkedVariable.name; 2027 String get name => unlinkedVariable.name;
1512 2028
1513 @override 2029 @override
2030 void set type(DartType newType) {
2031 // TODO(paulberry): store inferred type.
2032 }
2033
2034 @override
1514 DartType buildType(DartType getTypeArgument(int i), 2035 DartType buildType(DartType getTypeArgument(int i),
1515 List<int> implicitFunctionTypeIndices) => 2036 List<int> implicitFunctionTypeIndices) =>
1516 DynamicTypeImpl.instance; 2037 DynamicTypeImpl.instance;
1517 2038
1518 ReferenceableElementForLink getContainedName(String name) { 2039 ReferenceableElementForLink getContainedName(String name) {
1519 return new NonstaticMemberElementForLink(_constNode); 2040 return new NonstaticMemberElementForLink(_constNode);
1520 } 2041 }
1521 2042
1522 @override 2043 @override
1523 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); 2044 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
(...skipping 23 matching lines...) Expand all
1547 final Map<Uri, LibraryElementForLink> _libraries = 2068 final Map<Uri, LibraryElementForLink> _libraries =
1548 <Uri, LibraryElementForLink>{}; 2069 <Uri, LibraryElementForLink>{};
1549 2070
1550 /** 2071 /**
1551 * List of library elements for the libraries in the build unit 2072 * List of library elements for the libraries in the build unit
1552 * being linked. 2073 * being linked.
1553 */ 2074 */
1554 final List<LibraryElementInBuildUnit> _librariesInBuildUnit = 2075 final List<LibraryElementInBuildUnit> _librariesInBuildUnit =
1555 <LibraryElementInBuildUnit>[]; 2076 <LibraryElementInBuildUnit>[];
1556 2077
1557 InterfaceType _objectType; 2078 /**
2079 * Indicates whether type inference should use strong mode rules.
2080 */
2081 final bool strongMode;
2082
1558 LibraryElementForLink _coreLibrary; 2083 LibraryElementForLink _coreLibrary;
2084 LibraryElementForLink _asyncLibrary;
2085 TypeProviderForLink _typeProvider;
1559 2086
1560 _Linker(Map<String, LinkedLibraryBuilder> linkedLibraries, this.getDependency, 2087 _Linker(Map<String, LinkedLibraryBuilder> linkedLibraries, this.getDependency,
1561 this.getUnit) { 2088 this.getUnit, this.strongMode) {
1562 // Create elements for the libraries to be linked. The rest of 2089 // Create elements for the libraries to be linked. The rest of
1563 // the element model will be created on demand. 2090 // the element model will be created on demand.
1564 linkedLibraries 2091 linkedLibraries
1565 .forEach((String absoluteUri, LinkedLibraryBuilder linkedLibrary) { 2092 .forEach((String absoluteUri, LinkedLibraryBuilder linkedLibrary) {
1566 Uri uri = Uri.parse(absoluteUri); 2093 Uri uri = Uri.parse(absoluteUri);
1567 _librariesInBuildUnit.add(_libraries[uri] = 2094 _librariesInBuildUnit.add(_libraries[uri] =
1568 new LibraryElementInBuildUnit(this, uri, linkedLibrary)); 2095 new LibraryElementInBuildUnit(this, uri, linkedLibrary));
1569 }); 2096 });
1570 } 2097 }
1571 2098
1572 /** 2099 /**
2100 * Get the library element for `dart:async`.
2101 */
2102 LibraryElementForLink get asyncLibrary =>
2103 _asyncLibrary ??= getLibrary(Uri.parse('dart:async'));
2104
2105 /**
1573 * Get the library element for `dart:core`. 2106 * Get the library element for `dart:core`.
1574 */ 2107 */
1575 LibraryElementForLink get coreLibrary => 2108 LibraryElementForLink get coreLibrary =>
1576 _coreLibrary ??= getLibrary(Uri.parse('dart:core')); 2109 _coreLibrary ??= getLibrary(Uri.parse('dart:core'));
1577 2110
1578 /** 2111 /**
1579 * Get the `InterfaceType` for the type `Object`. 2112 * Get an instance of [TypeProvider] for use during linking.
1580 */ 2113 */
1581 InterfaceType get objectType => _objectType ??= coreLibrary 2114 TypeProviderForLink get typeProvider =>
1582 .getContainedName('Object') 2115 _typeProvider ??= new TypeProviderForLink(this);
1583 .buildType((int i) => DynamicTypeImpl.instance, const []);
1584 2116
1585 /** 2117 /**
1586 * Get the library element for the library having the given [uri]. 2118 * Get the library element for the library having the given [uri].
1587 */ 2119 */
1588 LibraryElementForLink getLibrary(Uri uri) => _libraries.putIfAbsent( 2120 LibraryElementForLink getLibrary(Uri uri) => _libraries.putIfAbsent(
1589 uri, 2121 uri,
1590 () => new LibraryElementInDependency( 2122 () => new LibraryElementInDependency(
1591 this, uri, getDependency(uri.toString()))); 2123 this, uri, getDependency(uri.toString())));
1592 2124
1593 /** 2125 /**
1594 * Perform type inference and const cycle detection on all libraries 2126 * Perform type inference and const cycle detection on all libraries
1595 * in the build unit being linked. 2127 * in the build unit being linked.
1596 */ 2128 */
1597 void link() { 2129 void link() {
2130 // TODO(paulberry): link library cycles in appropriate dependency order.
1598 for (LibraryElementInBuildUnit library in _librariesInBuildUnit) { 2131 for (LibraryElementInBuildUnit library in _librariesInBuildUnit) {
1599 library.link(); 2132 library.link();
1600 } 2133 }
1601 // TODO(paulberry): set dependencies. 2134 // TODO(paulberry): set dependencies.
1602 } 2135 }
1603 2136
1604 /** 2137 /**
1605 * Throw away any information produced by a previous call to [link]. 2138 * Throw away any information produced by a previous call to [link].
1606 */ 2139 */
1607 void unlink() { 2140 void unlink() {
1608 for (LibraryElementInBuildUnit library in _librariesInBuildUnit) { 2141 for (LibraryElementInBuildUnit library in _librariesInBuildUnit) {
1609 library.unlink(); 2142 library.unlink();
1610 } 2143 }
1611 } 2144 }
1612 } 2145 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/task/dart.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698