From 3a7df9efd5d1bb5fd14120e12742e40727a7421d Mon Sep 17 00:00:00 2001 From: Greg Littlefield Date: Mon, 15 Jun 2020 13:06:35 -0700 Subject: [PATCH 1/3] Clean up diagnostic base classes --- .../lib/src/diagnostic/component_usage.dart | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/over_react_analyzer_plugin/lib/src/diagnostic/component_usage.dart b/over_react_analyzer_plugin/lib/src/diagnostic/component_usage.dart index b654fb491..c43f24f08 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic/component_usage.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic/component_usage.dart @@ -12,7 +12,6 @@ import 'package:analyzer_plugin/protocol/protocol.dart'; import 'package:analyzer_plugin/protocol/protocol_common.dart'; import 'package:analyzer_plugin/protocol/protocol_generated.dart'; import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; -import 'package:analyzer_plugin/utilities/range_factory.dart'; import 'package:meta/meta.dart'; import 'package:over_react_analyzer_plugin/src/component_usage.dart'; import 'package:over_react_analyzer_plugin/src/error_filtering.dart'; @@ -56,7 +55,7 @@ class ErrorCode { String toString() => uniqueName; } -/// An object used to produce errors. +/// An object used to produce errors and fixes. /// /// Clients may implement this class when implementing plugins. abstract class DiagnosticContributor { @@ -101,9 +100,9 @@ extension ResultLocation on ResolvedUnitResult { } } -/// A generator that will generate an 'edit.getErrors' response. -/// -/// Clients may not extend, implement or mix-in this class. +/// A class that generates errors and fixes for aa set of [contributors] for +/// a given result unit or fixes request. +@sealed class DiagnosticGenerator { /// Initialize a newly created errors generator to use the given /// [contributors]. @@ -112,44 +111,25 @@ class DiagnosticGenerator { /// The contributors to be used to generate the errors. final List contributors; - // TODO dry up - // todo use generatorResult - /// Create an 'edit.getErrors' response for the location in the file specified + /// Creates a 'analysis.errors' response for the the file specified /// by the given [unitResult]. If any of the contributors throws an exception, /// also create a non-fatal 'plugin.error' notification. Future>> generateErrors(ResolvedUnitResult unitResult) async { - final notifications = []; - final collector = DiagnosticCollectorImpl(shouldComputeFixes: false); - for (final contributor in contributors) { - try { - await contributor.computeErrors(unitResult, collector); - } catch (exception, stackTrace) { - notifications.add(PluginErrorParams(false, exception.toString(), stackTrace.toString()).toNotification()); - } - } - - // The analyzer normally filters out errors with "ignore" comments, - // but it doesn't do it for plugin errors, so we need to do that here. - final lineInfo = unitResult.unit.lineInfo; - final filteredErrors = - filterIgnores(collector.errors, lineInfo, () => IgnoreInfo.calculateIgnores(unitResult.content, lineInfo)); - - return GeneratorResult(filteredErrors, notifications); + return _generateErrors(unitResult, DiagnosticCollectorImpl(shouldComputeFixes: false)); } + /// Creates an 'edit.getFixes' response for the location in the file specified + /// by the given [request]. If any of the contributors throws an exception, + /// also create a non-fatal 'plugin.error' notification. Future> generateFixesResponse(DartFixesRequest request) async { - final notifications = []; - final collector = DiagnosticCollectorImpl(shouldComputeFixes: true); + // Recompute the errors and then emit the matching fixes - for (final contributor in contributors) { - try { - await contributor.computeErrors(request.result, collector); - } catch (exception, stackTrace) { - notifications.add(PluginErrorParams(false, exception.toString(), stackTrace.toString()).toNotification()); - } - } + final collector = DiagnosticCollectorImpl(shouldComputeFixes: true); + final errorsResult = await _generateErrors(request.result, collector); + final notifications = [...errorsResult.notifications]; // Return any fixes that contain the given offset. + // TODO use request.errorsToFix instead? final fixes = []; for (var i = 0; i < collector.errors.length; i++) { final error = collector.errors[i]; @@ -163,19 +143,38 @@ class DiagnosticGenerator { error, fixes: [collector.fixes[i]], )); - break; } } return GeneratorResult(EditGetFixesResult(fixes), notifications); } + + Future>> _generateErrors( + ResolvedUnitResult unitResult, DiagnosticCollectorImpl collector) async { + final notifications = []; + for (final contributor in contributors) { + try { + await contributor.computeErrors(unitResult, collector); + } catch (exception, stackTrace) { + notifications.add(PluginErrorParams(false, exception.toString(), stackTrace.toString()).toNotification()); + } + } + + // The analyzer normally filters out errors with "ignore" comments, + // but it doesn't do it for plugin errors, so we need to do that here. + final lineInfo = unitResult.unit.lineInfo; + final filteredErrors = + filterIgnores(collector.errors, lineInfo, () => IgnoreInfo.calculateIgnores(unitResult.content, lineInfo)); + + return GeneratorResult(filteredErrors, notifications); + } } -/// An object that [DiagnosticContributor]s use to record errors. -/// -/// Clients may not extend, implement or mix-in this class. +/// An object that [DiagnosticContributor]s use to record errors and fixes. +@sealed abstract class DiagnosticCollector { void addRawError(AnalysisError error, {PrioritizedSourceChange fix}); + void addError(ErrorCode code, Location location, {bool hasFix, List errorMessageArgs}); /// @@ -205,6 +204,7 @@ abstract class DiagnosticCollector { List fixMessageArgs}); } +@protected class DiagnosticCollectorImpl implements DiagnosticCollector { DiagnosticCollectorImpl({@required this.shouldComputeFixes}); From 3cbf6dd13c23642324666a440c938152927946c8 Mon Sep 17 00:00:00 2001 From: Greg Littlefield Date: Mon, 15 Jun 2020 13:48:40 -0700 Subject: [PATCH 2/3] Reorganize diagnostic contributor code --- .../lib/src/assist/add_props.dart | 2 +- .../lib/src/async_plugin_apis/diagnostic.dart | 110 +++++++- .../lib/src/component_usage.dart | 53 ++++ .../src/diagnostic/analyzer_debug_helper.dart | 4 +- .../src/diagnostic/arrow_function_prop.dart | 4 +- .../bool_prop_name_readability.dart | 4 +- .../lib/src/diagnostic/dom_prop_types.dart | 4 +- .../diagnostic/duplicate_prop_cascade.dart | 4 +- .../lib/src/diagnostic/hashcode_as_key.dart | 4 +- .../lib/src/diagnostic/invalid_child.dart | 4 +- .../diagnostic/missing_cascade_parens.dart | 4 +- .../src/diagnostic/missing_required_prop.dart | 4 +- .../diagnostic/pseudo_static_lifecycle.dart | 4 +- .../src/diagnostic/render_return_value.dart | 6 +- .../lib/src/diagnostic/string_ref.dart | 4 +- .../src/diagnostic/style_missing_unit.dart | 4 +- .../lib/src/diagnostic/variadic_children.dart | 4 +- ...usage.dart => diagnostic_contributor.dart} | 247 +++--------------- .../prop_navigation_contributor.dart | 2 +- .../lib/src/outline/element_outline.dart | 2 +- .../lib/src/plugin.dart | 2 +- .../lib/src/util/location.dart | 40 +++ 22 files changed, 264 insertions(+), 252 deletions(-) rename over_react_analyzer_plugin/lib/src/{diagnostic/component_usage.dart => diagnostic_contributor.dart} (50%) create mode 100644 over_react_analyzer_plugin/lib/src/util/location.dart diff --git a/over_react_analyzer_plugin/lib/src/assist/add_props.dart b/over_react_analyzer_plugin/lib/src/assist/add_props.dart index aa5b85b47..856d3f697 100644 --- a/over_react_analyzer_plugin/lib/src/assist/add_props.dart +++ b/over_react_analyzer_plugin/lib/src/assist/add_props.dart @@ -2,7 +2,7 @@ import 'package:analyzer_plugin/protocol/protocol_generated.dart'; import 'package:analyzer_plugin/utilities/assist/assist.dart'; import 'package:over_react_analyzer_plugin/src/assist/contributor_base.dart'; import 'package:over_react_analyzer_plugin/src/component_usage.dart'; -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; import 'package:over_react_analyzer_plugin/src/fluent_interface_util.dart'; class AddPropsAssistContributor extends AssistContributorBase { diff --git a/over_react_analyzer_plugin/lib/src/async_plugin_apis/diagnostic.dart b/over_react_analyzer_plugin/lib/src/async_plugin_apis/diagnostic.dart index 6925393b4..f8baa25ae 100644 --- a/over_react_analyzer_plugin/lib/src/async_plugin_apis/diagnostic.dart +++ b/over_react_analyzer_plugin/lib/src/async_plugin_apis/diagnostic.dart @@ -33,15 +33,19 @@ import 'dart:async'; import 'package:analyzer/dart/analysis/results.dart'; -import 'package:analyzer/error/error.dart'; +import 'package:analyzer_plugin/channel/channel.dart'; import 'package:analyzer_plugin/plugin/plugin.dart'; +import 'package:analyzer_plugin/protocol/protocol.dart'; import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin; +import 'package:analyzer_plugin/protocol/protocol_common.dart'; import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin; import 'package:analyzer_plugin/protocol/protocol_generated.dart'; // ignore: implementation_imports import 'package:analyzer_plugin/src/utilities/fixes/fixes.dart'; import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:meta/meta.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; +import 'package:over_react_analyzer_plugin/src/error_filtering.dart'; mixin DiagnosticMixin on ServerPlugin { List getDiagnosticContributors(String path); @@ -56,7 +60,7 @@ mixin DiagnosticMixin on ServerPlugin { // If there is something to analyze, do so and notify the analyzer. // Note that notifying with an empty set of errors is important as // this clears errors if they were fixed. - final generator = DiagnosticGenerator(getDiagnosticContributors(analysisResult.path)); + final generator = _DiagnosticGenerator(getDiagnosticContributors(analysisResult.path)); final result = await generator.generateErrors(analysisResult); channel.sendNotification(plugin.AnalysisErrorsParams(analysisResult.path, result.result).toNotification()); result.sendNotifications(channel); @@ -72,7 +76,7 @@ mixin DiagnosticMixin on ServerPlugin { // We want request errors to propagate if they throw final request = await _getFixesRequest(parameters); try { - final generator = DiagnosticGenerator(getDiagnosticContributors(parameters.file)); + final generator = _DiagnosticGenerator(getDiagnosticContributors(parameters.file)); final result = await generator.generateFixesResponse(request); result.sendNotifications(channel); return result.result; @@ -103,3 +107,101 @@ mixin DiagnosticMixin on ServerPlugin { // return result.errors; // } } + + +/// A class that generates errors and fixes for a set of [contributors] for +/// a given result unit or fixes request. +@sealed +class _DiagnosticGenerator { + /// Initialize a newly created errors generator to use the given + /// [contributors]. + _DiagnosticGenerator(this.contributors); + + /// The contributors to be used to generate the errors. + final List contributors; + + /// Creates a 'analysis.errors' response for the the file specified + /// by the given [unitResult]. If any of the contributors throws an exception, + /// also create a non-fatal 'plugin.error' notification. + Future<_GeneratorResult>> generateErrors(ResolvedUnitResult unitResult) async { + return _generateErrors(unitResult, DiagnosticCollectorImpl(shouldComputeFixes: false)); + } + + /// Creates an 'edit.getFixes' response for the location in the file specified + /// by the given [request]. If any of the contributors throws an exception, + /// also create a non-fatal 'plugin.error' notification. + Future<_GeneratorResult> generateFixesResponse(DartFixesRequest request) async { + // Recompute the errors and then emit the matching fixes + + final collector = DiagnosticCollectorImpl(shouldComputeFixes: true); + final errorsResult = await _generateErrors(request.result, collector); + final notifications = [...errorsResult.notifications]; + + // Return any fixes that contain the given offset. + // TODO use request.errorsToFix instead? + final fixes = []; + for (var i = 0; i < collector.errors.length; i++) { + final error = collector.errors[i]; + final errorStart = error.location.offset; + final errorEnd = errorStart + error.location.length; + + // `<=` because we do want the end to be inclusive (you should get + // the fix when your cursor is on the tail end of the error). + if (request.offset >= errorStart && request.offset <= errorEnd) { + fixes.add(AnalysisErrorFixes( + error, + fixes: [collector.fixes[i]], + )); + } + } + + return _GeneratorResult(EditGetFixesResult(fixes), notifications); + } + + Future<_GeneratorResult>> _generateErrors( + ResolvedUnitResult unitResult, DiagnosticCollectorImpl collector) async { + final notifications = []; + for (final contributor in contributors) { + try { + await contributor.computeErrors(unitResult, collector); + } catch (exception, stackTrace) { + notifications.add(PluginErrorParams(false, exception.toString(), stackTrace.toString()).toNotification()); + } + } + + // The analyzer normally filters out errors with "ignore" comments, + // but it doesn't do it for plugin errors, so we need to do that here. + final lineInfo = unitResult.unit.lineInfo; + final filteredErrors = + filterIgnores(collector.errors, lineInfo, () => IgnoreInfo.calculateIgnores(unitResult.content, lineInfo)); + + return _GeneratorResult(filteredErrors, notifications); + } +} + + +/// The result produced by a generator. +/// +/// Adapted from `GeneratorResult` in analyzer_plugin, but with less restrictive typing. +@sealed +class _GeneratorResult { + /// The result to be sent to the server, or `null` if there is no response, as + /// when the generator is generating a notification. + final T result; + + /// The notifications that should be sent to the server. The list will be empty + /// if there are no notifications. + final List notifications; + + /// Initialize a newly created generator result with the given [result] and + /// [notifications]. + _GeneratorResult(this.result, this.notifications); + + /// Use the given communications [channel] to send the notifications to the + /// server. + void sendNotifications(PluginCommunicationChannel channel) { + for (final notification in notifications) { + channel.sendNotification(notification); + } + } +} diff --git a/over_react_analyzer_plugin/lib/src/component_usage.dart b/over_react_analyzer_plugin/lib/src/component_usage.dart index b52c12c0a..91dfb9a80 100644 --- a/over_react_analyzer_plugin/lib/src/component_usage.dart +++ b/over_react_analyzer_plugin/lib/src/component_usage.dart @@ -167,3 +167,56 @@ FluentComponentUsage identifyUsage(AstNode node) { } return null; } + + +class ComponentUsageVisitor extends RecursiveAstVisitor { + ComponentUsageVisitor(this.onComponent); + + final void Function(FluentComponentUsage) onComponent; + + @override + void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { + visitInvocationExpression(node); + } + + @override + void visitMethodInvocation(MethodInvocation node) { + visitInvocationExpression(node); + } + + void visitInvocationExpression(InvocationExpression node) { + var usage = getComponentUsage(node); + if (usage != null) { + onComponent(usage); + } + + node.visitChildren(this); + } +} + +// +//class ComponentUsageElementVisitor extends RecursiveElementVisitor { +// final _OnComponent onComponent; +// +// ComponentUsageElementVisitor(this.onComponent); +// +// @override +// void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { +// return visitInvocationExpression(node); +// } +// +// @override +// void visitMethodInvocation(MethodInvocation node) { +// return visitInvocationExpression(node); +// } +// +// void visitInvocationExpression(InvocationExpression node) { +// var usage = getComponentUsage(node); +// if (usage != null) { +// onComponent(usage); +// } +// +// node.visitChildren(this); +// return null; +// } +//} diff --git a/over_react_analyzer_plugin/lib/src/diagnostic/analyzer_debug_helper.dart b/over_react_analyzer_plugin/lib/src/diagnostic/analyzer_debug_helper.dart index 5794ad6cf..e501bcd4e 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic/analyzer_debug_helper.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic/analyzer_debug_helper.dart @@ -1,6 +1,6 @@ import 'package:analyzer/dart/analysis/results.dart'; import 'package:analyzer_plugin/protocol/protocol_common.dart'; -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; /// Usage: /// AnalyzerDebugHelper debug = new AnalyzerDebugHelper(result, collector); @@ -9,7 +9,7 @@ class AnalyzerDebugHelper { ResolvedUnitResult result; DiagnosticCollector collector; - static const code = ErrorCode( + static const code = DiagnosticCode( 'over_react_debug_analyzer_plugin_helper', "{0}", AnalysisErrorSeverity.INFO, diff --git a/over_react_analyzer_plugin/lib/src/diagnostic/arrow_function_prop.dart b/over_react_analyzer_plugin/lib/src/diagnostic/arrow_function_prop.dart index 188424dcd..38b60024e 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic/arrow_function_prop.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic/arrow_function_prop.dart @@ -1,11 +1,11 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer_plugin/protocol/protocol_common.dart'; import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; import 'package:over_react_analyzer_plugin/src/fluent_interface_util.dart'; class ArrowFunctionPropCascadeDiagnostic extends ComponentUsageDiagnosticContributor { - static final code = ErrorCode( + static final code = DiagnosticCode( 'over_react_cascaded_arrow_functions', 'Unparenthesized arrow function values prevent subsequent cascades', AnalysisErrorSeverity.WARNING, diff --git a/over_react_analyzer_plugin/lib/src/diagnostic/bool_prop_name_readability.dart b/over_react_analyzer_plugin/lib/src/diagnostic/bool_prop_name_readability.dart index 5af663574..efe20e733 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic/bool_prop_name_readability.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic/bool_prop_name_readability.dart @@ -1,10 +1,10 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/ast/visitor.dart'; import 'package:analyzer/dart/element/element.dart'; -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; class BoolPropNameReadabilityDiagnostic extends DiagnosticContributor { - static const code = ErrorCode( + static const code = DiagnosticCode( 'over_react_bool_prop_name_readability', "'{0}.{1}' isn't an easily readable Boolean prop name. Try using a prefix like: {2}", AnalysisErrorSeverity.INFO, diff --git a/over_react_analyzer_plugin/lib/src/diagnostic/dom_prop_types.dart b/over_react_analyzer_plugin/lib/src/diagnostic/dom_prop_types.dart index 313246d1e..062f1b376 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic/dom_prop_types.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic/dom_prop_types.dart @@ -1,8 +1,8 @@ -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; import 'package:over_react_analyzer_plugin/src/fluent_interface_util.dart'; class InvalidDomAttributeDiagnostic extends ComponentUsageDiagnosticContributor { - static const code = ErrorCode( + static const code = DiagnosticCode( 'over_react_invalid_dom_attribute', "{}' isn't a valid HTML attribute prop for '{}'. It may only be used on: {}", AnalysisErrorSeverity.WARNING, diff --git a/over_react_analyzer_plugin/lib/src/diagnostic/duplicate_prop_cascade.dart b/over_react_analyzer_plugin/lib/src/diagnostic/duplicate_prop_cascade.dart index e64b6af3b..650f299cb 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic/duplicate_prop_cascade.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic/duplicate_prop_cascade.dart @@ -1,10 +1,10 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer_plugin/utilities/pair.dart'; -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; import 'package:over_react_analyzer_plugin/src/fluent_interface_util.dart'; class DuplicatePropCascadeDiagnostic extends ComponentUsageDiagnosticContributor { - static final code = ErrorCode( + static final code = DiagnosticCode( 'over_react_duplicate_prop_cascade', "Prop '{0}' is set more than once ({1} of {2}). This is most likely a typo.", AnalysisErrorSeverity.WARNING, diff --git a/over_react_analyzer_plugin/lib/src/diagnostic/hashcode_as_key.dart b/over_react_analyzer_plugin/lib/src/diagnostic/hashcode_as_key.dart index 3db6f3130..9257ff071 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic/hashcode_as_key.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic/hashcode_as_key.dart @@ -1,8 +1,8 @@ -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; import 'package:over_react_analyzer_plugin/src/fluent_interface_util.dart'; class HashCodeAsKeyDiagnostic extends ComponentUsageDiagnosticContributor { - static final code = ErrorCode( + static final code = DiagnosticCode( 'over_react_missing_casecade_parens', "React keys should not be derived from 'hashCode' since it is not unique", AnalysisErrorSeverity.WARNING, diff --git a/over_react_analyzer_plugin/lib/src/diagnostic/invalid_child.dart b/over_react_analyzer_plugin/lib/src/diagnostic/invalid_child.dart index 19645dcb2..b8d200492 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic/invalid_child.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic/invalid_child.dart @@ -5,11 +5,11 @@ import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/src/generated/type_system.dart' show TypeSystem; import 'package:analyzer_plugin/protocol/protocol_common.dart'; import 'package:meta/meta.dart'; -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; import 'package:over_react_analyzer_plugin/src/fluent_interface_util.dart'; class InvalidChildDiagnostic extends ComponentUsageDiagnosticContributor { - static final code = ErrorCode( + static final code = DiagnosticCode( 'over_react_invalid_child', "Invalid child type: '{0}'. Must be a ReactElement, Fragment, string, number, boolean, null, or an Iterable of those types.{1}", AnalysisErrorSeverity.WARNING, diff --git a/over_react_analyzer_plugin/lib/src/diagnostic/missing_cascade_parens.dart b/over_react_analyzer_plugin/lib/src/diagnostic/missing_cascade_parens.dart index 0cc75a4c5..2b73e7089 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic/missing_cascade_parens.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic/missing_cascade_parens.dart @@ -5,10 +5,10 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer_plugin/protocol/protocol_common.dart'; import 'package:over_react_analyzer_plugin/src/diagnostic/analyzer_debug_helper.dart'; -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; class MissingCascadeParensDiagnostic extends DiagnosticContributor { - static final code = ErrorCode( + static final code = DiagnosticCode( 'over_react_missing_cascade_parens', 'Are you missing parentheses around the builder cascade?', AnalysisErrorSeverity.WARNING, diff --git a/over_react_analyzer_plugin/lib/src/diagnostic/missing_required_prop.dart b/over_react_analyzer_plugin/lib/src/diagnostic/missing_required_prop.dart index 531bfe9d9..0c5787007 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic/missing_required_prop.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic/missing_required_prop.dart @@ -1,10 +1,10 @@ import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; import 'package:over_react_analyzer_plugin/src/fluent_interface_util.dart'; class MissingRequiredPropDiagnostic extends ComponentUsageDiagnosticContributor { - static final code = ErrorCode('over_react_required_prop', 'The prop {0} is required.', AnalysisErrorSeverity.WARNING, + static final code = DiagnosticCode('over_react_required_prop', 'The prop {0} is required.', AnalysisErrorSeverity.WARNING, AnalysisErrorType.STATIC_WARNING); static final fixKind = FixKind(code.name, 200, 'Add required prop \'{0}\''); diff --git a/over_react_analyzer_plugin/lib/src/diagnostic/pseudo_static_lifecycle.dart b/over_react_analyzer_plugin/lib/src/diagnostic/pseudo_static_lifecycle.dart index 92a12a95c..f6cb2ab2c 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic/pseudo_static_lifecycle.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic/pseudo_static_lifecycle.dart @@ -1,7 +1,7 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/ast/visitor.dart'; import 'package:analyzer/dart/element/element.dart'; -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; const staticMethodNames = ['getDefaultProps', 'getDerivedStateFromProps']; const instanceMemberWhitelist = [ @@ -14,7 +14,7 @@ const instanceMemberWhitelist = [ ]; class PseudoStaticLifecycleDiagnostic extends DiagnosticContributor { - static final code = ErrorCode( + static final code = DiagnosticCode( 'over_react_pseudo_static_lifecycle', '\'{0}\' must be treated as a static method; only super-calls ' 'and props/state utility methods (like \'newProps\' and \'typedPropsFactory\') are allowed.', diff --git a/over_react_analyzer_plugin/lib/src/diagnostic/render_return_value.dart b/over_react_analyzer_plugin/lib/src/diagnostic/render_return_value.dart index d337f17ef..34aec5cd2 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic/render_return_value.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic/render_return_value.dart @@ -1,18 +1,18 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/ast/visitor.dart'; import 'package:analyzer_plugin/protocol/protocol_common.dart'; -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; import 'package:over_react_analyzer_plugin/src/diagnostic/invalid_child.dart'; import 'package:over_react_analyzer_plugin/src/fluent_interface_util.dart'; class RenderReturnValueDiagnostic extends DiagnosticContributor { - static final invalidTypeErrorCode = ErrorCode( + static final invalidTypeErrorCode = DiagnosticCode( 'over_react_invalid_render_return_type', "Invalid render() return type: '{0}'. Must be a ReactElement, primitive value, or an Iterable of those types.{1}", AnalysisErrorSeverity.WARNING, AnalysisErrorType.STATIC_TYPE_WARNING); - static final preferNullOverFalseErrorCode = ErrorCode( + static final preferNullOverFalseErrorCode = DiagnosticCode( 'over_react_prefer_null_over_false', 'Prefer returning null over false in render. (The dart2js bug involving null has been fixed.)', AnalysisErrorSeverity.WARNING, diff --git a/over_react_analyzer_plugin/lib/src/diagnostic/string_ref.dart b/over_react_analyzer_plugin/lib/src/diagnostic/string_ref.dart index 475b068b4..3d5171c1f 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic/string_ref.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic/string_ref.dart @@ -1,8 +1,8 @@ -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; import 'package:over_react_analyzer_plugin/src/fluent_interface_util.dart'; class StringRefDiagnostic extends ComponentUsageDiagnosticContributor { - static const code = ErrorCode( + static const code = DiagnosticCode( 'over_react_string_ref', 'String refs are deprecated. Use a callback ref instead.', // todo make error in Component2 diff --git a/over_react_analyzer_plugin/lib/src/diagnostic/style_missing_unit.dart b/over_react_analyzer_plugin/lib/src/diagnostic/style_missing_unit.dart index c315e3e82..52502d808 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic/style_missing_unit.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic/style_missing_unit.dart @@ -1,11 +1,11 @@ import 'package:analyzer/analyzer.dart' show ConstantEvaluator; import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/ast/visitor.dart'; -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; import 'package:over_react_analyzer_plugin/src/fluent_interface_util.dart'; class StyleMissingUnitDiagnostic extends ComponentUsageDiagnosticContributor { - static final code = ErrorCode( + static final code = DiagnosticCode( 'over_react_style_missing_unit', // TODO upgrade to error in React 16 "React CSS values must be strings with units, or numbers (in which case 'px' will be used). This will break in React 16.", diff --git a/over_react_analyzer_plugin/lib/src/diagnostic/variadic_children.dart b/over_react_analyzer_plugin/lib/src/diagnostic/variadic_children.dart index a351d5b9c..33ea71971 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic/variadic_children.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic/variadic_children.dart @@ -1,10 +1,10 @@ // Adapted from dart_medic `misc` branch containing over_react diagnostics import 'package:analyzer/dart/ast/ast.dart'; -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; class VariadicChildrenDiagnostic extends ComponentUsageDiagnosticContributor { - static const code = ErrorCode( + static const code = DiagnosticCode( 'over_react_variadic_children', 'Variadic children should be used instead of lists where possible', AnalysisErrorSeverity.WARNING, diff --git a/over_react_analyzer_plugin/lib/src/diagnostic/component_usage.dart b/over_react_analyzer_plugin/lib/src/diagnostic_contributor.dart similarity index 50% rename from over_react_analyzer_plugin/lib/src/diagnostic/component_usage.dart rename to over_react_analyzer_plugin/lib/src/diagnostic_contributor.dart index c43f24f08..74c66a920 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic/component_usage.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic_contributor.dart @@ -3,18 +3,12 @@ import 'dart:async'; import 'package:analyzer/dart/analysis/results.dart'; -import 'package:analyzer/dart/ast/ast.dart'; -import 'package:analyzer/dart/ast/syntactic_entity.dart'; -import 'package:analyzer/dart/ast/visitor.dart'; -import 'package:analyzer/source/source_range.dart'; -import 'package:analyzer_plugin/channel/channel.dart'; -import 'package:analyzer_plugin/protocol/protocol.dart'; import 'package:analyzer_plugin/protocol/protocol_common.dart'; import 'package:analyzer_plugin/protocol/protocol_generated.dart'; import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; import 'package:meta/meta.dart'; -import 'package:over_react_analyzer_plugin/src/component_usage.dart'; -import 'package:over_react_analyzer_plugin/src/error_filtering.dart'; + +import 'component_usage.dart'; export 'package:analyzer_plugin/protocol/protocol_common.dart' show AnalysisErrorType, AnalysisErrorSeverity; export 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart'; @@ -22,13 +16,17 @@ export 'package:analyzer_plugin/utilities/fixes/fixes.dart' show FixKind; export 'package:analyzer_plugin/utilities/range_factory.dart' show range; export 'package:over_react_analyzer_plugin/src/component_usage.dart'; export 'package:over_react_analyzer_plugin/src/util/fix.dart'; +export 'package:over_react_analyzer_plugin/src/util/location.dart'; -class ErrorCode { +/// An error code associated with an [AnalysisError]. +/// +/// adapted from ErrorCode in _fe_analyzer_shared +class DiagnosticCode { /// Initialize a newly created error code to have the given [name]. The message /// associated with the error will be created from the given [message] /// template. The correction associated with the error will be created from the /// given [correction] template. - const ErrorCode(this.name, this.message, this.errorSeverity, this.type, [this.correction]); + const DiagnosticCode(this.name, this.message, this.errorSeverity, this.type, [this.correction]); /// The name of the error code. final String name; @@ -64,109 +62,17 @@ abstract class DiagnosticContributor { Future computeErrors(ResolvedUnitResult result, DiagnosticCollector collector); } -extension ResultLocation on ResolvedUnitResult { - Location location({ - int offset, - int end, - int length, - SourceRange range, - }) { - if (range != null) { - offset = range.offset; - length = range.length; - end = range.end; - } else { - if (offset == null) { - throw ArgumentError.notNull('offset or range'); - } - if (end != null && length != null) { - throw ArgumentError('Cannot specify both `end` and `length`.'); - } else if (length != null) { - end = offset + length; - } else if (end != null) { - length = end - offset; - } else { - end = offset; - length = 0; - } - } - - final info = lineInfo.getLocation(offset); - return Location(path, offset, length, info.lineNumber, info.columnNumber); - } - - Location locationFor(SyntacticEntity entity) { - return location(offset: entity.offset, length: entity.length); - } -} - -/// A class that generates errors and fixes for aa set of [contributors] for -/// a given result unit or fixes request. -@sealed -class DiagnosticGenerator { - /// Initialize a newly created errors generator to use the given - /// [contributors]. - DiagnosticGenerator(this.contributors); - - /// The contributors to be used to generate the errors. - final List contributors; - - /// Creates a 'analysis.errors' response for the the file specified - /// by the given [unitResult]. If any of the contributors throws an exception, - /// also create a non-fatal 'plugin.error' notification. - Future>> generateErrors(ResolvedUnitResult unitResult) async { - return _generateErrors(unitResult, DiagnosticCollectorImpl(shouldComputeFixes: false)); - } - - /// Creates an 'edit.getFixes' response for the location in the file specified - /// by the given [request]. If any of the contributors throws an exception, - /// also create a non-fatal 'plugin.error' notification. - Future> generateFixesResponse(DartFixesRequest request) async { - // Recompute the errors and then emit the matching fixes - - final collector = DiagnosticCollectorImpl(shouldComputeFixes: true); - final errorsResult = await _generateErrors(request.result, collector); - final notifications = [...errorsResult.notifications]; - - // Return any fixes that contain the given offset. - // TODO use request.errorsToFix instead? - final fixes = []; - for (var i = 0; i < collector.errors.length; i++) { - final error = collector.errors[i]; - final errorStart = error.location.offset; - final errorEnd = errorStart + error.location.length; - // `<=` because we do want the end to be inclusive (you should get - // the fix when your cursor is on the tail end of the error). - if (request.offset >= errorStart && request.offset <= errorEnd) { - fixes.add(AnalysisErrorFixes( - error, - fixes: [collector.fixes[i]], - )); - } - } - - return GeneratorResult(EditGetFixesResult(fixes), notifications); - } - - Future>> _generateErrors( - ResolvedUnitResult unitResult, DiagnosticCollectorImpl collector) async { - final notifications = []; - for (final contributor in contributors) { - try { - await contributor.computeErrors(unitResult, collector); - } catch (exception, stackTrace) { - notifications.add(PluginErrorParams(false, exception.toString(), stackTrace.toString()).toNotification()); - } - } - - // The analyzer normally filters out errors with "ignore" comments, - // but it doesn't do it for plugin errors, so we need to do that here. - final lineInfo = unitResult.unit.lineInfo; - final filteredErrors = - filterIgnores(collector.errors, lineInfo, () => IgnoreInfo.calculateIgnores(unitResult.content, lineInfo)); +abstract class ComponentUsageDiagnosticContributor extends DiagnosticContributor { + // computeErrorsForUsage(result, collector, usage) async { + Future computeErrorsForUsage( + ResolvedUnitResult result, DiagnosticCollector collector, FluentComponentUsage usage); - return GeneratorResult(filteredErrors, notifications); + @override + Future computeErrors(ResolvedUnitResult result, DiagnosticCollector collector) async { + final usages = []; + result.unit.accept(ComponentUsageVisitor(usages.add)); + await Future.forEach(usages, (usage) => computeErrorsForUsage(result, collector, usage)); } } @@ -175,7 +81,7 @@ class DiagnosticGenerator { abstract class DiagnosticCollector { void addRawError(AnalysisError error, {PrioritizedSourceChange fix}); - void addError(ErrorCode code, Location location, {bool hasFix, List errorMessageArgs}); + void addError(DiagnosticCode code, Location location, {bool hasFix, List errorMessageArgs}); /// /// use of `buildFileEdit`]` is recommended: @@ -197,13 +103,14 @@ abstract class DiagnosticCollector { /// return builder.sourceChange; /// } /// - Future addErrorWithFix(ErrorCode code, Location location, + Future addErrorWithFix(DiagnosticCode code, Location location, {FixKind fixKind, - FutureOr Function() computeFix, - List errorMessageArgs, - List fixMessageArgs}); + FutureOr Function() computeFix, + List errorMessageArgs, + List fixMessageArgs}); } + @protected class DiagnosticCollectorImpl implements DiagnosticCollector { DiagnosticCollectorImpl({@required this.shouldComputeFixes}); @@ -221,12 +128,12 @@ class DiagnosticCollectorImpl implements DiagnosticCollector { } @override - void addError(ErrorCode code, Location location, + void addError(DiagnosticCode code, Location location, {bool hasFix = false, - FixKind fixKind, - SourceChange fixChange, - List errorMessageArgs, - List fixMessageArgs}) { + FixKind fixKind, + SourceChange fixChange, + List errorMessageArgs, + List fixMessageArgs}) { PrioritizedSourceChange fix; if (fixChange != null) { if (fixChange.edits.isNotEmpty) { @@ -250,11 +157,11 @@ class DiagnosticCollectorImpl implements DiagnosticCollector { } @override - Future addErrorWithFix(ErrorCode code, Location location, + Future addErrorWithFix(DiagnosticCode code, Location location, {FixKind fixKind, - FutureOr Function() computeFix, - List errorMessageArgs, - List fixMessageArgs}) async { + FutureOr Function() computeFix, + List errorMessageArgs, + List fixMessageArgs}) async { addError( code, location, @@ -267,96 +174,6 @@ class DiagnosticCollectorImpl implements DiagnosticCollector { } } -abstract class ComponentUsageDiagnosticContributor extends DiagnosticContributor { - // computeErrorsForUsage(result, collector, usage) async { - Future computeErrorsForUsage( - ResolvedUnitResult result, DiagnosticCollector collector, FluentComponentUsage usage); - - @override - Future computeErrors(ResolvedUnitResult result, DiagnosticCollector collector) async { - final usages = []; - result.unit.accept(ComponentUsageVisitor(usages.add)); - await Future.forEach(usages, (usage) => computeErrorsForUsage(result, collector, usage)); - } -} - -class ComponentUsageVisitor extends RecursiveAstVisitor { - ComponentUsageVisitor(this.onComponent); - - final void Function(FluentComponentUsage) onComponent; - - @override - void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { - visitInvocationExpression(node); - } - - @override - void visitMethodInvocation(MethodInvocation node) { - visitInvocationExpression(node); - } - - void visitInvocationExpression(InvocationExpression node) { - var usage = getComponentUsage(node); - if (usage != null) { - onComponent(usage); - } - - node.visitChildren(this); - } -} - -// -//class ComponentUsageElementVisitor extends RecursiveElementVisitor { -// final _OnComponent onComponent; -// -// ComponentUsageElementVisitor(this.onComponent); -// -// @override -// void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { -// return visitInvocationExpression(node); -// } -// -// @override -// void visitMethodInvocation(MethodInvocation node) { -// return visitInvocationExpression(node); -// } -// -// void visitInvocationExpression(InvocationExpression node) { -// var usage = getComponentUsage(node); -// if (usage != null) { -// onComponent(usage); -// } -// -// node.visitChildren(this); -// return null; -// } -//} - -/// The result produced by a generator. -/// -/// Clients may not extend, implement or mix-in this class. -class GeneratorResult { - /// The result to be sent to the server, or `null` if there is no response, as - /// when the generator is generating a notification. - final T result; - - /// The notifications that should be sent to the server. The list will be empty - /// if there are no notifications. - final List notifications; - - /// Initialize a newly created generator result with the given [result] and - /// [notifications]. - GeneratorResult(this.result, this.notifications); - - /// Use the given communications [channel] to send the notifications to the - /// server. - void sendNotifications(PluginCommunicationChannel channel) { - for (final notification in notifications) { - channel.sendNotification(notification); - } - } -} - // From package:analyzer/src/generated/java_core.dart // Copyright 2013, the Dart project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without diff --git a/over_react_analyzer_plugin/lib/src/navigation/prop_navigation_contributor.dart b/over_react_analyzer_plugin/lib/src/navigation/prop_navigation_contributor.dart index 6582bfdf2..0b98e21db 100644 --- a/over_react_analyzer_plugin/lib/src/navigation/prop_navigation_contributor.dart +++ b/over_react_analyzer_plugin/lib/src/navigation/prop_navigation_contributor.dart @@ -2,7 +2,7 @@ import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol; import 'package:analyzer_plugin/utilities/navigation/navigation.dart'; -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; import 'package:over_react_analyzer_plugin/src/fluent_interface_util.dart'; /// Provides navigation regions from props to their non-generated definitions. diff --git a/over_react_analyzer_plugin/lib/src/outline/element_outline.dart b/over_react_analyzer_plugin/lib/src/outline/element_outline.dart index 9cee7b0c9..6fa973249 100644 --- a/over_react_analyzer_plugin/lib/src/outline/element_outline.dart +++ b/over_react_analyzer_plugin/lib/src/outline/element_outline.dart @@ -1,7 +1,7 @@ import 'package:analyzer_plugin/utilities/analyzer_converter.dart'; import 'package:analyzer_plugin/utilities/outline/outline.dart'; import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin; -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; // TODO can you only create outlines for existing elements?? class ReactElementOutlineContributor implements OutlineContributor { diff --git a/over_react_analyzer_plugin/lib/src/plugin.dart b/over_react_analyzer_plugin/lib/src/plugin.dart index 37e553a0b..315c78236 100644 --- a/over_react_analyzer_plugin/lib/src/plugin.dart +++ b/over_react_analyzer_plugin/lib/src/plugin.dart @@ -51,7 +51,7 @@ import 'package:over_react_analyzer_plugin/src/async_plugin_apis/assist.dart'; import 'package:over_react_analyzer_plugin/src/async_plugin_apis/diagnostic.dart'; import 'package:over_react_analyzer_plugin/src/diagnostic/arrow_function_prop.dart'; import 'package:over_react_analyzer_plugin/src/diagnostic/bool_prop_name_readability.dart'; -import 'package:over_react_analyzer_plugin/src/diagnostic/component_usage.dart'; +import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; import 'package:over_react_analyzer_plugin/src/diagnostic/dom_prop_types.dart'; import 'package:over_react_analyzer_plugin/src/diagnostic/duplicate_prop_cascade.dart'; import 'package:over_react_analyzer_plugin/src/diagnostic/hashcode_as_key.dart'; diff --git a/over_react_analyzer_plugin/lib/src/util/location.dart b/over_react_analyzer_plugin/lib/src/util/location.dart new file mode 100644 index 000000000..7b37d1936 --- /dev/null +++ b/over_react_analyzer_plugin/lib/src/util/location.dart @@ -0,0 +1,40 @@ +import 'package:analyzer/dart/analysis/results.dart'; +import 'package:analyzer/dart/ast/syntactic_entity.dart'; +import 'package:analyzer/source/source_range.dart'; +import 'package:analyzer_plugin/protocol/protocol_common.dart'; + +extension ResultLocation on ResolvedUnitResult { + Location location({ + int offset, + int end, + int length, + SourceRange range, + }) { + if (range != null) { + offset = range.offset; + length = range.length; + end = range.end; + } else { + if (offset == null) { + throw ArgumentError.notNull('offset or range'); + } + if (end != null && length != null) { + throw ArgumentError('Cannot specify both `end` and `length`.'); + } else if (length != null) { + end = offset + length; + } else if (end != null) { + length = end - offset; + } else { + end = offset; + length = 0; + } + } + + final info = lineInfo.getLocation(offset); + return Location(path, offset, length, info.lineNumber, info.columnNumber); + } + + Location locationFor(SyntacticEntity entity) { + return location(offset: entity.offset, length: entity.length); + } +} From abd93e428cbbbebe7f8d53219b69f3b80e66e314 Mon Sep 17 00:00:00 2001 From: Greg Littlefield Date: Mon, 15 Jun 2020 13:50:26 -0700 Subject: [PATCH 3/3] Format --- .../lib/src/async_plugin_apis/diagnostic.dart | 4 +--- .../lib/src/component_usage.dart | 1 - .../src/diagnostic/missing_required_prop.dart | 4 ++-- .../lib/src/diagnostic_contributor.dart | 22 +++++++++---------- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/over_react_analyzer_plugin/lib/src/async_plugin_apis/diagnostic.dart b/over_react_analyzer_plugin/lib/src/async_plugin_apis/diagnostic.dart index f8baa25ae..d2813af7e 100644 --- a/over_react_analyzer_plugin/lib/src/async_plugin_apis/diagnostic.dart +++ b/over_react_analyzer_plugin/lib/src/async_plugin_apis/diagnostic.dart @@ -108,7 +108,6 @@ mixin DiagnosticMixin on ServerPlugin { // } } - /// A class that generates errors and fixes for a set of [contributors] for /// a given result unit or fixes request. @sealed @@ -173,13 +172,12 @@ class _DiagnosticGenerator { // but it doesn't do it for plugin errors, so we need to do that here. final lineInfo = unitResult.unit.lineInfo; final filteredErrors = - filterIgnores(collector.errors, lineInfo, () => IgnoreInfo.calculateIgnores(unitResult.content, lineInfo)); + filterIgnores(collector.errors, lineInfo, () => IgnoreInfo.calculateIgnores(unitResult.content, lineInfo)); return _GeneratorResult(filteredErrors, notifications); } } - /// The result produced by a generator. /// /// Adapted from `GeneratorResult` in analyzer_plugin, but with less restrictive typing. diff --git a/over_react_analyzer_plugin/lib/src/component_usage.dart b/over_react_analyzer_plugin/lib/src/component_usage.dart index 91dfb9a80..5941c7b85 100644 --- a/over_react_analyzer_plugin/lib/src/component_usage.dart +++ b/over_react_analyzer_plugin/lib/src/component_usage.dart @@ -168,7 +168,6 @@ FluentComponentUsage identifyUsage(AstNode node) { return null; } - class ComponentUsageVisitor extends RecursiveAstVisitor { ComponentUsageVisitor(this.onComponent); diff --git a/over_react_analyzer_plugin/lib/src/diagnostic/missing_required_prop.dart b/over_react_analyzer_plugin/lib/src/diagnostic/missing_required_prop.dart index 0c5787007..5fe6c6e13 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic/missing_required_prop.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic/missing_required_prop.dart @@ -4,8 +4,8 @@ import 'package:over_react_analyzer_plugin/src/diagnostic_contributor.dart'; import 'package:over_react_analyzer_plugin/src/fluent_interface_util.dart'; class MissingRequiredPropDiagnostic extends ComponentUsageDiagnosticContributor { - static final code = DiagnosticCode('over_react_required_prop', 'The prop {0} is required.', AnalysisErrorSeverity.WARNING, - AnalysisErrorType.STATIC_WARNING); + static final code = DiagnosticCode('over_react_required_prop', 'The prop {0} is required.', + AnalysisErrorSeverity.WARNING, AnalysisErrorType.STATIC_WARNING); static final fixKind = FixKind(code.name, 200, 'Add required prop \'{0}\''); diff --git a/over_react_analyzer_plugin/lib/src/diagnostic_contributor.dart b/over_react_analyzer_plugin/lib/src/diagnostic_contributor.dart index 74c66a920..a39140e6e 100644 --- a/over_react_analyzer_plugin/lib/src/diagnostic_contributor.dart +++ b/over_react_analyzer_plugin/lib/src/diagnostic_contributor.dart @@ -62,7 +62,6 @@ abstract class DiagnosticContributor { Future computeErrors(ResolvedUnitResult result, DiagnosticCollector collector); } - abstract class ComponentUsageDiagnosticContributor extends DiagnosticContributor { // computeErrorsForUsage(result, collector, usage) async { Future computeErrorsForUsage( @@ -105,12 +104,11 @@ abstract class DiagnosticCollector { /// Future addErrorWithFix(DiagnosticCode code, Location location, {FixKind fixKind, - FutureOr Function() computeFix, - List errorMessageArgs, - List fixMessageArgs}); + FutureOr Function() computeFix, + List errorMessageArgs, + List fixMessageArgs}); } - @protected class DiagnosticCollectorImpl implements DiagnosticCollector { DiagnosticCollectorImpl({@required this.shouldComputeFixes}); @@ -130,10 +128,10 @@ class DiagnosticCollectorImpl implements DiagnosticCollector { @override void addError(DiagnosticCode code, Location location, {bool hasFix = false, - FixKind fixKind, - SourceChange fixChange, - List errorMessageArgs, - List fixMessageArgs}) { + FixKind fixKind, + SourceChange fixChange, + List errorMessageArgs, + List fixMessageArgs}) { PrioritizedSourceChange fix; if (fixChange != null) { if (fixChange.edits.isNotEmpty) { @@ -159,9 +157,9 @@ class DiagnosticCollectorImpl implements DiagnosticCollector { @override Future addErrorWithFix(DiagnosticCode code, Location location, {FixKind fixKind, - FutureOr Function() computeFix, - List errorMessageArgs, - List fixMessageArgs}) async { + FutureOr Function() computeFix, + List errorMessageArgs, + List fixMessageArgs}) async { addError( code, location,