@@ -15,21 +15,15 @@ import 'package:analysis_server/src/services/correction/statement_analyzer.dart'
1515import 'package:analysis_server/src/services/correction/util.dart' ;
1616import 'package:analysis_server/src/services/linter/lint_names.dart' ;
1717import 'package:analysis_server/src/services/search/hierarchy.dart' ;
18- import 'package:analysis_server/src/utilities/flutter.dart' ;
19- import 'package:analyzer/dart/analysis/session.dart' ;
2018import 'package:analyzer/dart/ast/ast.dart' ;
2119import 'package:analyzer/dart/ast/precedence.dart' ;
2220import 'package:analyzer/dart/ast/token.dart' ;
2321import 'package:analyzer/dart/ast/visitor.dart' ;
2422import 'package:analyzer/dart/element/element.dart' ;
2523import 'package:analyzer/dart/element/type.dart' ;
26- import 'package:analyzer/src/dart/analysis/experiments.dart' ;
27- import 'package:analyzer/src/dart/analysis/session_helper.dart' ;
2824import 'package:analyzer/src/dart/ast/token.dart' ;
2925import 'package:analyzer/src/dart/ast/utilities.dart' ;
30- import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
3126import 'package:analyzer/src/generated/java_core.dart' ;
32- import 'package:analyzer/src/generated/resolver.dart' ;
3327import 'package:analyzer/src/generated/source.dart' ;
3428import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
3529import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart' ;
@@ -47,41 +41,26 @@ typedef _SimpleIdentifierVisitor(SimpleIdentifier node);
4741 */
4842class AssistProcessor extends BaseProcessor {
4943 final DartAssistContext context;
50-
51- final AnalysisSession session;
52- final AnalysisSessionHelper sessionHelper;
53- final TypeProvider typeProvider;
54- final Flutter flutter;
55-
5644 final List <Assist > assists = < Assist > [];
5745
5846 AssistProcessor (this .context)
59- : session = context.resolveResult.session,
60- sessionHelper = AnalysisSessionHelper (context.resolveResult.session),
61- typeProvider = context.resolveResult.typeProvider,
62- flutter = Flutter .of (context.resolveResult),
63- super (
47+ : super (
6448 selectionOffset: context.selectionOffset,
6549 selectionLength: context.selectionLength,
6650 resolvedResult: context.resolveResult,
6751 workspace: context.workspace,
6852 );
6953
70- /**
71- * Return the status of the known experiments.
72- */
73- ExperimentStatus get experimentStatus =>
74- (session.analysisContext.analysisOptions as AnalysisOptionsImpl )
75- .experimentStatus;
76-
7754 Future <List <Assist >> compute () async {
7855 if (! setupCompute ()) {
7956 return assists;
8057 }
58+ if (! _containsErrorCode (
59+ {LintNames .always_specify_types, LintNames .type_annotate_public_apis},
60+ )) {
61+ await _addProposals_addTypeAnnotation ();
62+ }
8163
82- await _addProposal_addTypeAnnotation_DeclaredIdentifier ();
83- await _addProposal_addTypeAnnotation_SimpleFormalParameter ();
84- await _addProposal_addTypeAnnotation_VariableDeclaration ();
8564 await _addProposal_assignToLocalVariable ();
8665 await _addProposal_convertClassToMixin ();
8766 await _addProposal_convertDocumentationIntoBlock ();
@@ -138,8 +117,8 @@ class AssistProcessor extends BaseProcessor {
138117 await _addProposal_splitAndCondition ();
139118 await _addProposal_splitVariableDeclaration ();
140119 await _addProposal_surroundWith ();
141- if (! _containsDiagnostic (
142- LintNames .curly_braces_in_flow_control_structures,
120+ if (! _containsErrorCode (
121+ { LintNames .curly_braces_in_flow_control_structures} ,
143122 )) {
144123 await _addProposal_useCurlyBraces ();
145124 }
@@ -229,160 +208,6 @@ class AssistProcessor extends BaseProcessor {
229208 assists.add (new Assist (kind, change));
230209 }
231210
232- Future <void > _addProposal_addTypeAnnotation_DeclaredIdentifier () async {
233- DeclaredIdentifier declaredIdentifier =
234- node.thisOrAncestorOfType <DeclaredIdentifier >();
235- if (declaredIdentifier == null ) {
236- ForStatement forEach = node.thisOrAncestorMatching (
237- (node) => node is ForStatement && node.forLoopParts is ForEachParts );
238- ForEachParts forEachParts = forEach? .forLoopParts;
239- int offset = node.offset;
240- if (forEach != null &&
241- forEachParts.iterable != null &&
242- offset < forEachParts.iterable.offset) {
243- declaredIdentifier = forEachParts is ForEachPartsWithDeclaration
244- ? forEachParts.loopVariable
245- : null ;
246- }
247- }
248- if (declaredIdentifier == null ) {
249- _coverageMarker ();
250- return ;
251- }
252- // Ensure that there isn't already a type annotation.
253- if (declaredIdentifier.type != null ) {
254- _coverageMarker ();
255- return ;
256- }
257- DartType type = declaredIdentifier.identifier.staticType;
258- if (type is ! InterfaceType && type is ! FunctionType ) {
259- _coverageMarker ();
260- return ;
261- }
262- _configureTargetLocation (node);
263-
264- var changeBuilder = _newDartChangeBuilder ();
265- bool validChange = true ;
266- await changeBuilder.addFileEdit (file, (DartFileEditBuilder builder) {
267- Token keyword = declaredIdentifier.keyword;
268- if (keyword.keyword == Keyword .VAR ) {
269- builder.addReplacement (range.token (keyword), (DartEditBuilder builder) {
270- validChange = builder.writeType (type);
271- });
272- } else {
273- builder.addInsertion (declaredIdentifier.identifier.offset,
274- (DartEditBuilder builder) {
275- validChange = builder.writeType (type);
276- builder.write (' ' );
277- });
278- }
279- });
280- if (validChange) {
281- _addAssistFromBuilder (changeBuilder, DartAssistKind .ADD_TYPE_ANNOTATION );
282- }
283- }
284-
285- Future <void > _addProposal_addTypeAnnotation_SimpleFormalParameter () async {
286- AstNode node = this .node;
287- // should be the name of a simple parameter
288- if (node is ! SimpleIdentifier || node.parent is ! SimpleFormalParameter ) {
289- _coverageMarker ();
290- return ;
291- }
292- SimpleIdentifier name = node;
293- SimpleFormalParameter parameter = node.parent;
294- // the parameter should not have a type
295- if (parameter.type != null ) {
296- _coverageMarker ();
297- return ;
298- }
299- // prepare the type
300- DartType type = parameter.declaredElement.type;
301- // TODO(scheglov) If the parameter is in a method declaration, and if the
302- // method overrides a method that has a type for the corresponding
303- // parameter, it would be nice to copy down the type from the overridden
304- // method.
305- if (type is ! InterfaceType ) {
306- _coverageMarker ();
307- return ;
308- }
309- // prepare type source
310- _configureTargetLocation (node);
311-
312- var changeBuilder = _newDartChangeBuilder ();
313- bool validChange = true ;
314- await changeBuilder.addFileEdit (file, (DartFileEditBuilder builder) {
315- builder.addInsertion (name.offset, (DartEditBuilder builder) {
316- validChange = builder.writeType (type);
317- builder.write (' ' );
318- });
319- });
320- if (validChange) {
321- _addAssistFromBuilder (changeBuilder, DartAssistKind .ADD_TYPE_ANNOTATION );
322- }
323- }
324-
325- Future <void > _addProposal_addTypeAnnotation_VariableDeclaration () async {
326- AstNode node = this .node;
327- // prepare VariableDeclarationList
328- VariableDeclarationList declarationList =
329- node.thisOrAncestorOfType <VariableDeclarationList >();
330- if (declarationList == null ) {
331- _coverageMarker ();
332- return ;
333- }
334- // may be has type annotation already
335- if (declarationList.type != null ) {
336- _coverageMarker ();
337- return ;
338- }
339- // prepare single VariableDeclaration
340- List <VariableDeclaration > variables = declarationList.variables;
341- if (variables.length != 1 ) {
342- _coverageMarker ();
343- return ;
344- }
345- VariableDeclaration variable = variables[0 ];
346- // must be not after the name of the variable
347- if (selectionOffset > variable.name.end) {
348- _coverageMarker ();
349- return ;
350- }
351- // we need an initializer to get the type from
352- Expression initializer = variable.initializer;
353- if (initializer == null ) {
354- _coverageMarker ();
355- return ;
356- }
357- DartType type = initializer.staticType;
358- // prepare type source
359- if ((type is ! InterfaceType || type.isDartCoreNull) &&
360- type is ! FunctionType ) {
361- _coverageMarker ();
362- return ;
363- }
364- _configureTargetLocation (node);
365-
366- var changeBuilder = _newDartChangeBuilder ();
367- bool validChange = true ;
368- await changeBuilder.addFileEdit (file, (DartFileEditBuilder builder) {
369- Token keyword = declarationList.keyword;
370- if (keyword? .keyword == Keyword .VAR ) {
371- builder.addReplacement (range.token (keyword), (DartEditBuilder builder) {
372- validChange = builder.writeType (type);
373- });
374- } else {
375- builder.addInsertion (variable.offset, (DartEditBuilder builder) {
376- validChange = builder.writeType (type);
377- builder.write (' ' );
378- });
379- }
380- });
381- if (validChange) {
382- _addAssistFromBuilder (changeBuilder, DartAssistKind .ADD_TYPE_ANNOTATION );
383- }
384- }
385-
386211 Future <void > _addProposal_assignToLocalVariable () async {
387212 // prepare enclosing ExpressionStatement
388213 ExpressionStatement expressionStatement;
@@ -3857,6 +3682,19 @@ class AssistProcessor extends BaseProcessor {
38573682 _addAssistFromBuilder (changeBuilder, DartAssistKind .USE_CURLY_BRACES );
38583683 }
38593684
3685+ Future <void > _addProposals_addTypeAnnotation () async {
3686+ var changeBuilder =
3687+ await createBuilder_addTypeAnnotation_DeclaredIdentifier ();
3688+ _addAssistFromBuilder (changeBuilder, DartAssistKind .ADD_TYPE_ANNOTATION );
3689+
3690+ changeBuilder =
3691+ await createBuilder_addTypeAnnotation_SimpleFormalParameter ();
3692+ _addAssistFromBuilder (changeBuilder, DartAssistKind .ADD_TYPE_ANNOTATION );
3693+
3694+ changeBuilder = await createBuilder_addTypeAnnotation_VariableDeclaration ();
3695+ _addAssistFromBuilder (changeBuilder, DartAssistKind .ADD_TYPE_ANNOTATION );
3696+ }
3697+
38603698 /**
38613699 * Return `true` if all of the parameters in the given list of [parameters]
38623700 * have an explicit type annotation.
@@ -3891,14 +3729,14 @@ class AssistProcessor extends BaseProcessor {
38913729 }
38923730 }
38933731
3894- bool _containsDiagnostic ( String diagnosticCode ) {
3732+ bool _containsErrorCode ( Set < String > errorCodes ) {
38953733 final fileOffset = node.offset;
38963734 for (var error in context.resolveResult.errors) {
38973735 final errorSource = error.source;
38983736 if (file == errorSource.fullName) {
38993737 if (fileOffset >= error.offset &&
39003738 fileOffset <= error.offset + error.length) {
3901- if (error.errorCode.name == diagnosticCode ) {
3739+ if (errorCodes. contains ( error.errorCode.name) ) {
39023740 return true ;
39033741 }
39043742 }
0 commit comments