|  | // 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/element.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 [ClassElement] 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<ClassElement?> 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 ClassElement) { | 
|  | return element; | 
|  | } | 
|  | } | 
|  | return null; | 
|  | } | 
|  |  | 
|  | @Deprecated('Use [getClass] instead.') | 
|  | Future<ClassElement?> getClass2(String libraryUri, String className) async { | 
|  | return await getClass(libraryUri, className); | 
|  | } | 
|  |  | 
|  | /// Return the [EnumElement] 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<EnumElement?> 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 EnumElement) { | 
|  | return element; | 
|  | } | 
|  | } | 
|  | return null; | 
|  | } | 
|  |  | 
|  | /// Returns the [ClassElement] 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<ClassElement?> 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 [MixinElement] 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<MixinElement?> 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 MixinElement) { | 
|  | return element; | 
|  | } | 
|  | } | 
|  | return null; | 
|  | } | 
|  |  | 
|  | /// Returns the resolved unit that declares the given [element]. | 
|  | Future<ResolvedUnitResult?> getResolvedUnitByElement(Element 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 [PropertyAccessorElement] 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<PropertyAccessorElement?> 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 PropertyAccessorElement) { | 
|  | 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.getResolvedLibraryContaining(path); | 
|  | if (some is ResolvedLibraryResult) { | 
|  | result = _resolvedLibraries[path] = some; | 
|  | } | 
|  | } | 
|  | return result; | 
|  | } | 
|  | } |