[web] Enabled lints and cleanup violations

Change-Id: I1b559215cd8b55fca2b247d4279bef8b61f653b9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/243700
Reviewed-by: Stephen Adams <sra@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
This commit is contained in:
Nicholas Shahan 2022-05-24 23:59:16 +00:00 committed by Commit Bot
parent 3f0461a17c
commit ec1fa84691
5 changed files with 193 additions and 181 deletions

View file

@ -104,8 +104,7 @@ class TestStackTrace extends Step<Data, Data, ChainContext> {
var result = name;
if (result.startsWith('new ')) result = result.substring(4);
if (result.startsWith('Object.')) result = result.substring(7);
var inputName =
INPUT_FILE_NAME.substring(0, INPUT_FILE_NAME.indexOf('.') + 1);
var inputName = inputFileName.substring(0, inputFileName.indexOf('.') + 1);
if (result.startsWith(inputName)) {
result = result.substring(inputName.length);
}

View file

@ -0,0 +1,18 @@
# Copyright (c) 2022, 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.
include: package:lints/recommended.yaml
analyzer:
errors:
implementation_imports: ignore
linter:
rules:
# Not enforced by the lints package at any version.
- always_declare_return_types
- depend_on_referenced_packages
- directives_ordering
- prefer_single_quotes
- prefer_relative_imports

View file

@ -3,17 +3,17 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'dart:io';
import 'dart:convert' show jsonDecode;
import 'dart:io';
import 'package:_fe_analyzer_shared/src/testing/annotated_code_helper.dart';
import 'package:dart2js_tools/src/dart2js_mapping.dart';
import 'package:expect/expect.dart';
import 'package:source_maps/source_maps.dart';
import 'package:source_maps/src/utils.dart';
import 'package:source_span/source_span.dart';
import 'package:dart2js_tools/src/dart2js_mapping.dart';
const String INPUT_FILE_NAME = 'input.dart';
const String inputFileName = 'input.dart';
class Test {
final String code;
@ -33,7 +33,7 @@ class Expectations {
/// the annotations by prefix.
Test processTestCode(String code, Iterable<String> configs) {
AnnotatedCode annotatedCode =
new AnnotatedCode.fromText(code, commentStart, commentEnd);
AnnotatedCode.fromText(code, commentStart, commentEnd);
Map<String, Expectations> expectationMap = <String, Expectations>{};
@ -47,8 +47,8 @@ Test processTestCode(String code, Iterable<String> configs) {
int colonIndex = text.indexOf(':');
String indexText = text.substring(0, colonIndex);
String methodName = text.substring(colonIndex + 1);
StackTraceLine stackTraceLine = new StackTraceLine(
methodName, INPUT_FILE_NAME, annotation.lineNo, annotation.columnNo);
StackTraceLine stackTraceLine = StackTraceLine(
methodName, inputFileName, annotation.lineNo, annotation.columnNo);
if (indexText == '') {
unexpectedLines.add(stackTraceLine);
} else {
@ -63,16 +63,16 @@ Test processTestCode(String code, Iterable<String> configs) {
in (stackTraceMap.keys.toList()..sort()).reversed) {
expectedLines.add(stackTraceMap[stackTraceIndex]);
}
expectationMap[config] = new Expectations(expectedLines, unexpectedLines);
expectationMap[config] = Expectations(expectedLines, unexpectedLines);
});
return new Test(annotatedCode.sourceCode, expectationMap);
return Test(annotatedCode.sourceCode, expectationMap);
}
/// Compile function used in [testStackTrace]. [input] is the name of the input
/// Dart file and [output] is the name of the generated JavaScript file. The
/// function returns `true` if the compilation succeeded.
typedef Future<bool> CompileFunc(String input, String output);
typedef CompileFunc = Future<bool> Function(String, String);
List<String> emptyPreamble(input, output) => const <String>[];
String identityConverter(String name) => name;
@ -97,45 +97,45 @@ String identityConverter(String name) => name;
/// will not be cleaned up. Note that if *not* giving a temporary directory and
/// the test fails the directory will not be cleaned up.
Future testStackTrace(Test test, String config, CompileFunc compile,
{bool printJs: false,
bool writeJs: false,
bool verbose: false,
List<String> Function(String input, String output) jsPreambles:
{bool printJs = false,
bool writeJs = false,
bool verbose = false,
List<String> Function(String input, String output) jsPreambles =
emptyPreamble,
List<LineException> beforeExceptions: const <LineException>[],
List<LineException> afterExceptions: const <LineException>[],
bool useJsMethodNamesOnAbsence: false,
String Function(String name) jsNameConverter: identityConverter,
Directory forcedTmpDir: null,
int stackTraceLimit: 10,
expandDart2jsInliningData: false}) async {
List<LineException> beforeExceptions = const <LineException>[],
List<LineException> afterExceptions = const <LineException>[],
bool useJsMethodNamesOnAbsence = false,
String Function(String name) jsNameConverter = identityConverter,
Directory forcedTmpDir,
int stackTraceLimit = 10,
expandDart2jsInliningData = false}) async {
Expect.isTrue(test.expectationMap.keys.contains(config),
"No expectations found for '$config' in ${test.expectationMap.keys}");
Directory tmpDir =
forcedTmpDir ?? await Directory.systemTemp.createTemp('stacktrace-test');
String input = '${tmpDir.path}/$INPUT_FILE_NAME';
new File(input).writeAsStringSync(test.code);
String input = '${tmpDir.path}/$inputFileName';
File(input).writeAsStringSync(test.code);
String output = '${tmpDir.path}/out.js';
Expect.isTrue(await compile(input, output),
"Unsuccessful compilation of test:\n${test.code}");
File sourceMapFile = new File('$output.map');
'Unsuccessful compilation of test:\n${test.code}');
File sourceMapFile = File('$output.map');
Expect.isTrue(
sourceMapFile.existsSync(), "Source map not generated for $input");
sourceMapFile.existsSync(), 'Source map not generated for $input');
String sourceMapText = sourceMapFile.readAsStringSync();
SingleMapping sourceMap = parse(sourceMapText);
String jsOutput = new File(output).readAsStringSync();
String jsOutput = File(output).readAsStringSync();
if (printJs) {
print('JavaScript output:');
print(jsOutput);
}
if (writeJs) {
new File('out.js').writeAsStringSync(jsOutput);
new File('out.js.map').writeAsStringSync(sourceMapText);
File('out.js').writeAsStringSync(jsOutput);
File('out.js.map').writeAsStringSync(sourceMapText);
}
print("Running d8 $output");
print('Running d8 $output');
List<String> d8Arguments = <String>[];
d8Arguments.add('--stack-trace-limit');
d8Arguments.add('$stackTraceLimit');
@ -147,11 +147,11 @@ Future testStackTrace(Test test, String config, CompileFunc compile,
print('d8 output:');
print(out);
}
List<String> lines = out.split(new RegExp(r'(\r|\n|\r\n)'));
List<String> lines = out.split(RegExp(r'(\r|\n|\r\n)'));
List<StackTraceLine> jsStackTrace = <StackTraceLine>[];
for (String line in lines) {
if (line.startsWith(' at ')) {
StackTraceLine stackTraceLine = new StackTraceLine.fromText(line);
StackTraceLine stackTraceLine = StackTraceLine.fromText(line);
if (stackTraceLine.lineNo != null && stackTraceLine.columnNo != null) {
jsStackTrace.add(stackTraceLine);
}
@ -173,7 +173,7 @@ Future testStackTrace(Test test, String config, CompileFunc compile,
int targetColumn = targetEntry.sourceColumn + 1;
if (expandDart2jsInliningData) {
SourceFile file = new SourceFile.fromString(jsOutput);
SourceFile file = SourceFile.fromString(jsOutput);
int offset = file.getOffset(line.lineNo - 1, line.columnNo - 1);
Map<int, List<FrameEntry>> frames =
_loadInlinedFrameData(sourceMap, sourceMapText);
@ -186,8 +186,8 @@ Future testStackTrace(Test test, String config, CompileFunc compile,
if (frame.isEmpty) break outer;
if (frame.isPush) {
if (depth <= 0) {
dartStackTrace.add(new StackTraceLine(
frame.inlinedMethodName + "(inlined)",
dartStackTrace.add(StackTraceLine(
'${frame.inlinedMethodName}(inlined)',
fileName,
targetLine,
targetColumn,
@ -215,7 +215,7 @@ Future testStackTrace(Test test, String config, CompileFunc compile,
methodName = jsNameConverter(line.methodName);
}
dartStackTrace.add(new StackTraceLine(
dartStackTrace.add(StackTraceLine(
methodName, fileName, targetLine, targetColumn,
isMapped: true));
}
@ -273,20 +273,20 @@ Future testStackTrace(Test test, String config, CompileFunc compile,
Expect.equals(
expectedIndex,
expectations.expectedLines.length,
"Missing stack trace lines for test:\n${test.code}\n"
"Actual:\n${dartStackTrace.join('\n')}\n\n"
"Expected:\n${expectations.expectedLines.join('\n')}\n");
'Missing stack trace lines for test:\n${test.code}\n'
'Actual:\n${dartStackTrace.join('\n')}\n\n'
'Expected:\n${expectations.expectedLines.join('\n')}\n');
Expect.isTrue(
unexpectedLines.isEmpty,
"Unexpected stack trace lines for test:\n${test.code}\n"
"Actual:\n${dartStackTrace.join('\n')}\n\n"
"Unexpected:\n${expectations.unexpectedLines.join('\n')}\n");
'Unexpected stack trace lines for test:\n${test.code}\n'
'Actual:\n${dartStackTrace.join('\n')}\n\n'
'Unexpected:\n${expectations.unexpectedLines.join('\n')}\n');
Expect.isTrue(
unexpectedBeforeLines.isEmpty && unexpectedAfterLines.isEmpty,
"Unexpected stack trace lines:\n${test.code}\n"
"Actual:\n${dartStackTrace.join('\n')}\n\n"
"Unexpected before:\n${unexpectedBeforeLines.join('\n')}\n\n"
"Unexpected after:\n${unexpectedAfterLines.join('\n')}\n");
'Unexpected stack trace lines:\n${test.code}\n'
'Actual:\n${dartStackTrace.join('\n')}\n\n'
'Unexpected before:\n${unexpectedBeforeLines.join('\n')}\n\n'
'Unexpected after:\n${unexpectedAfterLines.join('\n')}\n');
if (forcedTmpDir == null) {
print("Deleting '${tmpDir.path}'.");
@ -302,7 +302,7 @@ class StackTraceLine {
bool isMapped;
StackTraceLine(this.methodName, this.fileName, this.lineNo, this.columnNo,
{this.isMapped: false});
{this.isMapped = false});
/// Creates a [StackTraceLine] by parsing a d8 stack trace line [text]. The
/// expected formats are
@ -353,11 +353,12 @@ class StackTraceLine {
} else {
fileName = text;
}
return new StackTraceLine(methodName, fileName, lineNo, columnNo);
return StackTraceLine(methodName, fileName, lineNo, columnNo);
}
@override
String toString() {
StringBuffer sb = new StringBuffer();
StringBuffer sb = StringBuffer();
sb.write(' at ');
if (methodName != null) {
sb.write(methodName);
@ -386,7 +387,7 @@ class StackTraceLine {
/// Copied from [SingleMapping._findLine].
TargetLineEntry _findLine(SingleMapping sourceMap, StackTraceLine stLine) {
String filename = stLine.fileName
.substring(stLine.fileName.lastIndexOf(new RegExp("[\\\/]")) + 1);
.substring(stLine.fileName.lastIndexOf(RegExp('[\\/]')) + 1);
if (sourceMap.targetUrl != filename) return null;
return _findLineInternal(sourceMap, stLine.lineNo - 1);
}
@ -404,7 +405,7 @@ TargetLineEntry _findLineInternal(SingleMapping sourceMap, int line) {
///
/// Copied from [SingleMapping._findColumn].
TargetEntry _findColumn(int line, int column, TargetLineEntry lineEntry) {
if (lineEntry == null || lineEntry.entries.length == 0) return null;
if (lineEntry == null || lineEntry.entries.isEmpty) return null;
if (lineEntry.line != line) return lineEntry.entries.last;
var entries = lineEntry.entries;
int index = binarySearch(entries, (e) => e.column > column);
@ -420,7 +421,7 @@ String get d8executable {
} else if (Platform.isMacOS) {
return 'third_party/d8/macos/d8';
}
throw new UnsupportedError('Unsupported platform.');
throw UnsupportedError('Unsupported platform.');
}
/// A line allowed in the mapped stack trace.

View file

@ -5,73 +5,67 @@ import 'package:expect/minitest.dart';
import 'package:path/path.dart' as path;
import 'package:source_maps/source_maps.dart';
/**
* Runs D8 and steps as the AnnotatedCode dictates.
*
* Note that the compiled javascript is expected to be called "js.js" inside the
* outputPath directory. It is also expected that there is a "js.js.map" file.
* It is furthermore expected that the js has been compiled from a file in the
* same folder called test.dart.
*/
/// Runs D8 and steps as the AnnotatedCode dictates.
///
/// Note that the compiled javascript is expected to be called "js.js" inside
/// the outputPath directory. It is also expected that there is a "js.js.map"
/// file. It is furthermore expected that the js has been compiled from a file
/// in the same folder called test.dart.
ProcessResult runD8AndStep(String outputPath, String testFileName,
AnnotatedCode code, List<String> scriptD8Command) {
var outputFile = path.join(outputPath, "js.js");
SingleMapping sourceMap =
parse(new File("${outputFile}.map").readAsStringSync());
var outputFile = path.join(outputPath, 'js.js');
SingleMapping sourceMap = parse(File('$outputFile.map').readAsStringSync());
Set<int> mappedToLines = sourceMap.lines
.map((entry) => entry.entries.map((entry) => entry.sourceLine).toSet())
.fold(new Set<int>(), (prev, e) => prev..addAll(e));
.fold(<int>{}, (prev, e) => prev..addAll(e));
for (Annotation annotation
in code.annotations.where((a) => a.text.trim() == "nm")) {
in code.annotations.where((a) => a.text.trim() == 'nm')) {
if (mappedToLines.contains(annotation.lineNo - 1)) {
fail("Was not allowed to have a mapping to line "
"${annotation.lineNo}, but did.\n"
"Sourcemap looks like this (note 0-indexed):\n"
"${sourceMap.debugString}");
fail('Was not allowed to have a mapping to line '
'${annotation.lineNo}, but did.\n'
'Sourcemap looks like this (note 0-indexed):\n'
'${sourceMap.debugString}');
}
}
List<String> breakpoints = [];
// Annotations are 1-based, js breakpoints are 0-based.
for (Annotation breakAt
in code.annotations.where((a) => a.text.trim() == "bl")) {
in code.annotations.where((a) => a.text.trim() == 'bl')) {
breakpoints
.add(_getJsBreakpointLine(testFileName, sourceMap, breakAt.lineNo - 1));
}
for (Annotation breakAt
in code.annotations.where((a) => a.text.trim().startsWith("bc:"))) {
in code.annotations.where((a) => a.text.trim().startsWith('bc:'))) {
breakpoints.add(_getJsBreakpointLineAndColumn(
testFileName, sourceMap, breakAt.lineNo - 1, breakAt.columnNo - 1));
}
File inspectorFile = new File.fromUri(
sdkRoot.uri.resolve("pkg/sourcemap_testing/lib/src/js/inspector.js"));
File inspectorFile = File.fromUri(
sdkRoot.uri.resolve('pkg/sourcemap_testing/lib/src/js/inspector.js'));
if (!inspectorFile.existsSync()) throw "Couldn't find 'inspector.js'";
var outInspectorPath = path.join(outputPath, "inspector.js");
var outInspectorPath = path.join(outputPath, 'inspector.js');
inspectorFile.copySync(outInspectorPath);
String debugAction = "Debugger.stepInto";
if (code.annotations.any((a) => a.text.trim() == "Debugger:stepOver")) {
debugAction = "Debugger.stepOver";
String debugAction = 'Debugger.stepInto';
if (code.annotations.any((a) => a.text.trim() == 'Debugger:stepOver')) {
debugAction = 'Debugger.stepOver';
}
return _runD8(outInspectorPath, scriptD8Command, debugAction, breakpoints);
}
/**
* Translates the D8 js steps and checks against expectations.
*
* Note that the compiled javascript is expected to be called "js.js" inside the
* outputPath directory. It is also expected that there is a "js.js.map" file.
* It is furthermore expected that the js has been compiled from a file in the
* same folder called test.dart.
*/
/// Translates the D8 js steps and checks against expectations.
///
/// Note that the compiled javascript is expected to be called "js.js" inside
/// the outputPath directory. It is also expected that there is a "js.js.map"
/// file. It is furthermore expected that the js has been compiled from a file
/// in the same folder called test.dart.
void checkD8Steps(String outputPath, List<String> d8Output, AnnotatedCode code,
{bool debug: false}) {
var outputFilename = "js.js";
{bool debug = false}) {
var outputFilename = 'js.js';
var outputFile = path.join(outputPath, outputFilename);
SingleMapping sourceMap =
parse(new File("${outputFile}.map").readAsStringSync());
SingleMapping sourceMap = parse(File('$outputFile.map').readAsStringSync());
List<List<_DartStackTraceDataEntry>> result =
_extractStackTraces(d8Output, sourceMap, outputFilename);
@ -81,37 +75,37 @@ void checkD8Steps(String outputPath, List<String> d8Output, AnnotatedCode code,
if (debug) _debugPrint(trace, outputPath);
List<String> recordStops =
trace.where((entry) => !entry.isError).map((entry) => "$entry").toList();
trace.where((entry) => !entry.isError).map((entry) => '$entry').toList();
Set<int> recordStopLines =
trace.where((entry) => !entry.isError).map((entry) => entry.line).toSet();
Set<String> recordStopLineColumns = trace
.where((entry) => !entry.isError)
.map((entry) => "${entry.line}:${entry.column}")
.map((entry) => '${entry.line}:${entry.column}')
.toSet();
List<String> expectedStops = [];
for (Annotation annotation in code.annotations.where((annotation) =>
annotation.text.trim().startsWith("s:") ||
annotation.text.trim().startsWith("sl:") ||
annotation.text.trim().startsWith("bc:"))) {
annotation.text.trim().startsWith('s:') ||
annotation.text.trim().startsWith('sl:') ||
annotation.text.trim().startsWith('bc:'))) {
String text = annotation.text.trim();
int stopNum = int.parse(text.substring(text.indexOf(":") + 1));
int stopNum = int.parse(text.substring(text.indexOf(':') + 1));
if (expectedStops.length < stopNum) expectedStops.length = stopNum;
if (text.startsWith("sl:")) {
expectedStops[stopNum - 1] = "test.dart:${annotation.lineNo}:";
if (text.startsWith('sl:')) {
expectedStops[stopNum - 1] = 'test.dart:${annotation.lineNo}:';
} else {
expectedStops[stopNum - 1] =
"test.dart:${annotation.lineNo}:${annotation.columnNo}:";
'test.dart:${annotation.lineNo}:${annotation.columnNo}:';
}
}
List<List<String>> noBreaksStart = [];
List<List<String>> noBreaksEnd = [];
for (Annotation annotation in code.annotations
.where((annotation) => annotation.text.trim().startsWith("nbb:"))) {
.where((annotation) => annotation.text.trim().startsWith('nbb:'))) {
String text = annotation.text.trim();
var split = text.split(":");
var split = text.split(':');
int stopNum1 = int.parse(split[1]);
int stopNum2 = int.parse(split[2]);
if (noBreaksStart.length <= stopNum1) noBreaksStart.length = stopNum1 + 1;
@ -119,33 +113,33 @@ void checkD8Steps(String outputPath, List<String> d8Output, AnnotatedCode code,
if (noBreaksEnd.length <= stopNum2) noBreaksEnd.length = stopNum2 + 1;
noBreaksEnd[stopNum2] ??= [];
noBreaksStart[stopNum1].add("test.dart:${annotation.lineNo}:");
noBreaksEnd[stopNum2].add("test.dart:${annotation.lineNo}:");
noBreaksStart[stopNum1].add('test.dart:${annotation.lineNo}:');
noBreaksEnd[stopNum2].add('test.dart:${annotation.lineNo}:');
}
_checkRecordedStops(
recordStops, expectedStops, noBreaksStart, noBreaksEnd, debug);
for (Annotation annotation in code.annotations
.where((annotation) => annotation.text.trim() == "nb")) {
.where((annotation) => annotation.text.trim() == 'nb')) {
// Check that we didn't break where we're not allowed to.
if (recordStopLines.contains(annotation.lineNo)) {
fail("Was not allowed to stop on line ${annotation.lineNo}, but did!"
" Actual line stops: $recordStopLines${_debugHint(debug)}");
fail('Was not allowed to stop on line ${annotation.lineNo}, but did!'
' Actual line stops: $recordStopLines${_debugHint(debug)}');
}
}
for (Annotation annotation in code.annotations
.where((annotation) => annotation.text.trim() == "nbc")) {
.where((annotation) => annotation.text.trim() == 'nbc')) {
// Check that we didn't break where we're not allowed to.
if (recordStopLineColumns
.contains("${annotation.lineNo}:${annotation.columnNo}")) {
fail("Was not allowed to stop on line ${annotation.lineNo} "
"column ${annotation.columnNo}, but did!"
" Actual line stops: $recordStopLineColumns${_debugHint(debug)}");
.contains('${annotation.lineNo}:${annotation.columnNo}')) {
fail('Was not allowed to stop on line ${annotation.lineNo} '
'column ${annotation.columnNo}, but did!'
' Actual line stops: $recordStopLineColumns${_debugHint(debug)}');
}
}
if (code.annotations.any((a) => a.text.trim() == "fail")) {
if (code.annotations.any((a) => a.text.trim() == 'fail')) {
fail("Test contains 'fail' annotation.");
}
}
@ -162,15 +156,15 @@ void _checkRecordedStops(
// to be between those points though.
int expectedIndex = 0;
Set<String> aliveNoBreaks = new Set<String>();
if (noBreaksStart.length > 0 && noBreaksStart[0] != null) {
Set<String> aliveNoBreaks = {};
if (noBreaksStart.isNotEmpty && noBreaksStart[0] != null) {
aliveNoBreaks.addAll(noBreaksStart[0]);
}
int stopNumber = 0;
for (String recorded in recordStops) {
stopNumber++;
if (expectedIndex == expectedStops.length) break;
if ("$recorded:".contains(expectedStops[expectedIndex])) {
if ('$recorded:'.contains(expectedStops[expectedIndex])) {
++expectedIndex;
if (noBreaksStart.length > expectedIndex &&
noBreaksStart[expectedIndex] != null) {
@ -191,27 +185,27 @@ void _checkRecordedStops(
// Both failures are difficult to debug without seeing the stops that
// didn't match. No breaks failures are misleading (the problem isn't
// an incorrect break, but we missed a stop, so the aliveNoBreaks is
// wrong), and the normal failure list dumps the enitre stop list,
// wrong), and the normal failure list dumps the entire stop list,
// making it difficult to see where the mismatch was.
//
// Also we add 1 to expectedIndex, because the stop annotations are
// 1-based in the source files (e.g. `/*s:1*/` is expectedIndex 0)
print("Skipping stop `$recorded` that didn't match expected stop "
"${expectedIndex + 1} `${expectedStops[expectedIndex]}`");
'${expectedIndex + 1} `${expectedStops[expectedIndex]}`');
}
if (aliveNoBreaks
.contains("${(recorded.split(":")..removeLast()).join(":")}:")) {
fail("Break '$recorded' was found when it wasn't allowed "
"(js step $stopNumber, after stop ${expectedIndex + 1}). "
"This can happen when an expected stop was not matched"
"${_debugHint(debug)}.");
'(js step $stopNumber, after stop ${expectedIndex + 1}). '
'This can happen when an expected stop was not matched'
'${_debugHint(debug)}.');
}
}
}
if (expectedIndex != expectedStops.length) {
// Didn't find everything.
fail("Expected to find $expectedStops but found $recordStops"
"${_debugHint(debug)}");
fail('Expected to find $expectedStops but found $recordStops'
'${_debugHint(debug)}');
}
}
@ -223,15 +217,14 @@ String _debugHint(bool debug) {
}
void _debugPrint(List<_DartStackTraceDataEntry> trace, String outputPath) {
StringBuffer sb = new StringBuffer();
StringBuffer sb = StringBuffer();
var jsFile =
new File(path.join(outputPath, "js.js")).readAsStringSync().split("\n");
var dartFile = new File(path.join(outputPath, "test.dart"))
.readAsStringSync()
.split("\n");
File(path.join(outputPath, 'js.js')).readAsStringSync().split('\n');
var dartFile =
File(path.join(outputPath, 'test.dart')).readAsStringSync().split('\n');
List<String> getSnippet(List<String> data, int line, int column) {
List<String> result = new List<String>.filled(5, "");
List<String> result = List<String>.filled(5, '');
if (line < 0 || column < 0) return result;
for (int i = 0; i < 5; ++i) {
@ -240,34 +233,34 @@ void _debugPrint(List<_DartStackTraceDataEntry> trace, String outputPath) {
result[i] = data[j];
}
if (result[2].length >= column) {
result[2] = result[2].substring(0, column) +
"/*STOP*/" +
result[2].substring(column);
var before = result[2].substring(0, column);
var after = result[2].substring(column);
result[2] = '$before/*STOP*/$after';
}
return result;
}
List<String> sideBySide(List<String> a, List<String> b, int columns) {
List<String> result = new List<String>.filled(a.length, null);
List<String> result = List<String>.filled(a.length, null);
for (int i = 0; i < a.length; ++i) {
String left = a[i].padRight(columns).substring(0, columns);
String right = b[i].padRight(columns).substring(0, columns);
result[i] = left + " | " + right;
result[i] = '$left | $right';
}
return result;
}
for (int i = 0; i < trace.length; ++i) {
sb.write("\n\nStop #${i + 1}\n\n");
sb.write('\n\nStop #${i + 1}\n\n');
if (trace[i].isError && trace[i].jsLine < 0) {
sb.write("${trace[i].errorString}\n");
sb.write('${trace[i].errorString}\n');
continue;
}
var jsSnippet = getSnippet(jsFile, trace[i].jsLine, trace[i].jsColumn);
var dartSnippet =
getSnippet(dartFile, trace[i].line - 1, trace[i].column - 1);
var view = sideBySide(jsSnippet, dartSnippet, 50);
sb.writeAll(view, "\n");
sb.writeAll(view, '\n');
}
print(sb.toString());
@ -279,9 +272,9 @@ List<List<_DartStackTraceDataEntry>> _extractStackTraces(
bool inStackTrace = false;
List<String> currentStackTrace = <String>[];
for (var line in lines) {
if (line.trim() == "--- Debugger stacktrace start ---") {
if (line.trim() == '--- Debugger stacktrace start ---') {
inStackTrace = true;
} else if (line.trim() == "--- Debugger stacktrace end ---") {
} else if (line.trim() == '--- Debugger stacktrace end ---') {
result.add(
_extractStackTrace(currentStackTrace, sourceMap, outputFilename));
currentStackTrace.clear();
@ -297,14 +290,13 @@ List<_DartStackTraceDataEntry> _extractStackTrace(
List<String> js, SingleMapping sourceMap, String wantedFile) {
List<_DartStackTraceDataEntry> result = [];
for (String line in js) {
if (!line.contains("$wantedFile:")) {
result.add(
new _DartStackTraceDataEntry.error("Not correct file @ '$line'"));
if (!line.contains('$wantedFile:')) {
result.add(_DartStackTraceDataEntry.error("Not correct file @ '$line'"));
continue;
}
Iterable<Match> ms = new RegExp(r"(\d+):(\d+)").allMatches(line);
Iterable<Match> ms = RegExp(r'(\d+):(\d+)').allMatches(line);
if (ms.isEmpty) {
result.add(new _DartStackTraceDataEntry.error(
result.add(_DartStackTraceDataEntry.error(
"Line and column not found for '$line'"));
continue;
}
@ -313,12 +305,12 @@ List<_DartStackTraceDataEntry> _extractStackTrace(
int c = int.parse(m.group(2));
SourceMapSpan span = _getColumnOrPredecessor(sourceMap, l, c);
if (span?.start == null) {
result.add(new _DartStackTraceDataEntry.errorWithJsPosition(
result.add(_DartStackTraceDataEntry.errorWithJsPosition(
"Source map not found for '$line'", l, c));
continue;
}
var file = span.sourceUrl?.pathSegments?.last ?? "(unknown file)";
result.add(new _DartStackTraceDataEntry(
var file = span.sourceUrl?.pathSegments?.last ?? '(unknown file)';
result.add(_DartStackTraceDataEntry(
file, span.start.line + 1, span.start.column + 1, l, c));
}
return result;
@ -337,7 +329,7 @@ class _DartStackTraceDataEntry {
final String file;
final int line;
final int column;
final errorString;
final String errorString;
final int jsLine;
final int jsColumn;
@ -356,9 +348,10 @@ class _DartStackTraceDataEntry {
line = -1,
column = -1;
get isError => errorString != null;
bool get isError => errorString != null;
String toString() => isError ? errorString : "$file:$line:$column";
@override
String toString() => isError ? errorString : '$file:$line:$column';
}
class _PointMapping {
@ -370,13 +363,10 @@ class _PointMapping {
_PointMapping(this.fromLine, this.fromColumn, this.toLine, this.toColumn);
}
/**
* Input and output is expected to be 0-based.
*
* The "magic 4" below is taken from https://github.com/ChromeDevTools/devtools-
* frontend/blob/fa18d70a995f06cb73365b2e5b8ae974cf60bd3a/front_end/sources/
* JavaScriptSourceFrame.js#L1520-L1523
*/
/// Input and output is expected to be 0-based.
///
/// The "magic 4" below is taken from
/// https://github.com/ChromeDevTools/devtools-frontend/blob/fa18d70a995f06cb73365b2e5b8ae974cf60bd3a/front_end/sources/JavaScriptSourceFrame.js#L1520-L1523
String _getJsBreakpointLine(
String testFileName, SingleMapping sourceMap, int breakOnLine) {
List<_PointMapping> mappingsOnLines = [];
@ -387,7 +377,7 @@ String _getJsBreakpointLine(
entry.sourceLine < breakOnLine + 4 &&
entry.sourceUrlId != null &&
sourceMap.urls[entry.sourceUrlId] == testFileName) {
mappingsOnLines.add(new _PointMapping(
mappingsOnLines.add(_PointMapping(
entry.sourceLine, entry.sourceColumn, line.line, entry.column));
}
}
@ -405,12 +395,10 @@ String _getJsBreakpointLine(
mappingsOnLines.retainWhere((p) => p.toLine >= first.toLine);
_PointMapping last = mappingsOnLines.last;
return "${first.toLine}:${first.toColumn}:${last.toLine}:${first.toColumn}";
return '${first.toLine}:${first.toColumn}:${last.toLine}:${first.toColumn}';
}
/**
* Input and output is expected to be 0-based.
*/
/// Input and output is expected to be 0-based.
String _getJsBreakpointLineAndColumn(String testFileName,
SingleMapping sourceMap, int breakOnLine, int breakOnColumn) {
for (var line in sourceMap.lines) {
@ -418,8 +406,9 @@ String _getJsBreakpointLineAndColumn(String testFileName,
if (entry.sourceLine == breakOnLine &&
entry.sourceColumn == breakOnColumn &&
entry.sourceUrlId != null &&
sourceMap.urls[entry.sourceUrlId] == testFileName)
return "${line.line}:${entry.column}";
sourceMap.urls[entry.sourceUrlId] == testFileName) {
return '${line.line}:${entry.column}';
}
}
}
return null;
@ -428,16 +417,18 @@ String _getJsBreakpointLineAndColumn(String testFileName,
ProcessResult _runD8(String outInspectorPath, List<String> scriptD8Command,
String debugAction, List<String> breakpoints) {
var outInspectorPathRelative = path.relative(outInspectorPath);
ProcessResult runResult = Process.runSync(
d8Executable,
['--enable-inspector', outInspectorPathRelative]
..addAll(scriptD8Command)
..addAll(["--", debugAction])
..addAll(breakpoints.where((s) => s != null)));
ProcessResult runResult = Process.runSync(d8Executable, [
'--enable-inspector',
outInspectorPathRelative,
...scriptD8Command,
'--',
debugAction,
...breakpoints.where((s) => s != null)
]);
if (runResult.exitCode != 0) {
print(runResult.stderr);
print(runResult.stdout);
throw "Exit code: ${runResult.exitCode} from d8";
throw 'Exit code: ${runResult.exitCode} from d8';
}
return runResult;
}
@ -447,23 +438,23 @@ Directory _cachedSdkRoot;
File getD8File() {
File attemptFileFromDir(Directory dir) {
if (Platform.isWindows) {
return new File(dir.path + Platform.pathSeparator + "d8/windows/d8.exe");
return File('${dir.path}${Platform.pathSeparator}d8/windows/d8.exe');
} else if (Platform.isLinux) {
return new File(dir.path + Platform.pathSeparator + "d8/linux/d8");
return File('${dir.path}${Platform.pathSeparator}d8/linux/d8');
} else if (Platform.isMacOS) {
return new File(dir.path + Platform.pathSeparator + "d8/macos/d8");
return File('${dir.path}${Platform.pathSeparator}d8/macos/d8');
}
throw new UnsupportedError('Unsupported platform.');
throw UnsupportedError('Unsupported platform.');
}
File search() {
Directory dir = new File.fromUri(Platform.script).parent;
Directory dir = File.fromUri(Platform.script).parent;
while (dir.path.length > 1) {
for (var entry in dir.listSync()) {
if (entry is! Directory) continue;
if (entry.path.endsWith("third_party")) {
if (entry.path.endsWith('third_party')) {
List<String> segments = entry.uri.pathSegments;
if (segments[segments.length - 2] == "third_party") {
if (segments[segments.length - 2] == 'third_party') {
File possibleD8 = attemptFileFromDir(entry);
if (possibleD8.existsSync()) {
_cachedSdkRoot = dir;
@ -475,7 +466,7 @@ File getD8File() {
dir = dir.parent;
}
throw "Cannot find D8 directory.";
throw 'Cannot find D8 directory.';
}
return _cachedD8File ??= search();

View file

@ -4,12 +4,15 @@ name: sourcemap_testing
publish_to: none
environment:
sdk: '>=2.1.0 <3.0.0'
sdk: '>=2.11.0 <3.0.0'
dependencies:
_fe_analyzer_shared: any
dart2js_tools: any
expect: any
dart2js_tools: any
expect: any
path: any
source_maps: any
source_span: any
dev_dependencies:
lints: any