@@ -22,6 +22,7 @@ import 'package:analyzer/dart/ast/ast.dart'
22
22
InstanceCreationExpression;
23
23
import 'package:analyzer/dart/element/element.dart' ;
24
24
import 'package:analyzer/dart/element/type.dart' ;
25
+ import 'package:analyzer/dart/element/type_system.dart' ;
25
26
import 'package:analyzer/dart/element/visitor.dart' ;
26
27
import 'package:analyzer/file_system/file_system.dart' as file_system;
27
28
import 'package:analyzer/file_system/physical_file_system.dart' ;
@@ -35,12 +36,14 @@ import 'package:analyzer/src/dart/element/element.dart';
35
36
import 'package:analyzer/src/dart/element/inheritance_manager3.dart' ;
36
37
import 'package:analyzer/src/dart/element/member.dart'
37
38
show ExecutableMember, Member, ParameterMember;
39
+ import 'package:analyzer/src/dart/element/type.dart' show InterfaceTypeImpl;
38
40
import 'package:analyzer/src/dart/sdk/sdk.dart' ;
39
41
import 'package:analyzer/src/generated/engine.dart' ;
40
42
import 'package:analyzer/src/generated/java_io.dart' ;
41
43
import 'package:analyzer/src/generated/sdk.dart' ;
42
44
import 'package:analyzer/src/generated/source.dart' ;
43
45
import 'package:analyzer/src/generated/source_io.dart' ;
46
+ import 'package:analyzer/src/generated/type_system.dart' show Dart2TypeSystem;
44
47
import 'package:analyzer/src/source/package_map_resolver.dart' ;
45
48
import 'package:analyzer/src/source/sdk_ext.dart' ;
46
49
import 'package:args/args.dart' ;
@@ -793,6 +796,20 @@ class Class extends Container
793
796
return _defaultConstructor;
794
797
}
795
798
799
+ bool get hasPotentiallyApplicableExtensions =>
800
+ potentiallyApplicableExtensions.isNotEmpty;
801
+
802
+ List <Extension > _potentiallyApplicableExtensions;
803
+ Iterable <Extension > get potentiallyApplicableExtensions {
804
+ if (_potentiallyApplicableExtensions == null ) {
805
+ _potentiallyApplicableExtensions = utils
806
+ .filterNonDocumented (packageGraph.extensions)
807
+ .where ((e) => e.couldApplyTo (this ))
808
+ .toList (growable: false );
809
+ }
810
+ return _potentiallyApplicableExtensions;
811
+ }
812
+
796
813
Iterable <Method > get allInstanceMethods =>
797
814
quiver.concat ([instanceMethods, inheritedMethods]);
798
815
@@ -951,7 +968,8 @@ class Class extends Container
951
968
hasAnnotations ||
952
969
hasPublicInterfaces ||
953
970
hasPublicSuperChainReversed ||
954
- hasPublicImplementors;
971
+ hasPublicImplementors ||
972
+ hasPotentiallyApplicableExtensions;
955
973
956
974
@override
957
975
bool get hasPublicOperators =>
@@ -1326,6 +1344,28 @@ class Extension extends Container
1326
1344
ElementType .from (_extension.extendedType, library, packageGraph);
1327
1345
}
1328
1346
1347
+ /// Returns [true] if there is an instantiation of [c] to which this extension
1348
+ /// could be applied.
1349
+ bool couldApplyTo (Class c) =>
1350
+ _couldApplyTo (extendedType.type, c.element, packageGraph.typeSystem);
1351
+
1352
+ static bool _couldApplyTo (
1353
+ DartType extendedType, ClassElement element, Dart2TypeSystem typeSystem) {
1354
+ InterfaceTypeImpl classInstantiated =
1355
+ typeSystem.instantiateToBounds (element.thisType);
1356
+ classInstantiated = element.instantiate (
1357
+ typeArguments: classInstantiated.typeArguments.map ((a) {
1358
+ if (a.isDynamic) {
1359
+ return typeSystem.typeProvider.neverType;
1360
+ }
1361
+ return a;
1362
+ }).toList (),
1363
+ nullabilitySuffix: classInstantiated.nullabilitySuffix);
1364
+
1365
+ return (classInstantiated.element == extendedType.element) ||
1366
+ typeSystem.isSubtypeOf (classInstantiated, extendedType);
1367
+ }
1368
+
1329
1369
@override
1330
1370
ModelElement get enclosingElement => library;
1331
1371
@@ -2371,11 +2411,8 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
2371
2411
2372
2412
// Initialize the list of elements defined in this library and
2373
2413
// exported via its export directives.
2374
- Set <Element > exportedAndLocalElements = _libraryElement
2375
- .exportNamespace
2376
- .definedNames
2377
- .values
2378
- .toSet ();
2414
+ Set <Element > exportedAndLocalElements =
2415
+ _libraryElement.exportNamespace.definedNames.values.toSet ();
2379
2416
// TODO(jcollins-g): Consider switch to [_libraryElement.topLevelElements].
2380
2417
exportedAndLocalElements
2381
2418
.addAll (getDefinedElements (_libraryElement.definingCompilationUnit));
@@ -2403,6 +2440,8 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
2403
2440
2404
2441
List <String > _allOriginalModelElementNames;
2405
2442
2443
+ bool get isInSdk => _libraryElement.isInSdk;
2444
+
2406
2445
final Package _package;
2407
2446
2408
2447
@override
@@ -4967,7 +5006,7 @@ class Operator extends Method {
4967
5006
4968
5007
class PackageGraph {
4969
5008
PackageGraph .UninitializedPackageGraph (
4970
- this .config, this .driver, this .sdk, this .hasEmbedderSdk)
5009
+ this .config, this .driver, this .typeSystem, this . sdk, this .hasEmbedderSdk)
4971
5010
: packageMeta = config.topLevelPackageMeta,
4972
5011
session = driver.currentSession {
4973
5012
_packageWarningCounter = PackageWarningCounter (this );
@@ -5023,10 +5062,14 @@ class PackageGraph {
5023
5062
package._libraries.sort ((a, b) => compareNatural (a.name, b.name));
5024
5063
package._libraries.forEach ((library) {
5025
5064
library.allClasses.forEach (_addToImplementors);
5065
+ // TODO(jcollins-g): Use a better data structure.
5066
+ _extensions.addAll (library.extensions);
5026
5067
});
5027
5068
});
5028
5069
_implementors.values.forEach ((l) => l.sort ());
5029
5070
allImplementorsAdded = true ;
5071
+ _extensions.sort (byName);
5072
+ allExtensionsAdded = true ;
5030
5073
5031
5074
// We should have found all special classes by now.
5032
5075
specialClasses.assertSpecials ();
@@ -5080,15 +5123,24 @@ class PackageGraph {
5080
5123
5081
5124
SpecialClasses specialClasses;
5082
5125
5083
- /// It is safe to cache values derived from the _implementors table if this
5126
+ /// It is safe to cache values derived from the [ _implementors] table if this
5084
5127
/// is true.
5085
5128
bool allImplementorsAdded = false ;
5086
5129
5130
+ /// It is safe to cache values derived from the [_extensions] table if this
5131
+ /// is true.
5132
+ bool allExtensionsAdded = false ;
5133
+
5087
5134
Map <String , List <Class >> get implementors {
5088
5135
assert (allImplementorsAdded);
5089
5136
return _implementors;
5090
5137
}
5091
5138
5139
+ Iterable <Extension > get extensions {
5140
+ assert (allExtensionsAdded);
5141
+ return _extensions;
5142
+ }
5143
+
5092
5144
Map <String , Set <ModelElement >> _findRefElementCache;
5093
5145
5094
5146
Map <String , Set <ModelElement >> get findRefElementCache {
@@ -5126,6 +5178,10 @@ class PackageGraph {
5126
5178
/// Map of Class.href to a list of classes implementing that class
5127
5179
final Map <String , List <Class >> _implementors = Map ();
5128
5180
5181
+ /// A list of extensions that exist in the package graph.
5182
+ // TODO(jcollins-g): Consider implementing a smarter structure for this.
5183
+ final List <Extension > _extensions = List ();
5184
+
5129
5185
/// PackageMeta for the default package.
5130
5186
final PackageMeta packageMeta;
5131
5187
@@ -5156,6 +5212,7 @@ class PackageGraph {
5156
5212
/// TODO(brianwilkerson) Replace the driver with the session.
5157
5213
final AnalysisDriver driver;
5158
5214
final AnalysisSession session;
5215
+ final TypeSystem typeSystem;
5159
5216
final DartSdk sdk;
5160
5217
5161
5218
Map <Source , SdkLibrary > _sdkLibrarySources;
@@ -6818,7 +6875,11 @@ class PackageBuilder {
6818
6875
}
6819
6876
6820
6877
PackageGraph newGraph = PackageGraph .UninitializedPackageGraph (
6821
- config, driver, sdk, hasEmbedderSdkFiles);
6878
+ config,
6879
+ driver,
6880
+ await driver.currentSession.typeSystem,
6881
+ sdk,
6882
+ hasEmbedderSdkFiles);
6822
6883
await getLibraries (newGraph);
6823
6884
await newGraph.initializePackageGraph ();
6824
6885
return newGraph;
0 commit comments