77446204da
This reverts commite48f35b43d. Reason for revert: linter is fixed. Original change's description: > Revert "[analyzer] Move 4 more HintCodes to be WarningCodes, UNUSED_*" > > This reverts commit0ef7ed2ebd. > > Reason for revert: Tests are failing in google3 - linter needs to be bumped > > Original change's description: > > [analyzer] Move 4 more HintCodes to be WarningCodes, UNUSED_* > > > > Bug: https://github.com/dart-lang/sdk/issues/50796 > > Change-Id: Ib5b153bc6e64bc433df1f05c53d82f71b470bbec > > TEST=presubmit bots > > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/290703 > > Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> > > Reviewed-by: Alexander Aprelev <aam@google.com> > > Commit-Queue: Samuel Rawlins <srawlins@google.com> > > Reviewed-by: Nate Bosch <nbosch@google.com> > > Bug: https://github.com/dart-lang/sdk/issues/50796 > Change-Id: If1c460bdcf422033648417da5ba2f5fbc1b459c2 > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/291460 > Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com> > Auto-Submit: Oleh Prypin <oprypin@google.com> > Reviewed-by: Alexander Thomas <athom@google.com> > Commit-Queue: Alexander Thomas <athom@google.com> > Commit-Queue: Oleh Prypin <oprypin@google.com> Bug: https://github.com/dart-lang/sdk/issues/50796 Change-Id: Ie503b57a19df1a50cb3dfe50c840d20779310e87 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/291560 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Oleh Prypin <oprypin@google.com> Reviewed-by: Nate Bosch <nbosch@google.com> Commit-Queue: Samuel Rawlins <srawlins@google.com> Reviewed-by: Alexander Aprelev <aam@google.com> Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
170 lines
5.8 KiB
Dart
170 lines
5.8 KiB
Dart
// 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.
|
|
|
|
import 'dart:convert';
|
|
|
|
import 'package:analyzer/dart/analysis/analysis_context.dart';
|
|
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
|
|
import 'package:analyzer/dart/analysis/results.dart';
|
|
import 'package:analyzer/error/error.dart';
|
|
import 'package:analyzer/file_system/file_system.dart';
|
|
import 'package:analyzer/file_system/overlay_file_system.dart';
|
|
import 'package:analyzer/file_system/physical_file_system.dart';
|
|
import 'package:analyzer/src/error/codes.dart';
|
|
import 'package:analyzer_utilities/package_root.dart' as package_root;
|
|
import 'package:test/test.dart';
|
|
|
|
main() async {
|
|
SnippetTester tester = SnippetTester();
|
|
await tester.verify();
|
|
if (tester.output.isNotEmpty) {
|
|
fail(tester.output.toString());
|
|
}
|
|
}
|
|
|
|
class SnippetTester {
|
|
final OverlayResourceProvider provider;
|
|
final Folder docFolder;
|
|
final String snippetDirPath;
|
|
final String snippetPath;
|
|
|
|
final StringBuffer output = StringBuffer();
|
|
|
|
factory SnippetTester() {
|
|
var provider = OverlayResourceProvider(PhysicalResourceProvider.INSTANCE);
|
|
var packageRoot = provider.pathContext.normalize(package_root.packageRoot);
|
|
var analyzerPath = provider.pathContext.join(packageRoot, 'analyzer');
|
|
var docPath = provider.pathContext.join(analyzerPath, 'doc');
|
|
var docFolder = provider.getFolder(docPath);
|
|
var snippetDirPath =
|
|
provider.pathContext.join(analyzerPath, 'test', 'snippets');
|
|
var snippetPath = provider.pathContext.join(snippetDirPath, 'snippet.dart');
|
|
return SnippetTester._(provider, docFolder, snippetDirPath, snippetPath);
|
|
}
|
|
|
|
SnippetTester._(
|
|
this.provider, this.docFolder, this.snippetDirPath, this.snippetPath);
|
|
|
|
Future<void> verify() async {
|
|
await verifyFolder(docFolder);
|
|
}
|
|
|
|
Future<void> verifyFile(File file) async {
|
|
String content = file.readAsStringSync();
|
|
List<String> lines = const LineSplitter().convert(content);
|
|
List<String> codeLines = [];
|
|
bool inCode = false;
|
|
for (int i = 0; i < lines.length; i++) {
|
|
String line = lines[i];
|
|
if (line == '```dart') {
|
|
if (inCode) {
|
|
// TODO(brianwilkerson) Report this.
|
|
}
|
|
inCode = true;
|
|
} else if (line == '```') {
|
|
if (!inCode) {
|
|
// TODO(brianwilkerson) Report this.
|
|
}
|
|
await verifySnippet(file, codeLines.join('\n'));
|
|
codeLines.clear();
|
|
inCode = false;
|
|
} else if (inCode) {
|
|
codeLines.add(line);
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<void> verifyFolder(Folder folder) async {
|
|
for (Resource child in folder.getChildren()) {
|
|
if (child is File) {
|
|
if (child.shortName.endsWith('.md')) {
|
|
await verifyFile(child);
|
|
}
|
|
} else if (child is Folder) {
|
|
await verifyFolder(child);
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<void> verifySnippet(File file, String snippet) async {
|
|
// TODO(brianwilkerson) When the files outside of 'src' contain only public
|
|
// API, write code to compute the list of imports so that new public API
|
|
// will automatically be allowed.
|
|
String imports = '''
|
|
import 'dart:math' as math;
|
|
|
|
import 'package:analyzer/dart/analysis/analysis_context.dart';
|
|
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
|
|
import 'package:analyzer/dart/analysis/results.dart';
|
|
import 'package:analyzer/dart/analysis/session.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/dart/element/visitor.dart';
|
|
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
|
|
|
Future<void> assertNoErrorsInCode(String s) async {}
|
|
void test(String s, void Function() f) {}
|
|
void group(String s, void Function() f) {}
|
|
''';
|
|
provider.setOverlay(snippetPath,
|
|
content: '''
|
|
$imports
|
|
$snippet
|
|
''',
|
|
modificationStamp: 1);
|
|
try {
|
|
AnalysisContextCollection collection = AnalysisContextCollection(
|
|
includedPaths: <String>[snippetDirPath], resourceProvider: provider);
|
|
List<AnalysisContext> contexts = collection.contexts;
|
|
if (contexts.length != 1) {
|
|
fail('The snippets directory contains multiple analysis contexts.');
|
|
}
|
|
var results = await contexts[0].currentSession.getErrors(snippetPath);
|
|
if (results is ErrorsResult) {
|
|
Iterable<AnalysisError> errors = results.errors.where((error) {
|
|
ErrorCode errorCode = error.errorCode;
|
|
return errorCode != WarningCode.UNUSED_IMPORT &&
|
|
errorCode != HintCode.UNUSED_LOCAL_VARIABLE;
|
|
});
|
|
if (errors.isNotEmpty) {
|
|
String filePath =
|
|
provider.pathContext.relative(file.path, from: docFolder.path);
|
|
if (output.isNotEmpty) {
|
|
output.writeln();
|
|
}
|
|
output.writeln('Errors in snippet in "$filePath":');
|
|
output.writeln();
|
|
output.writeln(snippet);
|
|
output.writeln();
|
|
int importsLength = imports.length + 1; // account for the '\n'.
|
|
for (var error in errors) {
|
|
writeError(error, importsLength);
|
|
}
|
|
}
|
|
}
|
|
} catch (exception, stackTrace) {
|
|
if (output.isNotEmpty) {
|
|
output.writeln();
|
|
}
|
|
output.writeln('Exception while analyzing "$snippet"');
|
|
output.writeln();
|
|
output.writeln(exception);
|
|
output.writeln(stackTrace);
|
|
} finally {
|
|
provider.removeOverlay(snippetPath);
|
|
}
|
|
}
|
|
|
|
void writeError(AnalysisError error, int prefixLength) {
|
|
output.write(error.errorCode);
|
|
output.write(' (');
|
|
output.write(error.offset - prefixLength);
|
|
output.write(', ');
|
|
output.write(error.length);
|
|
output.write(') ');
|
|
output.writeln(error.message);
|
|
}
|
|
}
|