You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
545 lines
22 KiB
545 lines
22 KiB
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.Parser = void 0;
|
|
const path_1 = require("path");
|
|
const Matchers_1 = require("./Matchers");
|
|
const switchRegex_1 = require("./switchRegex");
|
|
function unescaped(args) {
|
|
return args.map(v => v.replace(/\\/g, ''));
|
|
}
|
|
class Parser {
|
|
constructor(formatter) {
|
|
this.formatter = formatter;
|
|
this.formattedSummary = false;
|
|
this.failures = {};
|
|
this.linkerFailure = {
|
|
files: [],
|
|
};
|
|
this.currentIssue = {};
|
|
}
|
|
parse(text) {
|
|
const matchedErrorResults = this.updateErrorState(text);
|
|
if (this.shouldFormatWarning()) {
|
|
return this.formatCompileWarning();
|
|
}
|
|
if (this.shouldFormatError()) {
|
|
return this.formatCompileError();
|
|
}
|
|
if (matchedErrorResults) {
|
|
return '';
|
|
}
|
|
const matchedLinkerResults = this.updateLinkerFailureState(text);
|
|
if (this.shouldFormatUndefinedSymbols()) {
|
|
return this.formatUndefinedSymbols();
|
|
}
|
|
if (this.shouldFormatDuplicateSymbols()) {
|
|
return this.formatDuplicateSymbols();
|
|
}
|
|
if (matchedLinkerResults) {
|
|
return '';
|
|
}
|
|
this.updateTestState(text);
|
|
const { formatter } = this;
|
|
return switchRegex_1.switchRegex(text, [
|
|
[
|
|
Matchers_1.Matchers.ANALYZE_MATCHER,
|
|
([, $1, $2, $3, $4]) => formatter.formatFileOperation({
|
|
type: 'Analyze',
|
|
filePath: $1,
|
|
fileName: $2,
|
|
target: $3,
|
|
project: $4,
|
|
}),
|
|
],
|
|
[
|
|
Matchers_1.Matchers.BUILD_TARGET_MATCHER,
|
|
([, $1, $2, $3]) => formatter.formatTarget({
|
|
type: 'Build',
|
|
configuration: $3,
|
|
target: $1,
|
|
project: $2,
|
|
}),
|
|
],
|
|
[
|
|
Matchers_1.Matchers.AGGREGATE_TARGET_MATCHER,
|
|
([, $1, $2, $3]) => formatter.formatTarget({
|
|
type: 'Aggregate',
|
|
configuration: $3,
|
|
target: $1,
|
|
project: $2,
|
|
}),
|
|
],
|
|
[
|
|
Matchers_1.Matchers.ANALYZE_TARGET_MATCHER,
|
|
([, $1, $2, $3]) => formatter.formatTarget({
|
|
type: 'Analyze',
|
|
configuration: $3,
|
|
target: $1,
|
|
project: $2,
|
|
}),
|
|
],
|
|
[Matchers_1.Matchers.CLEAN_REMOVE_MATCHER, ([$0]) => formatter.formatCleanRemove($0)],
|
|
[
|
|
Matchers_1.Matchers.CLEAN_TARGET_MATCHER,
|
|
([, $1, $2, $3]) => formatter.formatTarget({
|
|
type: 'Clean',
|
|
configuration: $3,
|
|
target: $1,
|
|
project: $2,
|
|
}),
|
|
],
|
|
[
|
|
Matchers_1.Matchers.ANY_COPY_MATCHER,
|
|
([, $1, $2, $3, $4, $5]) => {
|
|
let from = $3;
|
|
let to = $2;
|
|
// Flipped with CpResource and CpHeader
|
|
if ($1.startsWith('Cp')) {
|
|
from = $2;
|
|
to = $3;
|
|
}
|
|
return formatter.formatCopy({ type: $1, from, to, target: $4, project: $5 });
|
|
},
|
|
],
|
|
[Matchers_1.Matchers.CHECK_DEPENDENCIES_MATCHER, ([$0]) => formatter.formatCheckDependencies($0)],
|
|
[Matchers_1.Matchers.Errors.CLANG_ERROR_MATCHER, ([, $1]) => formatter.formatError($1)],
|
|
[
|
|
Matchers_1.Matchers.CODESIGN_FRAMEWORK_MATCHER,
|
|
([, $1, $2, $3, $4]) => formatter.formatFileOperation({
|
|
type: 'CodeSign',
|
|
fileName: $2,
|
|
filePath: $1,
|
|
target: $3,
|
|
project: $4,
|
|
}),
|
|
],
|
|
[
|
|
Matchers_1.Matchers.CODESIGN_MATCHER,
|
|
([, $1, $2, $3, $4]) => formatter.formatFileOperation({
|
|
type: 'CodeSign',
|
|
fileName: $2,
|
|
filePath: $1,
|
|
target: $3,
|
|
project: $4,
|
|
}),
|
|
],
|
|
[Matchers_1.Matchers.Errors.CHECK_DEPENDENCIES_ERRORS_MATCHER, ([, $1]) => formatter.formatError($1)],
|
|
[
|
|
Matchers_1.Matchers.Errors.PROVISIONING_PROFILE_REQUIRED_MATCHER,
|
|
([, $1]) => formatter.formatError($1),
|
|
],
|
|
[Matchers_1.Matchers.Errors.NO_CERTIFICATE_MATCHER, ([, $1]) => formatter.formatError($1)],
|
|
[
|
|
Matchers_1.Matchers.COMPILE_MATCHER,
|
|
([, $1, $2, $3, $4, $5]) => formatter.formatFileOperation({
|
|
type: $1,
|
|
fileName: $3,
|
|
filePath: $2,
|
|
target: $4,
|
|
project: $5,
|
|
}),
|
|
],
|
|
[Matchers_1.Matchers.COMPILE_COMMAND_MATCHER, ([, $1, $2]) => formatter.formatCompileCommand($1, $2)],
|
|
[
|
|
Matchers_1.Matchers.COMPILE_XIB_MATCHER,
|
|
([, $1, $2, $3, $4]) => formatter.formatFileOperation({
|
|
type: 'CompileXIB',
|
|
fileName: $2,
|
|
filePath: $1,
|
|
target: $3,
|
|
project: $4,
|
|
}),
|
|
],
|
|
[
|
|
Matchers_1.Matchers.COMPILE_STORYBOARD_MATCHER,
|
|
([, $1, $2, $3, $4]) => formatter.formatFileOperation({
|
|
type: 'CompileStoryboard',
|
|
fileName: $2,
|
|
filePath: $1,
|
|
target: $3,
|
|
project: $4,
|
|
}),
|
|
],
|
|
[Matchers_1.Matchers.EXECUTED_MATCHER, () => this.formatSummaryIfNeeded(text)],
|
|
[Matchers_1.Matchers.REMARK_MATCHER, ([, $1]) => formatter.formatRemark($1)],
|
|
[
|
|
Matchers_1.Matchers.COMPILE_SWIFT_SOURCES_MATCHER,
|
|
([, , $2, $3, $4, $5, $6]) => formatter.formatCompileSwiftSources($2, $3, $4, $5, $6),
|
|
],
|
|
[
|
|
Matchers_1.Matchers.EMIT_SWIFT_MODULE_MATCHER,
|
|
([, , $2, $3, $4, $5]) => formatter.formatEmitSwiftModule($2, $3, $4, $5),
|
|
],
|
|
[
|
|
Matchers_1.Matchers.RESTARTING_TESTS_MATCHER,
|
|
() => formatter.formatFailingTest(this.testSuite, this.testCase, 'Test crashed', 'n/a'),
|
|
],
|
|
[
|
|
Matchers_1.Matchers.UI_FAILING_TEST_MATCHER,
|
|
([, $1, $2]) => formatter.formatFailingTest(this.testSuite, this.testCase, $2, $1),
|
|
],
|
|
[
|
|
Matchers_1.Matchers.FAILING_TEST_MATCHER,
|
|
([, $1, $2, $3, $4]) => formatter.formatFailingTest($2, $3, $4, $1),
|
|
],
|
|
[Matchers_1.Matchers.Errors.FATAL_ERROR_MATCHER, ([, $1]) => formatter.formatError($1)],
|
|
[Matchers_1.Matchers.Errors.RSYNC_ERROR_MATCHER, ([, $1]) => formatter.formatError($1)],
|
|
[
|
|
Matchers_1.Matchers.Errors.FILE_MISSING_ERROR_MATCHER,
|
|
([, $1, $2]) => formatter.formatFileMissingError($1, $2),
|
|
],
|
|
[
|
|
Matchers_1.Matchers.GENERATE_DSYM_MATCHER,
|
|
([, $1, $2, $3, $4]) => formatter.formatFileOperation({
|
|
type: 'GenerateDSYMFile',
|
|
filePath: $1,
|
|
fileName: $2,
|
|
target: $3,
|
|
project: $4,
|
|
}),
|
|
],
|
|
[
|
|
Matchers_1.Matchers.Warnings.LD_WARNING_MATCHER,
|
|
([, $1, $2]) => {
|
|
// Skip printing ld warnings when we're collecting multiline ld duplicate symbol warnings.
|
|
if (this.linkerFailure.isWarning) {
|
|
return '';
|
|
}
|
|
return formatter.formatLdWarning($1 + $2);
|
|
},
|
|
],
|
|
[Matchers_1.Matchers.Errors.LD_ERROR_MATCHER, ([, $1]) => formatter.formatError($1)],
|
|
[
|
|
Matchers_1.Matchers.LIBTOOL_MATCHER,
|
|
([, $1, $2, $3, $4]) => formatter.formatFileOperation({
|
|
type: 'Libtool',
|
|
filePath: $1,
|
|
fileName: $2,
|
|
target: $3,
|
|
project: $4,
|
|
}),
|
|
],
|
|
[
|
|
Matchers_1.Matchers.LINKING_MATCHER,
|
|
([, $1, $2, $3, $4, $5, $6]) => formatter.formatFileOperation({
|
|
type: 'Ld',
|
|
filePath: $1,
|
|
fileName: $2,
|
|
linkType: $3,
|
|
arch: $4,
|
|
target: $5,
|
|
project: $6,
|
|
}),
|
|
],
|
|
[Matchers_1.Matchers.Errors.MODULE_INCLUDES_ERROR_MATCHER, ([, $1]) => formatter.formatError($1)],
|
|
[
|
|
Matchers_1.Matchers.TEST_CASE_MEASURED_MATCHER,
|
|
([, $1, $2, $3]) => formatter.formatMeasuringTest($1, $2, $3),
|
|
],
|
|
[Matchers_1.Matchers.TEST_CASE_PENDING_MATCHER, ([, $1, $2]) => formatter.formatPendingTest($1, $2)],
|
|
[
|
|
Matchers_1.Matchers.TEST_CASE_PASSED_MATCHER,
|
|
([, $1, $2, $3]) => formatter.formatPassingTest($1, $2, $3),
|
|
],
|
|
[Matchers_1.Matchers.Errors.PODS_ERROR_MATCHER, ([, $1]) => formatter.formatError($1)],
|
|
[
|
|
Matchers_1.Matchers.PROCESS_INFO_PLIST_MATCHER,
|
|
([, $1, $2, $3, $4]) => {
|
|
const [filePath, fileName] = unescaped([$1, $2]);
|
|
return formatter.formatFileOperation({
|
|
type: 'ProcessInfoPlistFile',
|
|
fileName,
|
|
filePath,
|
|
target: $3,
|
|
project: $4,
|
|
});
|
|
},
|
|
],
|
|
[
|
|
Matchers_1.Matchers.PHASE_SCRIPT_EXECUTION_MATCHER,
|
|
// @ts-ignore: spread
|
|
([, $1, $2, $3]) => formatter.formatPhaseScriptExecution(...unescaped([$1]), $2, $3),
|
|
],
|
|
[Matchers_1.Matchers.PHASE_SUCCESS_MATCHER, ([, $1, $2]) => formatter.formatPhaseSuccess($1, $2)],
|
|
[
|
|
Matchers_1.Matchers.PROCESS_PCH_MATCHER,
|
|
([,
|
|
// pch / gch
|
|
$1,
|
|
// filename
|
|
$2,
|
|
// extra pch
|
|
$3,
|
|
// type
|
|
$4,
|
|
// arch
|
|
$5, $6, $7,]) => formatter.formatFileOperation({
|
|
type: 'ProcessPCH',
|
|
filePath: $1,
|
|
fileName: $2,
|
|
linkType: $4,
|
|
arch: $5,
|
|
target: $6,
|
|
project: $7,
|
|
}),
|
|
],
|
|
[Matchers_1.Matchers.PROCESS_PCH_COMMAND_MATCHER, ([, $1]) => formatter.formatProcessPchCommand($1)],
|
|
[Matchers_1.Matchers.PREPROCESS_MATCHER, ([, $1]) => formatter.formatPreprocess($1)],
|
|
[
|
|
Matchers_1.Matchers.TESTS_RUN_COMPLETION_MATCHER,
|
|
([, $1, , $3]) => formatter.formatTestRunFinished($1, $3),
|
|
],
|
|
[Matchers_1.Matchers.TEST_SUITE_STARTED_MATCHER, ([, $1]) => formatter.formatTestRunStarted($1)],
|
|
[Matchers_1.Matchers.TEST_SUITE_START_MATCHER, ([, $1]) => formatter.formatTestSuiteStarted($1)],
|
|
[Matchers_1.Matchers.TIFFUTIL_MATCHER, ([, $1]) => formatter.formatTiffutil($1)],
|
|
[
|
|
Matchers_1.Matchers.TOUCH_MATCHER,
|
|
([, $1, $2, $3, $4]) => formatter.formatFileOperation({
|
|
type: 'Touch',
|
|
filePath: $1,
|
|
// file name is undefined in newer projects
|
|
fileName: $2 || path_1.basename($1 || ''),
|
|
target: $3,
|
|
project: $4,
|
|
}),
|
|
],
|
|
[Matchers_1.Matchers.WRITE_FILE_MATCHER, ([, $1]) => formatter.formatWriteFile($1)],
|
|
[Matchers_1.Matchers.WRITE_AUXILIARY_FILES, ([$0]) => formatter.formatWriteAuxiliaryFiles($0)],
|
|
[Matchers_1.Matchers.SHELL_COMMAND_MATCHER, ([, $1, $2]) => formatter.formatShellCommand($1, $2)],
|
|
[Matchers_1.Matchers.Warnings.GENERIC_WARNING_MATCHER, ([, $1]) => formatter.formatWarning($1)],
|
|
[
|
|
Matchers_1.Matchers.Warnings.WILL_NOT_BE_CODE_SIGNED_MATCHER,
|
|
([, $1]) => formatter.formatWillNotBeCodeSigned($1),
|
|
],
|
|
[
|
|
Matchers_1.Matchers.Errors.COMPILE_ERROR_MATCHER,
|
|
([, $1, $2, $3, $4, $5]) => {
|
|
return formatter.formatSingleLineCompileIssue('error', $1, $2, $3, $4, $5);
|
|
},
|
|
],
|
|
[
|
|
Matchers_1.Matchers.Warnings.COMPILE_WARNING_INLINE_MATCHER,
|
|
([, $1, $2, $3, $4, $5]) => {
|
|
return formatter.formatSingleLineCompileIssue('warning', $1, $2, $3, $4, $5);
|
|
},
|
|
],
|
|
[null, () => formatter.formatOther(text)],
|
|
]);
|
|
}
|
|
updateTestState(text) {
|
|
return switchRegex_1.switchRegex(text, [
|
|
[
|
|
Matchers_1.Matchers.TEST_SUITE_STARTED_MATCHER,
|
|
() => {
|
|
this.testsDone = false;
|
|
this.formattedSummary = false;
|
|
this.failures = {};
|
|
},
|
|
],
|
|
[
|
|
Matchers_1.Matchers.TEST_CASE_STARTED_MATCHER,
|
|
([, $1, $2]) => {
|
|
this.testSuite = $1;
|
|
this.testCase = $2;
|
|
},
|
|
],
|
|
[
|
|
Matchers_1.Matchers.TESTS_RUN_COMPLETION_MATCHER,
|
|
() => {
|
|
this.testsDone = true;
|
|
},
|
|
],
|
|
[
|
|
Matchers_1.Matchers.FAILING_TEST_MATCHER,
|
|
([, $1, $2, $3, $4]) => this.storeFailure({ file: $1, testSuite: $2, testCase: $3, reason: $4 }),
|
|
],
|
|
[
|
|
Matchers_1.Matchers.UI_FAILING_TEST_MATCHER,
|
|
([, $1, $2]) => this.storeFailure({
|
|
file: $1,
|
|
testSuite: this.testSuite,
|
|
testCase: this.testCase,
|
|
reason: $2,
|
|
}),
|
|
],
|
|
[
|
|
Matchers_1.Matchers.RESTARTING_TESTS_MATCHER,
|
|
() => this.storeFailure({
|
|
file: 'n/a',
|
|
testSuite: this.testSuite,
|
|
testCase: this.testCase,
|
|
reason: 'Test crashed',
|
|
}),
|
|
],
|
|
], true);
|
|
}
|
|
updateErrorState(text) {
|
|
const updateError = ([, $1, $2, $3]) => {
|
|
this.currentIssue.reason = $3;
|
|
this.currentIssue.filePath = $1;
|
|
this.currentIssue.fileName = $2;
|
|
};
|
|
const results = switchRegex_1.switchRegex(text, [
|
|
[
|
|
Matchers_1.Matchers.Errors.COMPILE_ERROR_MATCHER,
|
|
matches => {
|
|
// Prevent matching a one-liner error.
|
|
if (matches === null || matches === void 0 ? void 0 : matches[4]) {
|
|
return 'unmatched';
|
|
}
|
|
this.formattingError = true;
|
|
updateError(matches);
|
|
return null;
|
|
},
|
|
],
|
|
[
|
|
Matchers_1.Matchers.Warnings.COMPILE_WARNING_MATCHER,
|
|
matches => {
|
|
// Prevent matching a one-liner warning.
|
|
if (matches === null || matches === void 0 ? void 0 : matches[4]) {
|
|
return 'unmatched';
|
|
}
|
|
this.formattingWarning = true;
|
|
updateError(matches);
|
|
return null;
|
|
},
|
|
],
|
|
[
|
|
Matchers_1.Matchers.Errors.CURSOR_MATCHER,
|
|
([, $1]) => {
|
|
// is trim === chomp ?
|
|
this.currentIssue.cursor = $1;
|
|
},
|
|
],
|
|
[
|
|
null,
|
|
() => {
|
|
if (this.formattingError || this.formattingWarning) {
|
|
this.currentIssue.line = text;
|
|
}
|
|
return 'unmatched';
|
|
},
|
|
],
|
|
]);
|
|
return results !== 'unmatched';
|
|
}
|
|
updateLinkerFailureState(text) {
|
|
const handleLinkerFail = ([, $1]) => {
|
|
this.linkerFailure.message = $1;
|
|
// Some linker failures can be warnings...
|
|
const messageMatch = this.linkerFailure.message.match(/^(ld: )warning: (.*)/m);
|
|
if (messageMatch && messageMatch[2]) {
|
|
// Format like: `ld: duplicate symbol` to match other ld warnings.
|
|
this.linkerFailure.message = messageMatch[1] + messageMatch[2];
|
|
this.linkerFailure.isWarning = true;
|
|
}
|
|
this.formattingLinkerFailure = true;
|
|
};
|
|
switchRegex_1.switchRegex(text, [
|
|
[Matchers_1.Matchers.Errors.LINKER_UNDEFINED_SYMBOLS_MATCHER, handleLinkerFail],
|
|
[Matchers_1.Matchers.Errors.LINKER_DUPLICATE_SYMBOLS_MATCHER, handleLinkerFail],
|
|
]);
|
|
if (!this.formattingLinkerFailure) {
|
|
return false;
|
|
}
|
|
const results = switchRegex_1.switchRegex(text, [
|
|
[
|
|
Matchers_1.Matchers.Errors.SYMBOL_REFERENCED_FROM_MATCHER,
|
|
([, $1]) => {
|
|
this.linkerFailure.symbol = $1;
|
|
},
|
|
],
|
|
[
|
|
Matchers_1.Matchers.Errors.LINKER_UNDEFINED_SYMBOL_LOCATION_MATCHER,
|
|
() => {
|
|
// TODO: trim === strip ?
|
|
this.linkerFailure.reference = text.trim();
|
|
},
|
|
],
|
|
[
|
|
Matchers_1.Matchers.Errors.LINKER_DUPLICATE_SYMBOLS_LOCATION_MATCHER,
|
|
([, $1]) => {
|
|
// TODO: trim === strip ?
|
|
this.linkerFailure.files.push($1);
|
|
},
|
|
],
|
|
[
|
|
null,
|
|
() => {
|
|
return 'unmatched';
|
|
},
|
|
],
|
|
]);
|
|
return results !== 'unmatched';
|
|
}
|
|
// TODO: clean up the mess around all this
|
|
shouldFormatError() {
|
|
return !!this.formattingError && this.errorOrWarningIsPresent();
|
|
}
|
|
shouldFormatWarning() {
|
|
return this.formattingWarning && this.errorOrWarningIsPresent();
|
|
}
|
|
errorOrWarningIsPresent() {
|
|
var _a, _b, _c;
|
|
return !!((_a = this.currentIssue) === null || _a === void 0 ? void 0 : _a.reason) && !!((_b = this.currentIssue) === null || _b === void 0 ? void 0 : _b.cursor) && !!((_c = this.currentIssue) === null || _c === void 0 ? void 0 : _c.line);
|
|
}
|
|
shouldFormatUndefinedSymbols() {
|
|
var _a, _b, _c;
|
|
return (((_a = this.linkerFailure) === null || _a === void 0 ? void 0 : _a.message) && ((_b = this.linkerFailure) === null || _b === void 0 ? void 0 : _b.symbol) && ((_c = this.linkerFailure) === null || _c === void 0 ? void 0 : _c.reference));
|
|
}
|
|
shouldFormatDuplicateSymbols() {
|
|
var _a, _b, _c;
|
|
return ((_a = this.linkerFailure) === null || _a === void 0 ? void 0 : _a.message) && ((_c = (_b = this.linkerFailure) === null || _b === void 0 ? void 0 : _b.files) === null || _c === void 0 ? void 0 : _c.length) > 1;
|
|
}
|
|
formatCompileError() {
|
|
const error = { ...this.currentIssue };
|
|
this.currentIssue = {};
|
|
this.formattingError = false;
|
|
return this.formatter.formatCompileError(error.fileName, error.filePath, error.reason, error.line, error.cursor);
|
|
}
|
|
formatCompileWarning() {
|
|
const warning = { ...this.currentIssue };
|
|
this.currentIssue = {};
|
|
this.formattingWarning = false;
|
|
return this.formatter.formatCompileWarning(warning.fileName, warning.filePath, warning.reason, warning.line, warning.cursor);
|
|
}
|
|
formatUndefinedSymbols() {
|
|
const result = this.formatter.formatUndefinedSymbols(this.linkerFailure.message, this.linkerFailure.symbol, this.linkerFailure.reference);
|
|
this.resetLinkerFormatState();
|
|
return result;
|
|
}
|
|
formatDuplicateSymbols() {
|
|
const result = this.formatter.formatDuplicateSymbols(this.linkerFailure.message, this.linkerFailure.files, !!this.linkerFailure.isWarning);
|
|
this.resetLinkerFormatState();
|
|
return result;
|
|
}
|
|
resetLinkerFormatState() {
|
|
this.linkerFailure = { files: [] };
|
|
this.formattingLinkerFailure = false;
|
|
}
|
|
storeFailure({ file, testCase, testSuite, reason, }) {
|
|
if (!this.failures) {
|
|
this.failures = {};
|
|
}
|
|
if (!Array.isArray(this.failures[testSuite])) {
|
|
this.failures[testSuite] = [];
|
|
}
|
|
this.failures[testSuite].push({
|
|
filePath: file,
|
|
reason,
|
|
testCase,
|
|
});
|
|
}
|
|
formatSummaryIfNeeded(executedMessage) {
|
|
if (!this.shouldFormatSummary()) {
|
|
return '';
|
|
}
|
|
this.formattedSummary = true;
|
|
return this.formatter.formatTestSummary(executedMessage, this.failures);
|
|
}
|
|
shouldFormatSummary() {
|
|
return !!this.testsDone && !this.formattedSummary;
|
|
}
|
|
}
|
|
exports.Parser = Parser;
|
|
//# sourceMappingURL=Parser.js.map
|