@@ -9,11 +9,14 @@ import 'package:analysis_server/src/utilities/flutter.dart';
99import 'package:analyzer/dart/analysis/results.dart' ;
1010import 'package:analyzer/dart/analysis/session.dart' ;
1111import 'package:analyzer/dart/ast/ast.dart' ;
12+ import 'package:analyzer/dart/ast/token.dart' ;
1213import 'package:analyzer/dart/element/element.dart' ;
14+ import 'package:analyzer/dart/element/type.dart' ;
1315import 'package:analyzer/diagnostic/diagnostic.dart' ;
1416import 'package:analyzer/source/source_range.dart' ;
1517import 'package:analyzer/src/dart/analysis/session_helper.dart' ;
1618import 'package:analyzer/src/dart/ast/utilities.dart' ;
19+ import 'package:analyzer/src/dart/element/type.dart' ;
1720import 'package:analyzer/src/generated/resolver.dart' ;
1821import 'package:analyzer_plugin/utilities/assist/assist.dart' ;
1922import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart' ;
@@ -32,6 +35,9 @@ abstract class CorrectionProducer extends _AbstractCorrectionProducer {
3235 /// if this producer doesn't support assists.
3336 AssistKind get assistKind => null ;
3437
38+ /// Return the type for the class `bool` from `dart:core` .
39+ DartType get coreTypeBool => resolvedResult.typeProvider.boolType;
40+
3541 /// Return the arguments that should be used when composing the message for a
3642 /// fix, or `null` if the fix message has no parameters or if this producer
3743 /// doesn't support fixes.
@@ -41,8 +47,147 @@ abstract class CorrectionProducer extends _AbstractCorrectionProducer {
4147 /// producer doesn't support fixes.
4248 FixKind get fixKind => null ;
4349
50+ /// Returns `true` if [node] is in a static context.
51+ bool get inStaticContext {
52+ // constructor initializer cannot reference "this"
53+ if (node.thisOrAncestorOfType <ConstructorInitializer >() != null ) {
54+ return true ;
55+ }
56+ // field initializer cannot reference "this"
57+ if (node.thisOrAncestorOfType <FieldDeclaration >() != null ) {
58+ return true ;
59+ }
60+ // static method
61+ var method = node.thisOrAncestorOfType <MethodDeclaration >();
62+ return method != null && method.isStatic;
63+ }
64+
4465 Future <void > compute (DartChangeBuilder builder);
4566
67+ /// Returns an expected [DartType] of [expression] , may be `null` if cannot be
68+ /// inferred.
69+ DartType inferUndefinedExpressionType (Expression expression) {
70+ var parent = expression.parent;
71+ // myFunction();
72+ if (parent is ExpressionStatement ) {
73+ if (expression is MethodInvocation ) {
74+ return VoidTypeImpl .instance;
75+ }
76+ }
77+ // return myFunction();
78+ if (parent is ReturnStatement ) {
79+ var executable = getEnclosingExecutableElement (expression);
80+ return executable? .returnType;
81+ }
82+ // int v = myFunction();
83+ if (parent is VariableDeclaration ) {
84+ var variableDeclaration = parent;
85+ if (variableDeclaration.initializer == expression) {
86+ var variableElement = variableDeclaration.declaredElement;
87+ if (variableElement != null ) {
88+ return variableElement.type;
89+ }
90+ }
91+ }
92+ // myField = 42;
93+ if (parent is AssignmentExpression ) {
94+ var assignment = parent;
95+ if (assignment.leftHandSide == expression) {
96+ var rhs = assignment.rightHandSide;
97+ if (rhs != null ) {
98+ return rhs.staticType;
99+ }
100+ }
101+ }
102+ // v = myFunction();
103+ if (parent is AssignmentExpression ) {
104+ var assignment = parent;
105+ if (assignment.rightHandSide == expression) {
106+ if (assignment.operator .type == TokenType .EQ ) {
107+ // v = myFunction();
108+ var lhs = assignment.leftHandSide;
109+ if (lhs != null ) {
110+ return lhs.staticType;
111+ }
112+ } else {
113+ // v += myFunction();
114+ var method = assignment.staticElement;
115+ if (method != null ) {
116+ var parameters = method.parameters;
117+ if (parameters.length == 1 ) {
118+ return parameters[0 ].type;
119+ }
120+ }
121+ }
122+ }
123+ }
124+ // v + myFunction();
125+ if (parent is BinaryExpression ) {
126+ var binary = parent;
127+ var method = binary.staticElement;
128+ if (method != null ) {
129+ if (binary.rightOperand == expression) {
130+ var parameters = method.parameters;
131+ return parameters.length == 1 ? parameters[0 ].type : null ;
132+ }
133+ }
134+ }
135+ // foo( myFunction() );
136+ if (parent is ArgumentList ) {
137+ var parameter = expression.staticParameterElement;
138+ return parameter? .type;
139+ }
140+ // bool
141+ {
142+ // assert( myFunction() );
143+ if (parent is AssertStatement ) {
144+ var statement = parent;
145+ if (statement.condition == expression) {
146+ return coreTypeBool;
147+ }
148+ }
149+ // if ( myFunction() ) {}
150+ if (parent is IfStatement ) {
151+ var statement = parent;
152+ if (statement.condition == expression) {
153+ return coreTypeBool;
154+ }
155+ }
156+ // while ( myFunction() ) {}
157+ if (parent is WhileStatement ) {
158+ var statement = parent;
159+ if (statement.condition == expression) {
160+ return coreTypeBool;
161+ }
162+ }
163+ // do {} while ( myFunction() );
164+ if (parent is DoStatement ) {
165+ var statement = parent;
166+ if (statement.condition == expression) {
167+ return coreTypeBool;
168+ }
169+ }
170+ // !myFunction()
171+ if (parent is PrefixExpression ) {
172+ var prefixExpression = parent;
173+ if (prefixExpression.operator .type == TokenType .BANG ) {
174+ return coreTypeBool;
175+ }
176+ }
177+ // binary expression '&&' or '||'
178+ if (parent is BinaryExpression ) {
179+ var binaryExpression = parent;
180+ var operatorType = binaryExpression.operator .type;
181+ if (operatorType == TokenType .AMPERSAND_AMPERSAND ||
182+ operatorType == TokenType .BAR_BAR ) {
183+ return coreTypeBool;
184+ }
185+ }
186+ }
187+ // we don't know
188+ return null ;
189+ }
190+
46191 /// Return `true` if the [node] might be a type name.
47192 bool mightBeTypeIdentifier (AstNode node) {
48193 if (node is SimpleIdentifier ) {
0 commit comments