diff --git a/pkg/_fe_analyzer_shared/lib/src/base/diagnostic_message.dart b/pkg/_fe_analyzer_shared/lib/src/base/diagnostic_message.dart deleted file mode 100644 index d9f5a875e60..00000000000 --- a/pkg/_fe_analyzer_shared/lib/src/base/diagnostic_message.dart +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) 2025, 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/base/analyzer_public_api.dart'; -import 'package:_fe_analyzer_shared/src/base/errors.dart'; - -/// A single message associated with a [Diagnostic], consisting of the text of -/// the message and the location associated with it. -/// -/// Clients may not extend, implement or mix-in this class. -@AnalyzerPublicApi( - message: 'Exported by package:analyzer/diagnostic/diagnostic.dart', -) -abstract class DiagnosticMessage { - /// The absolute and normalized path of the file associated with this message. - String get filePath; - - /// The length of the source range associated with this message. - int get length; - - /// The zero-based offset from the start of the file to the beginning of the - /// source range associated with this message. - int get offset; - - /// The URL containing documentation about this diagnostic message, if any. - /// - /// Note: this should not be confused with the location in the user's code - /// where the error was reported; that information can be obtained from - /// [filePath], [length], and [offset]. - String? get url; - - /// Gets the text of the message. - /// - /// If [includeUrl] is `true`, and this diagnostic message has an associated - /// URL, it is included in the returned value in a human-readable way. - /// Clients that wish to present URLs as simple text can do this. If - /// [includeUrl] is `false`, no URL is included in the returned value. - /// Clients that have a special mechanism for presenting URLs (e.g. as a - /// clickable link) should do this and then consult the [url] getter to access - /// the URL. - String messageText({required bool includeUrl}); -} - -/// A concrete implementation of a diagnostic message. -class DiagnosticMessageImpl implements DiagnosticMessage { - @override - final String filePath; - - @override - final int length; - - final String _message; - - @override - final int offset; - - @override - final String? url; - - /// Initialize a newly created message to represent a [message] reported in - /// the file at the given [filePath] at the given [offset] and with the given - /// [length]. - DiagnosticMessageImpl({ - required this.filePath, - required this.length, - required String message, - required this.offset, - required this.url, - }) : _message = message; - - @override - String messageText({required bool includeUrl}) { - if (includeUrl && url != null) { - StringBuffer result = new StringBuffer(_message); - if (!_message.endsWith('.')) { - result.write('.'); - } - result.write(' See $url'); - return result.toString(); - } - return _message; - } -} - -/// An indication of the severity of a [Diagnostic]. -@AnalyzerPublicApi( - message: 'exported by package:analyzer/diagnostic/diagnostic.dart', -) -enum Severity { error, warning, info } diff --git a/pkg/_fe_analyzer_shared/lib/src/base/errors.dart b/pkg/_fe_analyzer_shared/lib/src/base/errors.dart index 0730045233c..91315d148ca 100644 --- a/pkg/_fe_analyzer_shared/lib/src/base/errors.dart +++ b/pkg/_fe_analyzer_shared/lib/src/base/errors.dart @@ -8,12 +8,7 @@ library; import 'dart:math'; import 'package:_fe_analyzer_shared/src/base/analyzer_public_api.dart'; -import 'package:_fe_analyzer_shared/src/base/diagnostic_message.dart'; -import 'package:_fe_analyzer_shared/src/base/source.dart'; -import 'package:_fe_analyzer_shared/src/base/source_range.dart'; -import 'package:_fe_analyzer_shared/src/base/syntactic_entity.dart'; import 'package:_fe_analyzer_shared/src/scanner/characters.dart'; -import 'package:source_span/source_span.dart'; import 'customized_codes.dart'; @@ -76,175 +71,6 @@ String formatList(String pattern, List? arguments) { return buffer.join(); } -/// A diagnostic, as defined by the [Diagnostic Design Guidelines][guidelines]: -/// -/// > An indication of a specific problem at a specific location within the -/// > source code being processed by a development tool. -/// -/// Clients may not extend, implement or mix-in this class. -/// -/// [guidelines]: https://github.com/dart-lang/sdk/blob/main/pkg/analyzer/doc/implementation/diagnostics.md -@AnalyzerPublicApi( - message: 'Exported by package:analyzer/diagnostic/diagnostic.dart', -) -class Diagnostic { - /// The diagnostic code associated with the diagnostic. - final DiagnosticCode diagnosticCode; - - /// A list of messages that provide context for understanding the problem - /// being reported. The list will be empty if there are no such messages. - final List contextMessages; - - /// A description of how to fix the problem, or `null` if there is no such - /// description. - final String? correctionMessage; - - /// A message describing what is wrong and why. - final DiagnosticMessage problemMessage; - - /// The source in which the diagnostic occurred, or `null` if unknown. - final Source source; - - Diagnostic.forValues({ - required this.source, - required int offset, - required int length, - required this.diagnosticCode, - required String message, - this.correctionMessage, - this.contextMessages = const [], - }) : problemMessage = new DiagnosticMessageImpl( - filePath: source.fullName, - length: length, - message: message, - offset: offset, - url: null, - ); - - /// Initialize a newly created diagnostic. - /// - /// The diagnostic is associated with the given [source] and is located at the - /// given [offset] with the given [length]. The diagnostic will have the given - /// [diagnosticCode] and the list of [arguments] will be used to complete the - /// message and correction. If any [contextMessages] are provided, they will - /// be recorded with the diagnostic. - factory Diagnostic.tmp({ - required Source source, - required int offset, - required int length, - required DiagnosticCode diagnosticCode, - List arguments = const [], - List contextMessages = const [], - }) { - assert( - arguments.length == diagnosticCode.numParameters, - 'Message $diagnosticCode requires ${diagnosticCode.numParameters} ' - 'argument${diagnosticCode.numParameters == 1 ? '' : 's'}, but ' - '${arguments.length} ' - 'argument${arguments.length == 1 ? ' was' : 's were'} ' - 'provided', - ); - String message = formatList(diagnosticCode.problemMessage, arguments); - String? correctionTemplate = diagnosticCode.correctionMessage; - String? correctionMessage; - if (correctionTemplate != null) { - correctionMessage = formatList(correctionTemplate, arguments); - } - - return new Diagnostic.forValues( - source: source, - offset: offset, - length: length, - diagnosticCode: diagnosticCode, - message: message, - correctionMessage: correctionMessage, - contextMessages: contextMessages, - ); - } - - /// The template used to create the correction to be displayed for this - /// diagnostic, or `null` if there is no correction information for this - /// error. The correction should indicate how the user can fix the error. - @Deprecated("Use 'correctionMessage' instead.") - String? get correction => correctionMessage; - - @Deprecated("Use 'diagnosticCode' instead") - DiagnosticCode get errorCode => diagnosticCode; - - @override - int get hashCode { - int hashCode = offset; - hashCode ^= message.hashCode; - hashCode ^= source.hashCode; - return hashCode; - } - - /// The number of characters from the offset to the end of the source which - /// encompasses the compilation error. - int get length => problemMessage.length; - - /// The message to be displayed for this diagnostic. - /// - /// The message indicates what is wrong and why it is wrong. - String get message => problemMessage.messageText(includeUrl: true); - - /// The character offset from the beginning of the source (zero based) where - /// the diagnostic occurred. - int get offset => problemMessage.offset; - - Severity get severity { - switch (diagnosticCode.severity) { - case DiagnosticSeverity.ERROR: - return Severity.error; - case DiagnosticSeverity.WARNING: - return Severity.warning; - case DiagnosticSeverity.INFO: - return Severity.info; - default: - throw new StateError('Invalid severity: ${diagnosticCode.severity}'); - } - } - - @override - bool operator ==(Object other) { - if (identical(other, this)) { - return true; - } - // prepare the other Diagnostic. - if (other is Diagnostic) { - // Quick checks. - if (!identical(diagnosticCode, other.diagnosticCode)) { - return false; - } - if (offset != other.offset || length != other.length) { - return false; - } - // Deep checks. - if (message != other.message) { - return false; - } - if (source != other.source) { - return false; - } - return true; - } - return false; - } - - @override - String toString() { - StringBuffer buffer = new StringBuffer(); - buffer.write(source.fullName); - buffer.write("("); - buffer.write(offset); - buffer.write(".."); - buffer.write(offset + length - 1); - buffer.write("): "); - buffer.write(message); - return buffer.toString(); - } -} - /// An error code associated with an `AnalysisError`. /// /// Generally, messages should follow the [Guide for Writing @@ -376,23 +202,6 @@ abstract class DiagnosticCodeImpl extends DiagnosticCode { DiagnosticSeverity get severity => type.severity; } -/// Private subtype of [DiagnosticCode] that supports runtime checking of -/// parameter types. -class DiagnosticCodeWithExpectedTypes extends DiagnosticCodeImpl { - final List? expectedTypes; - - const DiagnosticCodeWithExpectedTypes({ - super.correctionMessage, - super.hasPublishedDocs = false, - super.isUnresolvedIdentifier = false, - required super.name, - required super.problemMessage, - required super.type, - required super.uniqueName, - this.expectedTypes, - }); -} - /// The severity of an [DiagnosticCode]. @AnalyzerPublicApi(message: 'exported by package:analyzer/error/error.dart') class DiagnosticSeverity implements Comparable { @@ -565,215 +374,3 @@ class DiagnosticType implements Comparable { @override String toString() => name; } - -/// Common functionality for [DiagnosticCode]-derived classes that represent -/// errors that take arguments. -/// -/// This class provides a [withArguments] getter, which can be used to supply -/// arguments and produce a [LocatableDiagnostic]. -/// -/// Note: the type argument `T` should be instantiated with a function type. But -/// it is typed as `extends Object` in order to reduce the risk of accidental -/// dynamic invocation of [withArguments]. -class DiagnosticWithArguments - extends DiagnosticCodeWithExpectedTypes { - /// Function accepting named arguments and returning [LocatableDiagnostic]. - /// - /// The value returned by this function can - /// be associated with a location in the source code using the - /// [LocatableDiagnostic.at] method, and then the result can be passed to - /// [DiagnosticReporter.reportError]. - final T withArguments; - - const DiagnosticWithArguments({ - required super.name, - required super.problemMessage, - super.correctionMessage, - super.hasPublishedDocs = false, - super.isUnresolvedIdentifier = false, - required super.type, - required super.uniqueName, - required super.expectedTypes, - required this.withArguments, - }); -} - -/// Common functionality for [DiagnosticCode]-derived classes that represent -/// errors that do not take arguments. -/// -/// This class implements [LocatableDiagnostic], which means that instances can -/// be associated with a location in the source code using the [at] method, and -/// then the result can be passed to [DiagnosticReporter.reportError]. -base mixin DiagnosticWithoutArguments on DiagnosticCodeImpl - implements LocatableDiagnostic { - @override - List get arguments => const []; - - @override - DiagnosticCode get code => this; - - @override - Iterable get contextMessages => const []; - - @override - LocatedDiagnostic at(SyntacticEntity node) => - atOffset(offset: node.offset, length: node.length); - - @override - LocatedDiagnostic atOffset({required int offset, required int length}) => - new LocatedDiagnostic(this, offset, length); - - @override - LocatedDiagnostic atSourceRange(SourceRange sourceRange) => - atOffset(offset: sourceRange.offset, length: sourceRange.length); - - @override - LocatedDiagnostic atSourceSpan(SourceSpan span) => - atOffset(offset: span.start.offset, length: span.length); - - @override - LocatableDiagnostic withContextMessages( - Iterable messages, - ) => new LocatableDiagnosticImpl( - code, - arguments, - contextMessages: [...messages], - ); -} - -/// Concrete implementation of [DiagnosticWithoutArguments], used for diagnostic -/// messages that don't take any arguments. -/// -/// This needs to be a separate class from [DiagnosticWithoutArguments] because -/// [DiagnosticWithoutArguments] is a mixin. -final class DiagnosticWithoutArgumentsImpl - extends DiagnosticCodeWithExpectedTypes - with DiagnosticWithoutArguments { - const DiagnosticWithoutArgumentsImpl({ - required super.name, - required super.problemMessage, - super.correctionMessage, - super.hasPublishedDocs = false, - super.isUnresolvedIdentifier = false, - required super.type, - required super.uniqueName, - super.expectedTypes, - }); -} - -/// Expected type of a diagnostic code's parameter. -enum ExpectedType { element, int, name, object, string, token, type, uri } - -/// Interface for a diagnostic that does not have any unfilled template -/// parameters, and hence is ready to be associated with a location in the -/// source code. -/// -/// This could either be the result of calling `withArguments` on a diagnostic -/// code that requires arguments, or it could be a diagnostic code that doesn't -/// require arguments. -abstract final class LocatableDiagnostic { - /// The arguments that were applied to the diagnostic, or the empty list if - /// [code] doesn't accept any arguments. - List get arguments; - - /// The [DiagnosticCode] associated with the diagnostic. - DiagnosticCode get code; - - /// The context messages that were applied to the diagnostic. - Iterable get contextMessages; - - /// Converts this diagnostic to a [LocatedDiagnostic] by applying it to a - /// syntactic entity in the source code. - /// - /// The result may be passed to [DiagnosticReporter.reportError]. - LocatedDiagnostic at(SyntacticEntity node); - - /// Converts this diagnostic to a [LocatedDiagnostic] by applying it to a - /// location in the source code. - /// - /// The result may be passed to [DiagnosticReporter.reportError]. - LocatedDiagnostic atOffset({required int offset, required int length}); - - /// Converts this diagnostic to a [LocatedDiagnostic] by applying it to a - /// location in the source code. - /// - /// The result may be passed to [DiagnosticReporter.reportError]. - LocatedDiagnostic atSourceRange(SourceRange sourceRange); - - /// Converts this diagnostic to a [LocatedDiagnostic] by applying it to a - /// location in the source code. - /// - /// The result may be passed to [DiagnosticReporter.reportError]. - LocatedDiagnostic atSourceSpan(SourceSpan span); - - /// Attaches context messages to this diagnostic. - /// - /// The return value is a fresh instance of [LocatableDiagnostic]. This allows - /// for a literate style of error reporting, e.g.: - /// ```dart - /// // For an diagnostic code that doesn't take arguments: - /// diagnosticReporter.reportError( - /// diagnosticCode.withContextMessages(messages).at(astNode)); - /// - /// // For a diagnostic code that does take arguments: - /// diagnosticReporter.reportError( - /// diagnosticCode - /// .withArguments(...) - /// .withContextMessages(messages) - /// .at(astNode)); - /// ``` - LocatableDiagnostic withContextMessages(Iterable messages); -} - -/// Concrete implementation of [LocatableDiagnostic]. -final class LocatableDiagnosticImpl implements LocatableDiagnostic { - @override - final DiagnosticCode code; - - @override - final List arguments; - - @override - final Iterable contextMessages; - - LocatableDiagnosticImpl( - this.code, - this.arguments, { - this.contextMessages = const [], - }); - - @override - LocatedDiagnostic at(SyntacticEntity node) => - atOffset(offset: node.offset, length: node.length); - - @override - LocatedDiagnostic atOffset({required int offset, required int length}) => - new LocatedDiagnostic(this, offset, length); - - @override - LocatedDiagnostic atSourceRange(SourceRange sourceRange) => - atOffset(offset: sourceRange.offset, length: sourceRange.length); - - @override - LocatedDiagnostic atSourceSpan(SourceSpan span) => - atOffset(offset: span.start.offset, length: span.length); - - @override - LocatableDiagnostic withContextMessages( - Iterable messages, - ) => new LocatableDiagnosticImpl( - code, - arguments, - contextMessages: [...contextMessages, ...messages], - ); -} - -/// A diagnostic that does not have any unfilled template parameters, and has -/// been associated with a location in the source code. -final class LocatedDiagnostic { - final LocatableDiagnostic locatableDiagnostic; - final int offset; - final int length; - - LocatedDiagnostic(this.locatableDiagnostic, this.offset, this.length); -} diff --git a/pkg/_fe_analyzer_shared/pubspec.yaml b/pkg/_fe_analyzer_shared/pubspec.yaml index dc8d868005e..1b06f3982b6 100644 --- a/pkg/_fe_analyzer_shared/pubspec.yaml +++ b/pkg/_fe_analyzer_shared/pubspec.yaml @@ -12,7 +12,6 @@ resolution: workspace dependencies: meta: ^1.9.0 - source_span: ^1.10.0 # We use 'any' version constraints here as we get our package versions from # the dart-lang/sdk repo's DEPS file. Note that this is a special case; the diff --git a/pkg/analysis_server/lib/src/diagnostic.dart b/pkg/analysis_server/lib/src/diagnostic.dart index c72add3a499..04a679071bf 100644 --- a/pkg/analysis_server/lib/src/diagnostic.dart +++ b/pkg/analysis_server/lib/src/diagnostic.dart @@ -3,6 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'package:_fe_analyzer_shared/src/base/errors.dart'; +import 'package:analyzer/src/diagnostic/diagnostic.dart'; import 'diagnostic.dart' as diag; diff --git a/pkg/analysis_server_plugin/api.txt b/pkg/analysis_server_plugin/api.txt index f5b4f4614e1..d6e86e2f688 100644 --- a/pkg/analysis_server_plugin/api.txt +++ b/pkg/analysis_server_plugin/api.txt @@ -161,7 +161,6 @@ dart:core: bool (referenced) int (referenced) package:_fe_analyzer_shared/src/base/errors.dart: - Diagnostic (referenced) DiagnosticCode (referenced) package:_fe_analyzer_shared/src/base/source_range.dart: SourceRange (referenced) @@ -193,6 +192,8 @@ package:analyzer/dart/element/type_provider.dart: TypeProvider (referenced) package:analyzer/dart/element/type_system.dart: TypeSystem (referenced) +package:analyzer/diagnostic/diagnostic.dart: + Diagnostic (referenced) package:analyzer/instrumentation/service.dart: InstrumentationService (referenced) package:analyzer/src/dart/ast/ast.dart: diff --git a/pkg/analyzer/lib/diagnostic/diagnostic.dart b/pkg/analyzer/lib/diagnostic/diagnostic.dart index 4e9fc92e10e..4c1b8b81b51 100644 --- a/pkg/analyzer/lib/diagnostic/diagnostic.dart +++ b/pkg/analyzer/lib/diagnostic/diagnostic.dart @@ -2,6 +2,178 @@ // 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. -export 'package:_fe_analyzer_shared/src/base/diagnostic_message.dart' - show DiagnosticMessage, Severity; -export 'package:_fe_analyzer_shared/src/base/errors.dart' show Diagnostic; +import 'package:_fe_analyzer_shared/src/base/errors.dart'; +import 'package:analyzer/source/source.dart'; +import 'package:analyzer/src/diagnostic/diagnostic.dart' + show DiagnosticMessage, DiagnosticMessageImpl; + +export 'package:analyzer/src/diagnostic/diagnostic.dart' show DiagnosticMessage; + +/// A diagnostic, as defined by the [Diagnostic Design Guidelines][guidelines]: +/// +/// > An indication of a specific problem at a specific location within the +/// > source code being processed by a development tool. +/// +/// Clients may not extend, implement or mix-in this class. +/// +/// [guidelines]: https://github.com/dart-lang/sdk/blob/main/pkg/analyzer/doc/implementation/diagnostics.md +class Diagnostic { + /// The diagnostic code associated with the diagnostic. + final DiagnosticCode diagnosticCode; + + /// A list of messages that provide context for understanding the problem + /// being reported. The list will be empty if there are no such messages. + final List contextMessages; + + /// A description of how to fix the problem, or `null` if there is no such + /// description. + final String? correctionMessage; + + /// A message describing what is wrong and why. + final DiagnosticMessage problemMessage; + + /// The source in which the diagnostic occurred, or `null` if unknown. + final Source source; + + Diagnostic.forValues({ + required this.source, + required int offset, + required int length, + required this.diagnosticCode, + required String message, + this.correctionMessage, + this.contextMessages = const [], + }) : problemMessage = DiagnosticMessageImpl( + filePath: source.fullName, + length: length, + message: message, + offset: offset, + url: null, + ); + + /// Initialize a newly created diagnostic. + /// + /// The diagnostic is associated with the given [source] and is located at the + /// given [offset] with the given [length]. The diagnostic will have the given + /// [diagnosticCode] and the list of [arguments] will be used to complete the + /// message and correction. If any [contextMessages] are provided, they will + /// be recorded with the diagnostic. + factory Diagnostic.tmp({ + required Source source, + required int offset, + required int length, + required DiagnosticCode diagnosticCode, + List arguments = const [], + List contextMessages = const [], + }) { + assert( + arguments.length == diagnosticCode.numParameters, + 'Message $diagnosticCode requires ${diagnosticCode.numParameters} ' + 'argument${diagnosticCode.numParameters == 1 ? '' : 's'}, but ' + '${arguments.length} ' + 'argument${arguments.length == 1 ? ' was' : 's were'} ' + 'provided', + ); + String message = formatList(diagnosticCode.problemMessage, arguments); + String? correctionTemplate = diagnosticCode.correctionMessage; + String? correctionMessage; + if (correctionTemplate != null) { + correctionMessage = formatList(correctionTemplate, arguments); + } + + return Diagnostic.forValues( + source: source, + offset: offset, + length: length, + diagnosticCode: diagnosticCode, + message: message, + correctionMessage: correctionMessage, + contextMessages: contextMessages, + ); + } + + /// The template used to create the correction to be displayed for this + /// diagnostic, or `null` if there is no correction information for this + /// error. The correction should indicate how the user can fix the error. + @Deprecated("Use 'correctionMessage' instead.") + String? get correction => correctionMessage; + + @Deprecated("Use 'diagnosticCode' instead") + DiagnosticCode get errorCode => diagnosticCode; + + @override + int get hashCode { + int hashCode = offset; + hashCode ^= message.hashCode; + hashCode ^= source.hashCode; + return hashCode; + } + + /// The number of characters from the offset to the end of the source which + /// encompasses the compilation error. + int get length => problemMessage.length; + + /// The message to be displayed for this diagnostic. + /// + /// The message indicates what is wrong and why it is wrong. + String get message => problemMessage.messageText(includeUrl: true); + + /// The character offset from the beginning of the source (zero based) where + /// the diagnostic occurred. + int get offset => problemMessage.offset; + + Severity get severity { + switch (diagnosticCode.severity) { + case DiagnosticSeverity.ERROR: + return Severity.error; + case DiagnosticSeverity.WARNING: + return Severity.warning; + case DiagnosticSeverity.INFO: + return Severity.info; + default: + throw StateError('Invalid severity: ${diagnosticCode.severity}'); + } + } + + @override + bool operator ==(Object other) { + if (identical(other, this)) { + return true; + } + // prepare the other Diagnostic. + if (other is Diagnostic) { + // Quick checks. + if (!identical(diagnosticCode, other.diagnosticCode)) { + return false; + } + if (offset != other.offset || length != other.length) { + return false; + } + // Deep checks. + if (message != other.message) { + return false; + } + if (source != other.source) { + return false; + } + return true; + } + return false; + } + + @override + String toString() { + StringBuffer buffer = StringBuffer(); + buffer.write(source.fullName); + buffer.write("("); + buffer.write(offset); + buffer.write(".."); + buffer.write(offset + length - 1); + buffer.write("): "); + buffer.write(message); + return buffer.toString(); + } +} + +/// An indication of the severity of a [Diagnostic]. +enum Severity { error, warning, info } diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart index 9433fb0e442..6fb2866a2af 100644 --- a/pkg/analyzer/lib/error/error.dart +++ b/pkg/analyzer/lib/error/error.dart @@ -8,6 +8,7 @@ library; import 'dart:collection'; import 'package:_fe_analyzer_shared/src/base/errors.dart'; +import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/src/diagnostic/diagnostic_code_values.dart'; export 'package:_fe_analyzer_shared/src/base/errors.dart' diff --git a/pkg/analyzer/lib/error/listener.dart b/pkg/analyzer/lib/error/listener.dart index 64737186ff5..586f3a86d6d 100644 --- a/pkg/analyzer/lib/error/listener.dart +++ b/pkg/analyzer/lib/error/listener.dart @@ -2,7 +2,6 @@ // 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/base/errors.dart'; import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/src/error/listener.dart'; diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart index 59c337f971e..75de5a6c0e0 100644 --- a/pkg/analyzer/lib/src/dart/analysis/driver.dart +++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart @@ -39,7 +39,8 @@ import 'package:analyzer/src/dart/ast/ast.dart'; import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart'; import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart'; -import 'package:analyzer/src/diagnostic/diagnostic_message.dart'; +import 'package:analyzer/src/diagnostic/diagnostic.dart' + show DiagnosticMessageImpl; import 'package:analyzer/src/exception/exception.dart'; import 'package:analyzer/src/fine/manifest_id.dart'; import 'package:analyzer/src/fine/requirements.dart'; diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart index 9106ac3a9c3..6f551e15340 100644 --- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart +++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart @@ -28,8 +28,9 @@ import 'package:analyzer/src/dart/element/type_algebra.dart'; import 'package:analyzer/src/dart/element/type_provider.dart'; import 'package:analyzer/src/dart/element/type_system.dart' show TypeSystemImpl; import 'package:analyzer/src/dart/type_instantiation_target.dart'; +import 'package:analyzer/src/diagnostic/diagnostic.dart' + show DiagnosticMessageImpl; import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; -import 'package:analyzer/src/diagnostic/diagnostic_message.dart'; import 'package:analyzer/src/error/listener.dart'; import 'package:analyzer/src/generated/engine.dart'; import 'package:analyzer/src/generated/java_core.dart'; diff --git a/pkg/analyzer/lib/src/dart/element/extensions.dart b/pkg/analyzer/lib/src/dart/element/extensions.dart index c0203fbd468..7a13a1e65a3 100644 --- a/pkg/analyzer/lib/src/dart/element/extensions.dart +++ b/pkg/analyzer/lib/src/dart/element/extensions.dart @@ -10,7 +10,8 @@ import 'package:analyzer/source/source.dart'; import 'package:analyzer/source/source_range.dart'; import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/dart/element/type.dart'; -import 'package:analyzer/src/diagnostic/diagnostic_message.dart'; +import 'package:analyzer/src/diagnostic/diagnostic.dart' + show DiagnosticMessageImpl; import 'package:analyzer/src/generated/utilities_dart.dart'; import 'package:meta/meta_meta.dart'; diff --git a/pkg/analyzer/lib/src/dart/error/lint_codes.dart b/pkg/analyzer/lib/src/dart/error/lint_codes.dart index 370f3fe3f9b..4e6cc0f7048 100644 --- a/pkg/analyzer/lib/src/dart/error/lint_codes.dart +++ b/pkg/analyzer/lib/src/dart/error/lint_codes.dart @@ -8,8 +8,9 @@ library; import 'package:_fe_analyzer_shared/src/base/analyzer_public_api.dart'; import 'package:_fe_analyzer_shared/src/base/errors.dart'; +import 'package:analyzer/src/diagnostic/diagnostic.dart'; -export 'package:_fe_analyzer_shared/src/base/errors.dart' +export 'package:analyzer/src/diagnostic/diagnostic.dart' show DiagnosticWithArguments, DiagnosticWithoutArguments, diff --git a/pkg/analyzer/lib/src/dart/error/todo_codes.dart b/pkg/analyzer/lib/src/dart/error/todo_codes.dart index 9e2cf4b84bb..bae0ac541b0 100644 --- a/pkg/analyzer/lib/src/dart/error/todo_codes.dart +++ b/pkg/analyzer/lib/src/dart/error/todo_codes.dart @@ -6,8 +6,8 @@ import 'package:_fe_analyzer_shared/src/base/errors.dart'; import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; typedef TodoDiagnosticCode = - DiagnosticWithArguments< - LocatableDiagnostic Function({required String message}) + diag.DiagnosticWithArguments< + diag.LocatableDiagnostic Function({required String message}) >; /// Static helper methods and properties for working with [DiagnosticType.TODO] diff --git a/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart index 4165e470d41..ee15fd27bd0 100644 --- a/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart +++ b/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart @@ -14,13 +14,13 @@ import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/dart/element/type.dart'; import 'package:analyzer/src/dart/element/type_constraint_gatherer.dart'; import 'package:analyzer/src/dart/element/type_system.dart'; -import 'package:analyzer/src/dart/error/lint_codes.dart'; import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart'; import 'package:analyzer/src/dart/resolver/scope_context.dart'; import 'package:analyzer/src/dart/type_instantiation_target.dart'; +import 'package:analyzer/src/diagnostic/diagnostic.dart' + show DiagnosticMessageImpl, LocatableDiagnostic; import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; import 'package:analyzer/src/diagnostic/diagnostic_factory.dart'; -import 'package:analyzer/src/diagnostic/diagnostic_message.dart'; import 'package:analyzer/src/error/listener.dart'; import 'package:analyzer/src/generated/scope_helpers.dart'; diff --git a/pkg/analyzer/lib/src/dart/scanner/scanner.dart b/pkg/analyzer/lib/src/dart/scanner/scanner.dart index ecfa1a8bc3b..ec0c64d0849 100644 --- a/pkg/analyzer/lib/src/dart/scanner/scanner.dart +++ b/pkg/analyzer/lib/src/dart/scanner/scanner.dart @@ -4,7 +4,6 @@ import 'dart:typed_data'; -import 'package:_fe_analyzer_shared/src/base/errors.dart'; import 'package:_fe_analyzer_shared/src/parser/experimental_features.dart'; import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' as fasta; import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token; @@ -34,7 +33,7 @@ class Scanner { final String _inputText; /// The callback to report diagnostics. - final void Function(LocatedDiagnostic) reportError; + final void Function(diag.LocatedDiagnostic) reportError; /// If the file has [fasta.LanguageVersionToken], it is allowed to use the /// language version greater than the one specified in the package config. diff --git a/pkg/analyzer/lib/src/dart/scanner/translate_error_token.dart b/pkg/analyzer/lib/src/dart/scanner/translate_error_token.dart index c05056a5c4b..2f59bd044f8 100644 --- a/pkg/analyzer/lib/src/dart/scanner/translate_error_token.dart +++ b/pkg/analyzer/lib/src/dart/scanner/translate_error_token.dart @@ -2,7 +2,6 @@ // 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/base/errors.dart'; import 'package:_fe_analyzer_shared/src/messages/codes.dart'; import 'package:_fe_analyzer_shared/src/messages/diagnostic.dart' as fe_diag; import 'package:_fe_analyzer_shared/src/messages/diagnostic.dart'; @@ -18,7 +17,7 @@ void translateErrorToken(ErrorToken token, ReportError reportError) { int charOffset = token.charOffset; // TODO(paulberry): why is endOffset sometimes null? int endOffset = token.endOffset ?? charOffset; - void makeError(LocatableDiagnostic locatableDiagnostic) { + void makeError(diag.LocatableDiagnostic locatableDiagnostic) { if (_isAtEnd(token, charOffset)) { // Analyzer never generates an error message past the end of the input, // since such an error would not be visible in an editor. @@ -129,4 +128,4 @@ bool _isAtEnd(Token token, int charOffset) { /// Used to report a scan error. /// The [locatedDiagnostic] contains the error code, arguments, and the location /// of the error. -typedef ReportError = void Function(LocatedDiagnostic locatedDiagnostic); +typedef ReportError = void Function(diag.LocatedDiagnostic locatedDiagnostic); diff --git a/pkg/analyzer/lib/src/dart/type_instantiation_target.dart b/pkg/analyzer/lib/src/dart/type_instantiation_target.dart index 423fc791f5a..caa43126e63 100644 --- a/pkg/analyzer/lib/src/dart/type_instantiation_target.dart +++ b/pkg/analyzer/lib/src/dart/type_instantiation_target.dart @@ -6,7 +6,6 @@ // currently contains some classes called `TypeInstantiationTarget...` and some // called `InvocationTarget...`. -import 'package:_fe_analyzer_shared/src/base/errors.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/src/dart/element/element.dart'; @@ -30,7 +29,7 @@ class InvocationTargetConstructorElement InvocationTargetConstructorElement(super.element, this.rawType); @override - LocatableDiagnostic wrongNumberOfTypeArgumentsError({ + diag.LocatableDiagnostic wrongNumberOfTypeArgumentsError({ required int typeParameterCount, required int typeArgumentCount, }) { @@ -68,7 +67,7 @@ class InvocationTargetExecutableElement extends TypeInstantiationTargetElement element.type as FunctionTypeImpl; @override - LocatableDiagnostic wrongNumberOfTypeArgumentsError({ + diag.LocatableDiagnostic wrongNumberOfTypeArgumentsError({ required int typeParameterCount, required int typeArgumentCount, }) { @@ -102,7 +101,7 @@ class InvocationTargetExtensionOverride extends InvocationTarget { FunctionTypeImpl get rawType => type; @override - LocatableDiagnostic wrongNumberOfTypeArgumentsError({ + diag.LocatableDiagnostic wrongNumberOfTypeArgumentsError({ required int typeParameterCount, required int typeArgumentCount, }) { @@ -132,7 +131,7 @@ class InvocationTargetFunctionTypedExpression extends InvocationTarget { FunctionTypeImpl get rawType => type; @override - LocatableDiagnostic wrongNumberOfTypeArgumentsError({ + diag.LocatableDiagnostic wrongNumberOfTypeArgumentsError({ required int typeParameterCount, required int typeArgumentCount, }) { @@ -160,7 +159,7 @@ sealed class TypeInstantiationTarget { /// Creates the appropriate diagnostic message when the wrong number of type /// arguments is applied. - LocatableDiagnostic wrongNumberOfTypeArgumentsError({ + diag.LocatableDiagnostic wrongNumberOfTypeArgumentsError({ required int typeParameterCount, required int typeArgumentCount, }); @@ -215,7 +214,7 @@ sealed class TypeInstantiationTargetTypeDefiningElement const TypeInstantiationTargetTypeDefiningElement(); @override - LocatableDiagnostic wrongNumberOfTypeArgumentsError({ + diag.LocatableDiagnostic wrongNumberOfTypeArgumentsError({ required int typeParameterCount, required int typeArgumentCount, }) { diff --git a/pkg/analyzer/lib/src/diagnostic/diagnostic.dart b/pkg/analyzer/lib/src/diagnostic/diagnostic.dart index 92c64753094..45ce4ddcbe4 100644 --- a/pkg/analyzer/lib/src/diagnostic/diagnostic.dart +++ b/pkg/analyzer/lib/src/diagnostic/diagnostic.dart @@ -2,12 +2,320 @@ // 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. -/// @docImport 'package:analyzer/src/error/inference_error.dart'; +/// @docImport 'package:analyzer/diagnostic/diagnostic.dart'; +/// @docImport 'package:analyzer/error/listener.dart'; library; +import 'package:_fe_analyzer_shared/src/base/analyzer_public_api.dart'; import 'package:_fe_analyzer_shared/src/base/errors.dart'; +import 'package:analyzer/dart/ast/syntactic_entity.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; +import 'package:analyzer/source/source_range.dart'; import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; +import 'package:source_span/source_span.dart'; part 'package:analyzer/src/diagnostic/diagnostic.g.dart'; + +/// Private subtype of [DiagnosticCode] that supports runtime checking of +/// parameter types. +class DiagnosticCodeWithExpectedTypes extends DiagnosticCodeImpl { + final List? expectedTypes; + + const DiagnosticCodeWithExpectedTypes({ + super.correctionMessage, + super.hasPublishedDocs = false, + super.isUnresolvedIdentifier = false, + required super.name, + required super.problemMessage, + required super.type, + required super.uniqueName, + this.expectedTypes, + }); +} + +/// A single message associated with a [Diagnostic], consisting of the text of +/// the message and the location associated with it. +/// +/// Clients may not extend, implement or mix-in this class. +@AnalyzerPublicApi( + message: 'Exported by package:analyzer/diagnostic/diagnostic.dart', +) +abstract class DiagnosticMessage { + /// The absolute and normalized path of the file associated with this message. + String get filePath; + + /// The length of the source range associated with this message. + int get length; + + /// The zero-based offset from the start of the file to the beginning of the + /// source range associated with this message. + int get offset; + + /// The URL containing documentation about this diagnostic message, if any. + /// + /// Note: this should not be confused with the location in the user's code + /// where the error was reported; that information can be obtained from + /// [filePath], [length], and [offset]. + String? get url; + + /// Gets the text of the message. + /// + /// If [includeUrl] is `true`, and this diagnostic message has an associated + /// URL, it is included in the returned value in a human-readable way. + /// Clients that wish to present URLs as simple text can do this. If + /// [includeUrl] is `false`, no URL is included in the returned value. + /// Clients that have a special mechanism for presenting URLs (e.g. as a + /// clickable link) should do this and then consult the [url] getter to access + /// the URL. + String messageText({required bool includeUrl}); +} + +/// A concrete implementation of a diagnostic message. +class DiagnosticMessageImpl implements DiagnosticMessage { + @override + final String filePath; + + @override + final int length; + + final String _message; + + @override + final int offset; + + @override + final String? url; + + /// Initialize a newly created message to represent a [message] reported in + /// the file at the given [filePath] at the given [offset] and with the given + /// [length]. + DiagnosticMessageImpl({ + required this.filePath, + required this.length, + required String message, + required this.offset, + required this.url, + }) : _message = message; + + @override + String messageText({required bool includeUrl}) { + if (includeUrl && url != null) { + var result = StringBuffer(_message); + if (!_message.endsWith('.')) { + result.write('.'); + } + result.write(' See $url'); + return result.toString(); + } + return _message; + } +} + +/// Common functionality for [DiagnosticCode]-derived classes that represent +/// errors that take arguments. +/// +/// This class provides a [withArguments] getter, which can be used to supply +/// arguments and produce a [LocatableDiagnostic]. +/// +/// Note: the type argument `T` should be instantiated with a function type. But +/// it is typed as `extends Object` in order to reduce the risk of accidental +/// dynamic invocation of [withArguments]. +class DiagnosticWithArguments + extends DiagnosticCodeWithExpectedTypes { + /// Function accepting named arguments and returning [LocatableDiagnostic]. + /// + /// The value returned by this function can + /// be associated with a location in the source code using the + /// [LocatableDiagnostic.at] method, and then the result can be passed to + /// [DiagnosticReporter.reportError]. + final T withArguments; + + const DiagnosticWithArguments({ + required super.name, + required super.problemMessage, + super.correctionMessage, + super.hasPublishedDocs = false, + super.isUnresolvedIdentifier = false, + required super.type, + required super.uniqueName, + required super.expectedTypes, + required this.withArguments, + }); +} + +/// Common functionality for [DiagnosticCode]-derived classes that represent +/// errors that do not take arguments. +/// +/// This class implements [LocatableDiagnostic], which means that instances can +/// be associated with a location in the source code using the [at] method, and +/// then the result can be passed to [DiagnosticReporter.reportError]. +base mixin DiagnosticWithoutArguments on DiagnosticCodeImpl + implements LocatableDiagnostic { + @override + List get arguments => const []; + + @override + DiagnosticCode get code => this; + + @override + Iterable get contextMessages => const []; + + @override + LocatedDiagnostic at(SyntacticEntity node) => + atOffset(offset: node.offset, length: node.length); + + @override + LocatedDiagnostic atOffset({required int offset, required int length}) => + LocatedDiagnostic(this, offset, length); + + @override + LocatedDiagnostic atSourceRange(SourceRange sourceRange) => + atOffset(offset: sourceRange.offset, length: sourceRange.length); + + @override + LocatedDiagnostic atSourceSpan(SourceSpan span) => + atOffset(offset: span.start.offset, length: span.length); + + @override + LocatableDiagnostic withContextMessages( + Iterable messages, + ) => LocatableDiagnosticImpl(code, arguments, contextMessages: [...messages]); +} + +/// Concrete implementation of [DiagnosticWithoutArguments], used for diagnostic +/// messages that don't take any arguments. +/// +/// This needs to be a separate class from [DiagnosticWithoutArguments] because +/// [DiagnosticWithoutArguments] is a mixin. +final class DiagnosticWithoutArgumentsImpl + extends DiagnosticCodeWithExpectedTypes + with DiagnosticWithoutArguments { + const DiagnosticWithoutArgumentsImpl({ + required super.name, + required super.problemMessage, + super.correctionMessage, + super.hasPublishedDocs = false, + super.isUnresolvedIdentifier = false, + required super.type, + required super.uniqueName, + super.expectedTypes, + }); +} + +/// Expected type of a diagnostic code's parameter. +enum ExpectedType { element, int, name, object, string, token, type, uri } + +/// Interface for a diagnostic that does not have any unfilled template +/// parameters, and hence is ready to be associated with a location in the +/// source code. +/// +/// This could either be the result of calling `withArguments` on a diagnostic +/// code that requires arguments, or it could be a diagnostic code that doesn't +/// require arguments. +abstract final class LocatableDiagnostic { + /// The arguments that were applied to the diagnostic, or the empty list if + /// [code] doesn't accept any arguments. + List get arguments; + + /// The [DiagnosticCode] associated with the diagnostic. + DiagnosticCode get code; + + /// The context messages that were applied to the diagnostic. + Iterable get contextMessages; + + /// Converts this diagnostic to a [LocatedDiagnostic] by applying it to a + /// syntactic entity in the source code. + /// + /// The result may be passed to [DiagnosticReporter.reportError]. + LocatedDiagnostic at(SyntacticEntity node); + + /// Converts this diagnostic to a [LocatedDiagnostic] by applying it to a + /// location in the source code. + /// + /// The result may be passed to [DiagnosticReporter.reportError]. + LocatedDiagnostic atOffset({required int offset, required int length}); + + /// Converts this diagnostic to a [LocatedDiagnostic] by applying it to a + /// location in the source code. + /// + /// The result may be passed to [DiagnosticReporter.reportError]. + LocatedDiagnostic atSourceRange(SourceRange sourceRange); + + /// Converts this diagnostic to a [LocatedDiagnostic] by applying it to a + /// location in the source code. + /// + /// The result may be passed to [DiagnosticReporter.reportError]. + LocatedDiagnostic atSourceSpan(SourceSpan span); + + /// Attaches context messages to this diagnostic. + /// + /// The return value is a fresh instance of [LocatableDiagnostic]. This allows + /// for a literate style of error reporting, e.g.: + /// ```dart + /// // For an diagnostic code that doesn't take arguments: + /// diagnosticReporter.reportError( + /// diagnosticCode.withContextMessages(messages).at(astNode)); + /// + /// // For a diagnostic code that does take arguments: + /// diagnosticReporter.reportError( + /// diagnosticCode + /// .withArguments(...) + /// .withContextMessages(messages) + /// .at(astNode)); + /// ``` + LocatableDiagnostic withContextMessages(Iterable messages); +} + +/// Concrete implementation of [LocatableDiagnostic]. +final class LocatableDiagnosticImpl implements LocatableDiagnostic { + @override + final DiagnosticCode code; + + @override + final List arguments; + + @override + final Iterable contextMessages; + + LocatableDiagnosticImpl( + this.code, + this.arguments, { + this.contextMessages = const [], + }); + + @override + LocatedDiagnostic at(SyntacticEntity node) => + atOffset(offset: node.offset, length: node.length); + + @override + LocatedDiagnostic atOffset({required int offset, required int length}) => + LocatedDiagnostic(this, offset, length); + + @override + LocatedDiagnostic atSourceRange(SourceRange sourceRange) => + atOffset(offset: sourceRange.offset, length: sourceRange.length); + + @override + LocatedDiagnostic atSourceSpan(SourceSpan span) => + atOffset(offset: span.start.offset, length: span.length); + + @override + LocatableDiagnostic withContextMessages( + Iterable messages, + ) => LocatableDiagnosticImpl( + code, + arguments, + contextMessages: [...contextMessages, ...messages], + ); +} + +/// A diagnostic that does not have any unfilled template parameters, and has +/// been associated with a location in the source code. +final class LocatedDiagnostic { + final LocatableDiagnostic locatableDiagnostic; + final int offset; + final int length; + + LocatedDiagnostic(this.locatableDiagnostic, this.offset, this.length); +} diff --git a/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart b/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart index 2402c06fada..92b53045109 100644 --- a/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart +++ b/pkg/analyzer/lib/src/diagnostic/diagnostic_factory.dart @@ -2,7 +2,6 @@ // 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/base/errors.dart'; import 'package:analyzer/dart/ast/syntactic_entity.dart'; import 'package:analyzer/dart/ast/token.dart'; import 'package:analyzer/dart/element/element.dart'; @@ -10,14 +9,15 @@ import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/source/source.dart'; import 'package:analyzer/src/dart/ast/ast.dart'; import 'package:analyzer/src/dart/element/element.dart'; +import 'package:analyzer/src/diagnostic/diagnostic.dart' + show DiagnosticMessageImpl; import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; -import 'package:analyzer/src/diagnostic/diagnostic_message.dart'; import 'package:analyzer/src/utilities/extensions/string.dart'; import 'package:yaml/yaml.dart'; typedef InvalidOverrideDiagnosticCode = - DiagnosticWithArguments< - LocatableDiagnostic Function({ + diag.DiagnosticWithArguments< + diag.LocatableDiagnostic Function({ required String memberName, required String declaringInterfaceName, required DartType typeInDeclaringInterface, @@ -33,7 +33,7 @@ class DiagnosticFactory { /// Return a diagnostic indicating that [duplicate] uses the same [variable] /// as a previous [original] node in a pattern assignment. - LocatedDiagnostic duplicateAssignmentPatternVariable({ + diag.LocatedDiagnostic duplicateAssignmentPatternVariable({ required Source source, required PromotableElementImpl variable, required AssignedVariablePatternImpl original, @@ -55,8 +55,8 @@ class DiagnosticFactory { /// Return a diagnostic indicating that [duplicateFragment] reuses a name /// already used by [originalElement]. - LocatedDiagnostic duplicateDefinition( - LocatableDiagnostic locatableDiagnostic, + diag.LocatedDiagnostic duplicateDefinition( + diag.LocatableDiagnostic locatableDiagnostic, FragmentImpl duplicateFragment, ElementImpl originalElement, ) { @@ -81,9 +81,9 @@ class DiagnosticFactory { /// Return a diagnostic indicating that [duplicateNode] reuses a name /// already used by [originalNode]. - LocatedDiagnostic duplicateDefinitionForNodes( + diag.LocatedDiagnostic duplicateDefinitionForNodes( Source source, - LocatableDiagnostic locatableDiagnostic, + diag.LocatableDiagnostic locatableDiagnostic, SyntacticEntity duplicateNode, SyntacticEntity originalNode, ) { @@ -102,7 +102,7 @@ class DiagnosticFactory { /// Return a diagnostic indicating that [duplicateField] reuses a name /// already used by [originalField]. - LocatedDiagnostic duplicateFieldDefinitionInLiteral( + diag.LocatedDiagnostic duplicateFieldDefinitionInLiteral( Source source, RecordLiteralNamedField duplicateField, RecordLiteralNamedField originalField, @@ -128,7 +128,7 @@ class DiagnosticFactory { /// /// This method requires that both the [duplicateField] and [originalField] /// have a non-null `name`. - LocatedDiagnostic duplicateFieldDefinitionInType( + diag.LocatedDiagnostic duplicateFieldDefinitionInType( Source source, RecordTypeAnnotationField duplicateField, RecordTypeAnnotationField originalField, @@ -151,7 +151,7 @@ class DiagnosticFactory { /// Return a diagnostic indicating that [duplicateField] reuses a name /// already used by [originalField]. - LocatedDiagnostic duplicatePatternField({ + diag.LocatedDiagnostic duplicatePatternField({ required Source source, required String name, required PatternField duplicateField, @@ -177,7 +177,7 @@ class DiagnosticFactory { /// Return a diagnostic indicating that [duplicateElement] reuses a name /// already used by [originalElement]. - LocatedDiagnostic duplicateRestElementInPattern({ + diag.LocatedDiagnostic duplicateRestElementInPattern({ required Source source, required RestPatternElement originalElement, required RestPatternElement duplicateElement, @@ -197,7 +197,7 @@ class DiagnosticFactory { /// Return a diagnostic indicating that the [duplicateElement] (in a constant /// set) is a duplicate of the [originalElement]. - LocatedDiagnostic equalElementsInConstSet( + diag.LocatedDiagnostic equalElementsInConstSet( Source source, Expression duplicateElement, Expression originalElement, @@ -217,7 +217,7 @@ class DiagnosticFactory { /// Return a diagnostic indicating that the [duplicateKey] (in a constant map) /// is a duplicate of the [originalKey]. - LocatedDiagnostic equalKeysInConstMap( + diag.LocatedDiagnostic equalKeysInConstMap( Source source, Expression duplicateKey, Expression originalKey, @@ -237,7 +237,7 @@ class DiagnosticFactory { /// Return a diagnostic indicating that the [duplicateKey] (in a map pattern) /// is a duplicate of the [originalKey]. - LocatedDiagnostic equalKeysInMapPattern( + diag.LocatedDiagnostic equalKeysInMapPattern( Source source, Expression duplicateKey, Expression originalKey, @@ -255,7 +255,7 @@ class DiagnosticFactory { .at(duplicateKey); } - LocatedDiagnostic incompatibleLint({ + diag.LocatedDiagnostic incompatibleLint({ required Source source, required YamlScalar reference, required Map incompatibleRules, @@ -286,7 +286,7 @@ class DiagnosticFactory { /// Returns a diagnostic indicating that incompatible rules were found between /// the current list and one or more of the included files. - LocatedDiagnostic incompatibleLintFiles({ + diag.LocatedDiagnostic incompatibleLintFiles({ required Source source, required YamlScalar reference, required Map incompatibleRules, @@ -318,7 +318,7 @@ class DiagnosticFactory { /// Returns a diagnostic indicating that incompatible rules were found between /// the included files. - LocatedDiagnostic incompatibleLintIncluded({ + diag.LocatedDiagnostic incompatibleLintIncluded({ required Source source, required YamlScalar reference, required Map incompatibleRules, @@ -353,7 +353,7 @@ class DiagnosticFactory { /// Return a diagnostic indicating that [member] is not a correct override of /// [superMember]. - LocatedDiagnostic invalidOverride( + diag.LocatedDiagnostic invalidOverride( Source source, InvalidOverrideDiagnosticCode code, SyntacticEntity errorNode, @@ -403,7 +403,7 @@ class DiagnosticFactory { /// Return a diagnostic indicating that the given [nameToken] was referenced /// before it was declared. - LocatedDiagnostic referencedBeforeDeclaration( + diag.LocatedDiagnostic referencedBeforeDeclaration( Source source, { required Token nameToken, required Element element2, diff --git a/pkg/analyzer/lib/src/diagnostic/diagnostic_message.dart b/pkg/analyzer/lib/src/diagnostic/diagnostic_message.dart deleted file mode 100644 index d7957cccb87..00000000000 --- a/pkg/analyzer/lib/src/diagnostic/diagnostic_message.dart +++ /dev/null @@ -1,6 +0,0 @@ -// 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. - -export 'package:_fe_analyzer_shared/src/base/diagnostic_message.dart' - show DiagnosticMessageImpl; diff --git a/pkg/analyzer/lib/src/error/base_or_final_type_verifier.dart b/pkg/analyzer/lib/src/error/base_or_final_type_verifier.dart index 22475eda64c..95cbae4c78f 100644 --- a/pkg/analyzer/lib/src/error/base_or_final_type_verifier.dart +++ b/pkg/analyzer/lib/src/error/base_or_final_type_verifier.dart @@ -6,12 +6,12 @@ import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; -import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/source/source.dart'; import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/dart/element/extensions.dart'; +import 'package:analyzer/src/diagnostic/diagnostic.dart' + show DiagnosticMessage, DiagnosticMessageImpl; import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; -import 'package:analyzer/src/diagnostic/diagnostic_message.dart'; import 'package:analyzer/src/error/listener.dart'; /// Helper for verifying that subelements of a base or final element must be diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart index 5d85c483a58..b9b85f3a03a 100644 --- a/pkg/analyzer/lib/src/error/codes.dart +++ b/pkg/analyzer/lib/src/error/codes.dart @@ -2,7 +2,5 @@ // 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. -export 'package:_fe_analyzer_shared/src/base/errors.dart' - show LocatableDiagnosticImpl; export 'package:analyzer/src/dart/error/lint_codes.dart'; export 'package:analyzer/src/dart/error/todo_codes.dart'; diff --git a/pkg/analyzer/lib/src/error/listener.dart b/pkg/analyzer/lib/src/error/listener.dart index 890de75dbeb..95ed077eff5 100644 --- a/pkg/analyzer/lib/src/error/listener.dart +++ b/pkg/analyzer/lib/src/error/listener.dart @@ -17,7 +17,13 @@ import 'package:analyzer/src/dart/ast/extensions.dart'; import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/dart/element/extensions.dart'; import 'package:analyzer/src/dart/element/type.dart'; -import 'package:analyzer/src/diagnostic/diagnostic_message.dart'; +import 'package:analyzer/src/diagnostic/diagnostic.dart' + show + DiagnosticCodeWithExpectedTypes, + DiagnosticMessage, + DiagnosticMessageImpl, + ExpectedType, + LocatedDiagnostic; import 'package:analyzer/src/utilities/extensions/collection.dart'; import 'package:meta/meta.dart'; import 'package:source_span/source_span.dart'; diff --git a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart index 887c30f9645..7f2a409176c 100644 --- a/pkg/analyzer/lib/src/error/type_arguments_verifier.dart +++ b/pkg/analyzer/lib/src/error/type_arguments_verifier.dart @@ -8,15 +8,15 @@ import 'package:analyzer/dart/analysis/analysis_options.dart'; import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; -import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/src/dart/ast/ast.dart'; import 'package:analyzer/src/dart/ast/extensions.dart'; import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/dart/element/type.dart'; import 'package:analyzer/src/dart/element/type_algebra.dart'; import 'package:analyzer/src/dart/element/type_system.dart'; +import 'package:analyzer/src/diagnostic/diagnostic.dart' + show DiagnosticMessage, DiagnosticMessageImpl; import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; -import 'package:analyzer/src/diagnostic/diagnostic_message.dart'; import 'package:analyzer/src/error/codes.dart'; import 'package:analyzer/src/error/listener.dart'; diff --git a/pkg/analyzer/lib/src/fasta/error_converter.dart b/pkg/analyzer/lib/src/fasta/error_converter.dart index f73ea6e3e4d..f4b3b20d8cb 100644 --- a/pkg/analyzer/lib/src/fasta/error_converter.dart +++ b/pkg/analyzer/lib/src/fasta/error_converter.dart @@ -6,6 +6,7 @@ import 'package:_fe_analyzer_shared/src/base/errors.dart'; import 'package:_fe_analyzer_shared/src/messages/codes.dart' show Code, Message; import 'package:_fe_analyzer_shared/src/messages/diagnostic.dart'; import 'package:analyzer/dart/ast/token.dart' show Token; +import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; import 'package:analyzer/src/diagnostic/diagnostic_code_values.dart'; import 'package:analyzer/src/error/listener.dart'; @@ -378,7 +379,7 @@ class FastaErrorReporter { reportByCode(code.pseudoSharedCode, offset, length, message); } - void reportScannerError(LocatedDiagnostic locatedDiagnostic) { + void reportScannerError(diag.LocatedDiagnostic locatedDiagnostic) { diagnosticReporter?.report(locatedDiagnostic); } diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart index 3a0badc8d20..6c875061200 100644 --- a/pkg/analyzer/lib/src/generated/error_verifier.dart +++ b/pkg/analyzer/lib/src/generated/error_verifier.dart @@ -15,7 +15,6 @@ import 'package:analyzer/dart/ast/token.dart'; import 'package:analyzer/dart/ast/visitor.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; -import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/source/source_range.dart'; import 'package:analyzer/src/dart/analysis/analysis_options.dart'; import 'package:analyzer/src/dart/analysis/file_state.dart'; @@ -32,9 +31,10 @@ import 'package:analyzer/src/dart/element/type_system.dart'; import 'package:analyzer/src/dart/element/well_bounded.dart'; import 'package:analyzer/src/dart/resolver/flow_analysis_visitor.dart'; import 'package:analyzer/src/dart/resolver/scope.dart'; +import 'package:analyzer/src/diagnostic/diagnostic.dart' + show DiagnosticMessage, DiagnosticMessageImpl; import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; import 'package:analyzer/src/diagnostic/diagnostic_factory.dart'; -import 'package:analyzer/src/diagnostic/diagnostic_message.dart'; import 'package:analyzer/src/error/codes.dart'; import 'package:analyzer/src/error/const_argument_verifier.dart'; import 'package:analyzer/src/error/constructor_fields_verifier.dart'; diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart index c331922079e..b741b531d08 100644 --- a/pkg/analyzer/lib/src/generated/resolver.dart +++ b/pkg/analyzer/lib/src/generated/resolver.dart @@ -24,7 +24,6 @@ import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/scope.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/dart/element/type_provider.dart'; -import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/error/listener.dart'; import 'package:analyzer/source/source.dart'; import 'package:analyzer/src/dart/ast/ast.dart'; @@ -67,8 +66,9 @@ import 'package:analyzer/src/dart/resolver/typed_literal_resolver.dart'; import 'package:analyzer/src/dart/resolver/variable_declaration_resolver.dart'; import 'package:analyzer/src/dart/resolver/yield_statement_resolver.dart'; import 'package:analyzer/src/dart/type_instantiation_target.dart'; +import 'package:analyzer/src/diagnostic/diagnostic.dart' + show DiagnosticMessage, DiagnosticMessageImpl; import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; -import 'package:analyzer/src/diagnostic/diagnostic_message.dart'; import 'package:analyzer/src/error/base_or_final_type_verifier.dart'; import 'package:analyzer/src/error/bool_expression_verifier.dart'; import 'package:analyzer/src/error/codes.dart'; diff --git a/pkg/analyzer/lib/src/utilities/extensions/element.dart b/pkg/analyzer/lib/src/utilities/extensions/element.dart index ef5b0c76125..abadc809e28 100644 --- a/pkg/analyzer/lib/src/utilities/extensions/element.dart +++ b/pkg/analyzer/lib/src/utilities/extensions/element.dart @@ -8,7 +8,8 @@ import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/src/dart/element/element.dart'; import 'package:analyzer/src/dart/element/member.dart'; import 'package:analyzer/src/dart/element/type.dart'; -import 'package:analyzer/src/diagnostic/diagnostic_message.dart'; +import 'package:analyzer/src/diagnostic/diagnostic.dart' + show DiagnosticMessageImpl; import 'package:meta/meta.dart'; class MockLibraryImportElement implements Element { diff --git a/pkg/analyzer_plugin/api.txt b/pkg/analyzer_plugin/api.txt index 676d69db401..49b7c3ba1df 100644 --- a/pkg/analyzer_plugin/api.txt +++ b/pkg/analyzer_plugin/api.txt @@ -2103,10 +2103,7 @@ dart:core: int (referenced) dart:isolate: SendPort (referenced) -package:_fe_analyzer_shared/src/base/diagnostic_message.dart: - DiagnosticMessage@2 (referenced) package:_fe_analyzer_shared/src/base/errors.dart: - Diagnostic (referenced) DiagnosticSeverity (referenced) DiagnosticType (referenced) package:_fe_analyzer_shared/src/base/source_range.dart: @@ -2143,6 +2140,8 @@ package:analyzer/dart/element/type_provider.dart: TypeProvider (referenced) package:analyzer/dart/element/type_system.dart: TypeSystem (referenced) +package:analyzer/diagnostic/diagnostic.dart: + Diagnostic (referenced) package:analyzer/file_system/file_system.dart: Folder (referenced) ResourceProvider (referenced) @@ -2162,5 +2161,7 @@ package:analyzer/src/dart/ast/ast.dart: FunctionBody (referenced) NodeList (referenced) TypeAnnotation (referenced) +package:analyzer/src/diagnostic/diagnostic.dart: + DiagnosticMessage@2 (referenced) package:pub_semver/src/version.dart: Version (referenced) diff --git a/pkg/analyzer_plugin/test/utilities/analyzer_converter_test.dart b/pkg/analyzer_plugin/test/utilities/analyzer_converter_test.dart index 27944796503..087433df1c3 100644 --- a/pkg/analyzer_plugin/test/utilities/analyzer_converter_test.dart +++ b/pkg/analyzer_plugin/test/utilities/analyzer_converter_test.dart @@ -9,8 +9,9 @@ import 'package:analyzer/source/error_processor.dart' as analyzer; import 'package:analyzer/source/line_info.dart' as analyzer; import 'package:analyzer/src/dart/analysis/analysis_options.dart' as analyzer; import 'package:analyzer/src/dart/element/element.dart' as analyzer; +import 'package:analyzer/src/diagnostic/diagnostic.dart' + show DiagnosticMessageImpl; import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; -import 'package:analyzer/src/diagnostic/diagnostic_message.dart' as analyzer; import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin; import 'package:analyzer_plugin/utilities/analyzer_converter.dart'; import 'package:test/test.dart'; @@ -58,14 +59,14 @@ class AnalyzerConverterTest extends AbstractSingleUnitTest { int offset, { String? contextMessage, }) async { - var contextMessages = []; + var contextMessages = []; await resolveTestCode(''); var testSource = result.unit.declaredFragment!.source; if (contextMessage != null) { contextMessages.add( - analyzer.DiagnosticMessageImpl( + DiagnosticMessageImpl( filePath: testSource.fullName, offset: 53, length: 7, diff --git a/pkg/analyzer_testing/api.txt b/pkg/analyzer_testing/api.txt index 6e92e0064be..34d015feffc 100644 --- a/pkg/analyzer_testing/api.txt +++ b/pkg/analyzer_testing/api.txt @@ -97,8 +97,9 @@ dart:core: bool (referenced) int (referenced) package:_fe_analyzer_shared/src/base/errors.dart: - Diagnostic (referenced) DiagnosticCode (referenced) +package:analyzer/diagnostic/diagnostic.dart: + Diagnostic (referenced) package:analyzer/file_system/file_system.dart: File (referenced) Folder (referenced) diff --git a/pkg/front_end/test/scanner_cfe_test.dart b/pkg/front_end/test/scanner_cfe_test.dart index 1f1f0b9f131..c4b37d9689d 100644 --- a/pkg/front_end/test/scanner_cfe_test.dart +++ b/pkg/front_end/test/scanner_cfe_test.dart @@ -5,7 +5,6 @@ import 'dart:convert'; import 'dart:typed_data' show Uint8List; -import 'package:_fe_analyzer_shared/src/base/errors.dart'; import 'package:_fe_analyzer_shared/src/scanner/error_token.dart'; import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' as usedForFuzzTesting; @@ -13,6 +12,7 @@ import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'; import 'package:_fe_analyzer_shared/src/scanner/token.dart'; import 'package:_fe_analyzer_shared/src/scanner/token_constants.dart'; import 'package:analyzer/src/dart/scanner/translate_error_token.dart'; +import 'package:analyzer/src/diagnostic/diagnostic.dart' show LocatedDiagnostic; import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; import 'package:front_end/src/codes/diagnostic.dart' as fe_diag; import 'package:test/test.dart'; diff --git a/pkg/front_end/test/scanner_replacement_test.dart b/pkg/front_end/test/scanner_replacement_test.dart index 82999e3c4e2..7693a92b7c5 100644 --- a/pkg/front_end/test/scanner_replacement_test.dart +++ b/pkg/front_end/test/scanner_replacement_test.dart @@ -2,12 +2,12 @@ // 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/base/errors.dart'; import 'package:_fe_analyzer_shared/src/scanner/error_token.dart'; import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'; import 'package:_fe_analyzer_shared/src/scanner/token.dart'; import 'package:analyzer/src/dart/scanner/translate_error_token.dart' show translateErrorToken; +import 'package:analyzer/src/diagnostic/diagnostic.dart' show LocatedDiagnostic; import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; diff --git a/pkg/linter/lib/src/rules/prefer_final_locals.dart b/pkg/linter/lib/src/rules/prefer_final_locals.dart index be004bd3bb6..e56d83f7bb1 100644 --- a/pkg/linter/lib/src/rules/prefer_final_locals.dart +++ b/pkg/linter/lib/src/rules/prefer_final_locals.dart @@ -8,10 +8,10 @@ import 'package:analyzer/analysis_rule/rule_visitor_registry.dart'; import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/ast/visitor.dart'; import 'package:analyzer/dart/element/element.dart'; -import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/error/error.dart'; import 'package:analyzer/src/dart/element/extensions.dart'; // ignore: implementation_imports -import 'package:analyzer/src/diagnostic/diagnostic_message.dart'; // ignore: implementation_imports +import 'package:analyzer/src/diagnostic/diagnostic.dart' // ignore: implementation_imports + show DiagnosticMessage, DiagnosticMessageImpl; import '../analyzer.dart'; import '../diagnostic.dart' as diag;