| // Copyright (c) 2019, 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:_fe_analyzer_shared/src/types/shared_type.dart'; |
| import 'package:analyzer/dart/analysis/analysis_options.dart'; |
| import 'package:analyzer/dart/analysis/features.dart'; |
| import 'package:analyzer/dart/element/scope.dart'; |
| import 'package:analyzer/error/listener.dart'; |
| import 'package:analyzer/src/dart/ast/ast.dart'; |
| import 'package:analyzer/src/dart/element/element.dart'; |
| import 'package:analyzer/src/dart/element/type.dart'; |
| import 'package:analyzer/src/dart/element/type_schema.dart'; |
| import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart'; |
| import 'package:analyzer/src/dart/resolver/resolution_visitor.dart'; |
| import 'package:analyzer/src/dart/resolver/type_analyzer_options.dart'; |
| import 'package:analyzer/src/generated/resolver.dart'; |
| import 'package:analyzer/src/summary2/link.dart'; |
| |
| /// Used to resolve some AST nodes - variable initializers, and annotations. |
| class AstResolver { |
| final Linker _linker; |
| final LibraryFragmentImpl _unitElement; |
| final Scope _nameScope; |
| final FeatureSet _featureSet; |
| final DiagnosticListener _diagnosticListener = |
| DiagnosticListener.nullListener; |
| final AnalysisOptions analysisOptions; |
| final InterfaceElementImpl? enclosingClassElement; |
| final ExecutableElementImpl? enclosingExecutableElement; |
| late final _resolutionVisitor = ResolutionVisitor( |
| unitElement: _unitElement, |
| nameScope: _nameScope, |
| diagnosticListener: _diagnosticListener, |
| strictInference: analysisOptions.strictInference, |
| strictCasts: analysisOptions.strictCasts, |
| dataForTesting: null, |
| ); |
| late final _scopeResolverVisitor = ScopeResolverVisitor( |
| DiagnosticReporter(_diagnosticListener, _unitElement.source), |
| nameScope: _nameScope, |
| ); |
| late final _typeAnalyzerOptions = computeTypeAnalyzerOptions(_featureSet); |
| late final _flowAnalysis = FlowAnalysisHelper( |
| false, |
| typeSystemOperations: TypeSystemOperations( |
| _unitElement.library.typeSystem, |
| strictCasts: analysisOptions.strictCasts, |
| ), |
| typeAnalyzerOptions: _typeAnalyzerOptions, |
| ); |
| late final _resolverVisitor = ResolverVisitor( |
| _linker.inheritance, |
| _unitElement.library, |
| LibraryResolutionContext(), |
| _unitElement.source, |
| _unitElement.library.typeProvider, |
| _diagnosticListener, |
| featureSet: _featureSet, |
| analysisOptions: analysisOptions, |
| flowAnalysisHelper: _flowAnalysis, |
| libraryFragment: _unitElement, |
| typeAnalyzerOptions: _typeAnalyzerOptions, |
| ); |
| |
| AstResolver( |
| this._linker, |
| this._unitElement, |
| this._nameScope, |
| this.analysisOptions, { |
| this.enclosingClassElement, |
| this.enclosingExecutableElement, |
| }) : _featureSet = _unitElement.library.featureSet; |
| |
| void resolveAnnotation(AnnotationImpl node) { |
| node.accept(_resolutionVisitor); |
| node.accept(_scopeResolverVisitor); |
| _prepareEnclosingDeclarations(); |
| _flowAnalysis.bodyOrInitializer_enter(node, null); |
| node.accept(_resolverVisitor); |
| _resolverVisitor.checkIdle(); |
| _flowAnalysis.bodyOrInitializer_exit(); |
| } |
| |
| void resolveConstructorNode(ConstructorDeclarationImpl node) { |
| // We don't want to visit the whole node because that will try to create an |
| // element for it; we just want to process its children so that we can |
| // resolve initializers and/or a redirection. |
| void visit(AstVisitor<Object?> visitor) { |
| node.initializers.accept(visitor); |
| node.redirectedConstructor?.accept(visitor); |
| } |
| |
| visit(_resolutionVisitor); |
| visit(_scopeResolverVisitor); |
| |
| _prepareEnclosingDeclarations(); |
| _flowAnalysis.bodyOrInitializer_enter(node, node.parameters, visit: visit); |
| visit(_resolverVisitor); |
| _resolverVisitor.checkIdle(); |
| _flowAnalysis.bodyOrInitializer_exit(); |
| } |
| |
| void resolveExpression( |
| ExpressionImpl Function() getNode, { |
| TypeImpl contextType = UnknownInferredType.instance, |
| }) { |
| ExpressionImpl node = getNode(); |
| node.accept(_resolutionVisitor); |
| // Node may have been rewritten so get it again. |
| node = getNode(); |
| node.accept(_scopeResolverVisitor); |
| _prepareEnclosingDeclarations(); |
| _flowAnalysis.bodyOrInitializer_enter(node.parent as AstNodeImpl, null); |
| _resolverVisitor.analyzeExpression(node, SharedTypeSchemaView(contextType)); |
| _resolverVisitor.popRewrite(); |
| _resolverVisitor.checkIdle(); |
| _flowAnalysis.bodyOrInitializer_exit(); |
| } |
| |
| void _prepareEnclosingDeclarations() { |
| _resolverVisitor.prepareEnclosingDeclarations( |
| enclosingClassElement: enclosingClassElement, |
| enclosingExecutableElement: enclosingExecutableElement, |
| ); |
| } |
| } |