// Copyright (c) 2021, 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:analyzer/dart/analysis/results.dart'; import 'package:analyzer/dart/analysis/utilities.dart'; import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/error/error.dart'; import 'package:analyzer/src/test_utilities/find_node.dart'; import 'package:analyzer_testing/src/analysis_rule/pub_package_resolution.dart'; import 'package:analyzer_utilities/testing/tree_string_sink.dart'; import 'package:test/test.dart'; import '../../generated/test_support.dart'; import '../../util/diff.dart'; import '../../util/element_printer.dart'; import '../../util/feature_sets.dart'; import '../dart/resolution/node_text_expectations.dart'; import '../summary/resolved_ast_printer.dart'; class ParserDiagnosticsTest { // TODO(scheglov): Enable [withCheckingLinking] everywhere. void assertParsedNodeText( AstNode node, String expected, { bool withOffsets = false, bool withTokenPreviousNext = false, }) { var actual = _parsedNodeText( node, withOffsets: withOffsets, withTokenPreviousNext: withTokenPreviousNext, ); if (actual != expected) { NodeTextExpectationsCollector.add(actual); printPrettyDiff(expected, actual); fail('See the difference above.'); } } ExpectedError error( DiagnosticCode code, int offset, int length, { Pattern? correctionContains, // TODO(FMorschel): refactor the uses of this to prefer `messageContains` String? text, List messageContains = const [], List contextMessages = const [], }) { assert( text == null || messageContains.isEmpty, 'Only use one of text or messageContains', ); return ExpectedError( code, offset, length, correctionContains: correctionContains, messageContainsAll: text != null ? [text] : messageContains, contextMessages: contextMessages, ); } ParseStringResult parseStringWithErrors(String content) { return parseString( content: content, featureSet: FeatureSets.latestWithExperiments, throwIfDiagnostics: false, ); } void setUp() { useDeclaringConstructorsAst = false; } void tearDown() { useDeclaringConstructorsAst = false; } String _parsedNodeText( AstNode node, { required bool withOffsets, required bool withTokenPreviousNext, }) { var buffer = StringBuffer(); var sink = TreeStringSink(sink: buffer, indent: ''); var elementPrinter = ElementPrinter( sink: sink, configuration: ElementPrinterConfiguration(), ); node.accept( ResolvedAstPrinter( sink: sink, elementPrinter: elementPrinter, configuration: ResolvedNodeTextConfiguration() ..withTokenPreviousNext = withTokenPreviousNext, withResolution: false, withOffsets: withOffsets, ), ); return buffer.toString(); } } extension ParseStringResultExtension on ParseStringResult { FindNode get findNode { return FindNode(content, unit); } void assertErrors(List expectedDiagnostics) { var diagnosticListener = GatheringDiagnosticListener(); diagnosticListener.addAll(errors); diagnosticListener.assertErrors(expectedDiagnostics); } void assertNoErrors() { assertErrors(const []); } }