| // Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file | 
 | // for details. All rights reserved. Use of this source code is governed by a | 
 | // BSD-style license that can be found in the LICENSE file. | 
 |  | 
 | import 'package:analyzer/dart/analysis/results.dart'; | 
 | import 'package:analyzer/dart/analysis/session.dart'; | 
 | import 'package:analyzer/dart/element/element2.dart'; | 
 |  | 
 | /// A wrapper around [AnalysisSession] that provides additional utilities. | 
 | /// | 
 | /// The methods in this class that return analysis results will throw an | 
 | /// [InconsistentAnalysisException] if the result to be returned might be | 
 | /// inconsistent with any previously returned results. | 
 | class AnalysisSessionHelper { | 
 |   final AnalysisSession session; | 
 |  | 
 |   final Map<String, ResolvedLibraryResult> _resolvedLibraries = {}; | 
 |  | 
 |   AnalysisSessionHelper(this.session); | 
 |  | 
 |   /// Returns the [ClassElement2] with the given [className] that is exported | 
 |   /// from the library with the given [libraryUri], or `null` if the library | 
 |   /// does not export a class with such name. | 
 |   Future<ClassElement2?> getClass(String libraryUri, String className) async { | 
 |     var libraryResult = await session.getLibraryByUri(libraryUri); | 
 |     if (libraryResult is LibraryElementResult) { | 
 |       var element = libraryResult.element2.exportNamespace.get2(className); | 
 |       if (element is ClassElement2) { | 
 |         return element; | 
 |       } | 
 |     } | 
 |     return null; | 
 |   } | 
 |  | 
 |   @Deprecated('Use [getClass] instead.') | 
 |   Future<ClassElement2?> getClass2(String libraryUri, String className) async { | 
 |     return await getClass(libraryUri, className); | 
 |   } | 
 |  | 
 |   /// Return the [EnumElement2] with the given [className] that is exported | 
 |   /// from the library with the given [libraryUri], or `null` if the library | 
 |   /// does not export a class with such name. | 
 |   Future<EnumElement2?> getEnum(String libraryUri, String className) async { | 
 |     var libraryResult = await session.getLibraryByUri(libraryUri); | 
 |     if (libraryResult is LibraryElementResult) { | 
 |       var element = libraryResult.element2.exportNamespace.get2(className); | 
 |       if (element is EnumElement2) { | 
 |         return element; | 
 |       } | 
 |     } | 
 |     return null; | 
 |   } | 
 |  | 
 |   /// Returns the [ClassElement2] with the given [className] that is exported | 
 |   /// from the Flutter widgets library, or `null` if the library does not export | 
 |   /// a class with such name. | 
 |   Future<ClassElement2?> getFlutterClass(String className) => | 
 |       getClass('package:flutter/widgets.dart', className); | 
 |  | 
 |   /// Returns the declaration of the [fragment]. | 
 |   /// | 
 |   /// Returns `null` if the [fragment] is synthetic, or is declared in a file | 
 |   /// that is not a part of a library. | 
 |   Future<FragmentDeclarationResult?> getFragmentDeclaration( | 
 |       Fragment fragment) async { | 
 |     var libraryPath = fragment.libraryFragment!.source.fullName; | 
 |     var resolvedLibrary = await _getResolvedLibrary(libraryPath); | 
 |     return resolvedLibrary?.getFragmentDeclaration(fragment); | 
 |   } | 
 |  | 
 |   /// Return the [MixinElement2] with the given [name] that is exported | 
 |   /// from the library with the given [libraryUri], or `null` if the library | 
 |   /// does not export a class with such name. | 
 |   Future<MixinElement2?> getMixin(String libraryUri, String name) async { | 
 |     var libraryResult = await session.getLibraryByUri(libraryUri); | 
 |     if (libraryResult is LibraryElementResult) { | 
 |       var element = libraryResult.element2.exportNamespace.get2(name); | 
 |       if (element is MixinElement2) { | 
 |         return element; | 
 |       } | 
 |     } | 
 |     return null; | 
 |   } | 
 |  | 
 |   /// Returns the resolved unit that declares the given [element]. | 
 |   Future<ResolvedUnitResult?> getResolvedUnitByElement(Element2 element) async { | 
 |     var libraryPath = element.library2!.firstFragment.source.fullName; | 
 |     var resolvedLibrary = await _getResolvedLibrary(libraryPath); | 
 |     if (resolvedLibrary == null) { | 
 |       return null; | 
 |     } | 
 |  | 
 |     var unitPath = element.firstFragment.libraryFragment!.source.fullName; | 
 |     return resolvedLibrary.units | 
 |         .singleWhere((resolvedUnit) => resolvedUnit.path == unitPath); | 
 |   } | 
 |  | 
 |   /// Returns the [PropertyAccessorElement2] with the given [name] that is | 
 |   /// exported from the library with the given [uri]. | 
 |   /// | 
 |   /// Returns `null` if the library does not export a top-level accessor with | 
 |   /// that name. | 
 |   Future<PropertyAccessorElement2?> getTopLevelPropertyAccessor( | 
 |       String uri, String name) async { | 
 |     var libraryResult = await session.getLibraryByUri(uri); | 
 |     if (libraryResult is LibraryElementResult) { | 
 |       var element = libraryResult.element2.exportNamespace.get2(name); | 
 |       if (element is PropertyAccessorElement2) { | 
 |         return element; | 
 |       } | 
 |     } | 
 |     return null; | 
 |   } | 
 |  | 
 |   /// Return a newly resolved, or cached library with the given [path]. | 
 |   Future<ResolvedLibraryResult?> _getResolvedLibrary(String path) async { | 
 |     var result = _resolvedLibraries[path]; | 
 |     if (result == null) { | 
 |       var some = await session.getResolvedLibrary(path); | 
 |       if (some is ResolvedLibraryResult) { | 
 |         result = _resolvedLibraries[path] = some; | 
 |       } | 
 |     } | 
 |     return result; | 
 |   } | 
 | } |