@@ -22,6 +22,7 @@ import 'package:analyzer/dart/ast/ast.dart'
2222 InstanceCreationExpression;
2323import 'package:analyzer/dart/element/element.dart' ;
2424import 'package:analyzer/dart/element/type.dart' ;
25+ import 'package:analyzer/dart/element/type_system.dart' ;
2526import 'package:analyzer/dart/element/visitor.dart' ;
2627import 'package:analyzer/file_system/file_system.dart' as file_system;
2728import 'package:analyzer/file_system/physical_file_system.dart' ;
@@ -35,12 +36,14 @@ import 'package:analyzer/src/dart/element/element.dart';
3536import 'package:analyzer/src/dart/element/inheritance_manager3.dart' ;
3637import 'package:analyzer/src/dart/element/member.dart'
3738 show ExecutableMember, Member, ParameterMember;
39+ import 'package:analyzer/src/dart/element/type.dart' show InterfaceTypeImpl;
3840import 'package:analyzer/src/dart/sdk/sdk.dart' ;
3941import 'package:analyzer/src/generated/engine.dart' ;
4042import 'package:analyzer/src/generated/java_io.dart' ;
4143import 'package:analyzer/src/generated/sdk.dart' ;
4244import 'package:analyzer/src/generated/source.dart' ;
4345import 'package:analyzer/src/generated/source_io.dart' ;
46+ import 'package:analyzer/src/generated/type_system.dart' show Dart2TypeSystem;
4447import 'package:analyzer/src/source/package_map_resolver.dart' ;
4548import 'package:analyzer/src/source/sdk_ext.dart' ;
4649import 'package:args/args.dart' ;
@@ -793,6 +796,20 @@ class Class extends Container
793796 return _defaultConstructor;
794797 }
795798
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+
796813 Iterable <Method > get allInstanceMethods =>
797814 quiver.concat ([instanceMethods, inheritedMethods]);
798815
@@ -951,7 +968,8 @@ class Class extends Container
951968 hasAnnotations ||
952969 hasPublicInterfaces ||
953970 hasPublicSuperChainReversed ||
954- hasPublicImplementors;
971+ hasPublicImplementors ||
972+ hasPotentiallyApplicableExtensions;
955973
956974 @override
957975 bool get hasPublicOperators =>
@@ -1326,6 +1344,28 @@ class Extension extends Container
13261344 ElementType .from (_extension.extendedType, library, packageGraph);
13271345 }
13281346
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+
13291369 @override
13301370 ModelElement get enclosingElement => library;
13311371
@@ -2371,11 +2411,8 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
23712411
23722412 // Initialize the list of elements defined in this library and
23732413 // 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 ();
23792416 // TODO(jcollins-g): Consider switch to [_libraryElement.topLevelElements].
23802417 exportedAndLocalElements
23812418 .addAll (getDefinedElements (_libraryElement.definingCompilationUnit));
@@ -2403,6 +2440,8 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
24032440
24042441 List <String > _allOriginalModelElementNames;
24052442
2443+ bool get isInSdk => _libraryElement.isInSdk;
2444+
24062445 final Package _package;
24072446
24082447 @override
@@ -4967,7 +5006,7 @@ class Operator extends Method {
49675006
49685007class PackageGraph {
49695008 PackageGraph .UninitializedPackageGraph (
4970- this .config, this .driver, this .sdk, this .hasEmbedderSdk)
5009+ this .config, this .driver, this .typeSystem, this . sdk, this .hasEmbedderSdk)
49715010 : packageMeta = config.topLevelPackageMeta,
49725011 session = driver.currentSession {
49735012 _packageWarningCounter = PackageWarningCounter (this );
@@ -5023,10 +5062,14 @@ class PackageGraph {
50235062 package._libraries.sort ((a, b) => compareNatural (a.name, b.name));
50245063 package._libraries.forEach ((library) {
50255064 library.allClasses.forEach (_addToImplementors);
5065+ // TODO(jcollins-g): Use a better data structure.
5066+ _extensions.addAll (library.extensions);
50265067 });
50275068 });
50285069 _implementors.values.forEach ((l) => l.sort ());
50295070 allImplementorsAdded = true ;
5071+ _extensions.sort (byName);
5072+ allExtensionsAdded = true ;
50305073
50315074 // We should have found all special classes by now.
50325075 specialClasses.assertSpecials ();
@@ -5080,15 +5123,24 @@ class PackageGraph {
50805123
50815124 SpecialClasses specialClasses;
50825125
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
50845127 /// is true.
50855128 bool allImplementorsAdded = false ;
50865129
5130+ /// It is safe to cache values derived from the [_extensions] table if this
5131+ /// is true.
5132+ bool allExtensionsAdded = false ;
5133+
50875134 Map <String , List <Class >> get implementors {
50885135 assert (allImplementorsAdded);
50895136 return _implementors;
50905137 }
50915138
5139+ Iterable <Extension > get extensions {
5140+ assert (allExtensionsAdded);
5141+ return _extensions;
5142+ }
5143+
50925144 Map <String , Set <ModelElement >> _findRefElementCache;
50935145
50945146 Map <String , Set <ModelElement >> get findRefElementCache {
@@ -5126,6 +5178,10 @@ class PackageGraph {
51265178 /// Map of Class.href to a list of classes implementing that class
51275179 final Map <String , List <Class >> _implementors = Map ();
51285180
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+
51295185 /// PackageMeta for the default package.
51305186 final PackageMeta packageMeta;
51315187
@@ -5156,6 +5212,7 @@ class PackageGraph {
51565212 /// TODO(brianwilkerson) Replace the driver with the session.
51575213 final AnalysisDriver driver;
51585214 final AnalysisSession session;
5215+ final TypeSystem typeSystem;
51595216 final DartSdk sdk;
51605217
51615218 Map <Source , SdkLibrary > _sdkLibrarySources;
@@ -6818,7 +6875,11 @@ class PackageBuilder {
68186875 }
68196876
68206877 PackageGraph newGraph = PackageGraph .UninitializedPackageGraph (
6821- config, driver, sdk, hasEmbedderSdkFiles);
6878+ config,
6879+ driver,
6880+ await driver.currentSession.typeSystem,
6881+ sdk,
6882+ hasEmbedderSdkFiles);
68226883 await getLibraries (newGraph);
68236884 await newGraph.initializePackageGraph ();
68246885 return newGraph;
0 commit comments