Clean up, fix lint, typescript errors
MODIFY
packages/@romejs/cli-diagnostics/DiagnosticsPrinter.ts
packages/@romejs/cli-diagnostics/DiagnosticsPrinter.ts
@@ -212,7 +212,7 @@ export default class DiagnosticsPrinter extends Error {
// If focus is enabled, check if we should ignore this message
if (filename !== undefined && start !== undefined && end !== undefined) {
const niceFilename = humanizeMarkupFilename(
- [filename],
+ filename,
this.reporter.markupOptions,
);
const focusId = getDiagnosticHeader({

MODIFY
packages/@romejs/cli-reporter/Reporter.ts
packages/@romejs/cli-reporter/Reporter.ts
@@ -54,7 +54,6 @@ export type ReporterOptions = {
markupOptions?: MarkupFormatOptions;
disabled?: boolean;
verbose?: boolean;
- silent?: boolean;
useRemoteProgressBars?: boolean;
startTime?: number;
wrapperFactory?: WrapperFactory;
@@ -104,6 +103,10 @@ type Stdout =
columns?: number;
};
+function getStreamFormat(stdout: undefined | Stdout): ReporterStream['format'] {
+ return stdout !== undefined && stdout.isTTY === true ? 'ansi' : 'none';
+}
+
export default class Reporter {
constructor(opts: ReporterOptions = {}) {
this.programName = opts.programName === undefined ? 'rome' : opts.programName;
@@ -112,7 +115,6 @@ export default class Reporter {
this.noProgress = process.env.CI === '1';
this.isVerbose = Boolean(opts.verbose);
- this.silent = opts.silent === true;
this.startTime = opts.startTime === undefined ? Date.now() : opts.startTime;
this.hasClearScreen = opts.hasClearScreen === undefined
? true : opts.hasClearScreen;
@@ -153,25 +155,17 @@ export default class Reporter {
static DEFAULT_COLUMNS = 100;
- attachStdoutStreams(
- stdout?: Stdout,
- stderr?: Stdout,
- format?: ReporterStream['format'],
- ): ReporterDerivedStreams {
+ attachStdoutStreams(stdout?: Stdout, stderr?: Stdout): ReporterDerivedStreams {
const columns = stdout === undefined || stdout.columns === undefined
? Reporter.DEFAULT_COLUMNS : stdout.columns;
- if (format === undefined) {
- format = stdout !== undefined && stdout.isTTY === true ? 'ansi' : 'none';
- }
-
const columnsUpdated: Event<number, void> = new Event({
name: 'columnsUpdated',
});
const outStream: ReporterStream = {
type: 'out',
- format,
+ format: getStreamFormat(stdout),
columns,
write(chunk) {
if (stdout !== undefined) {
@@ -183,8 +177,9 @@ export default class Reporter {
};
const errStream: ReporterStream = {
- ...outStream,
type: 'error',
+ format: getStreamFormat(stderr),
+ columns,
write(chunk) {
if (stderr !== undefined) {
stderr.write(chunk);
@@ -238,7 +233,6 @@ export default class Reporter {
markupOptions: MarkupFormatOptions;
isRemote: boolean;
- silent: boolean;
noProgress: boolean;
isVerbose: boolean;
hasSpacer: boolean;
@@ -353,10 +347,6 @@ export default class Reporter {
}
addStream(stream: ReporterStream) {
- if (this.silent) {
- return;
- }
-
this.streams.add(stream);
if (stream.type === 'error' || stream.type === 'all') {

MODIFY
packages/@romejs/core/client/Client.ts
packages/@romejs/core/client/Client.ts
@@ -95,16 +95,19 @@ export default class Client {
this.reporter = new Reporter({
stdin: opts.stdin,
- silent: this.flags.silent === true || opts.stdout === undefined ||
- opts.stderr === undefined,
verbose: this.flags.verbose === true,
markupOptions: {
cwd: this.flags.cwd,
},
});
+ // Suppress stdout when silent is set
+ const isSilent = this.flags.silent === true || opts.stdout === undefined ||
+ opts.stderr === undefined;
+ const stdout = isSilent ? undefined : opts.stdout;
+
this.derivedReporterStreams = this.reporter.attachStdoutStreams(
- opts.stdout,
+ stdout,
opts.stderr,
);
@@ -547,15 +550,6 @@ export default class Client {
return undefined;
}
- async connectToDaemon(): Promise<undefined | MasterBridge> {
- const bridge = await this.tryConnectToExistingDaemon();
- if (bridge !== undefined) {
- return bridge;
- }
-
- return await this.startDaemon();
- }
-
async tryConnectToExistingDaemon(): Promise<undefined | MasterBridge> {
const promise: Promise<undefined | net.Socket> = new Promise((
resolve,

MODIFY
packages/@romejs/core/client/commands.ts
packages/@romejs/core/client/commands.ts
@@ -272,7 +272,7 @@ localCommands.set('lsp', {
const stdin = req.client.reporter.getStdin();
req.client.reporter.teardown();
- const bridge = await req.client.connectToDaemon();
+ const bridge = await req.client.findOrStartMaster();
if (bridge === undefined) {
return false;
}

MODIFY
packages/@romejs/core/master/Master.ts
packages/@romejs/core/master/Master.ts
@@ -437,7 +437,6 @@ export default class Master {
wrapperFactory: this.wrapFatal.bind(this),
streams: [outStream, errStream],
verbose: flags.verbose,
- silent: flags.silent,
markupOptions: {
cwd: flags.cwd,
humanizeFilename: (filename) => {
@@ -473,9 +472,9 @@ export default class Master {
// Add reporter to connected set, important logs may be output to these
if (!flags.silent) {
- this.connectedReporters.addStream(errStream);
this.connectedReporters.addStream(outStream);
}
+ this.connectedReporters.addStream(errStream);
const client: MasterClient = {
id: this.clientIdCounter++,

MODIFY
packages/@romejs/core/master/bundler/Bundler.ts
packages/@romejs/core/master/bundler/Bundler.ts
@@ -156,7 +156,7 @@ export default class Bundler {
progress.setTotal(entries.length);
const silentReporter = this.reporter.fork({
- silent: true,
+ streams: [],
});
const promises: Set<Promise<void>> = new Set();

MODIFY
packages/@romejs/core/master/dependencies/DependencyNode.ts
packages/@romejs/core/master/dependencies/DependencyNode.ts
@@ -297,7 +297,7 @@ export default class DependencyNode {
const localLoc = mod.analyze.topLevelLocalBindings[expectedName];
if (localLoc !== undefined) {
return {
- description: descriptions.BUNDLER.UNKNOWN_EXPORT_POSSIBLE_UNEXPORTED_LOCAL(
+ description: descriptions.RESOLVER.UNKNOWN_EXPORT_POSSIBLE_UNEXPORTED_LOCAL(
expectedName,
fromSource,
localLoc,
@@ -309,7 +309,7 @@ export default class DependencyNode {
}
return {
- description: descriptions.BUNDLER.UNKNOWN_EXPORT(
+ description: descriptions.RESOLVER.UNKNOWN_EXPORT(
expectedName,
fromSource,
Array.from(resolved.node.getExportedNames(kind)),
@@ -342,7 +342,7 @@ export default class DependencyNode {
const {record} = resolved;
return {
- description: descriptions.BUNDLER.IMPORT_TYPE_MISMATCH(
+ description: descriptions.RESOLVER.IMPORT_TYPE_MISMATCH(
name,
node.uid,
kind,

MODIFY
packages/@romejs/core/master/linter/Linter.ts
packages/@romejs/core/master/linter/Linter.ts
@@ -38,16 +38,19 @@ type ProgressFactory = (opts: ReporterProgressOptions) => ReporterProgress;
type WatchEvents = {
onRunStart: () => void;
createProgress: ProgressFactory;
- onChanges: (result: WatchResults, initial: boolean) => void;
+ onChanges: (result: WatchResults, initial: boolean, runner: LintRunner) => void;
};
type WatchResults = {
+ runner: LintRunner;
+ evictedPaths: AbsoluteFilePathSet;
changes: LintWatchChanges;
fixedCount: number;
+ totalCount: number;
};
type LintRunOptions = {
- changedPaths: AbsoluteFilePathSet;
+ evictedPaths: AbsoluteFilePathSet;
processor: DiagnosticsProcessor;
};
@@ -61,14 +64,16 @@ function createDiagnosticsPrinter(
printer.onBeforeFooterPrint((reporter, isError) => {
if (fixedCount > 0) {
- reporter.success(`<number emphasis>${totalCount}</number> files fixed`);
+ reporter.success(
+ `<number emphasis>${fixedCount}</number> <grammarNumber plural="files" singular="file">${fixedCount}</grammarNumber> fixed`,
+ );
}
if (isError) {
let couldFix = false;
let hasPendingFixes = false;
- for (const {description} of printer.processor.getDiagnostics()) {
+ for (const {description} of processor.getDiagnostics()) {
if (description.category === 'lint/pendingFixes') {
hasPendingFixes = true;
}
@@ -90,10 +95,10 @@ function createDiagnosticsPrinter(
} else {
if (totalCount === 0) {
reporter.warn('No files linted');
- } else if (totalCount === 1) {
- reporter.info(`<emphasis>1</emphasis> file linted`);
} else {
- reporter.info(`<number emphasis>${totalCount}</number> files linted`);
+ reporter.info(
+ `<number emphasis>${totalCount}</number> <grammarNumber plural="files" singular="file">${totalCount}</grammarNumber> linted`,
+ );
}
}
});
@@ -136,7 +141,7 @@ class LintRunner {
async runLint(
{
- changedPaths,
+ evictedPaths: changedPaths,
processor,
}: LintRunOptions,
): Promise<{fixedCount: number}> {
@@ -178,7 +183,7 @@ class LintRunner {
async runGraph(
{
- changedPaths,
+ evictedPaths,
processor,
}: LintRunOptions,
): Promise<AbsoluteFilePathSet> {
@@ -187,7 +192,7 @@ class LintRunner {
const validateDependencyPaths: AbsoluteFilePathSet =
new AbsoluteFilePathSet();
- for (const path of changedPaths) {
+ for (const path of evictedPaths) {
validateDependencyPaths.add(path);
// Will be undefined if this is the first time initializing it in the graph
@@ -220,7 +225,7 @@ class LintRunner {
}
computeChanges(
- {changedPaths, processor}: LintRunOptions,
+ {evictedPaths: changedPaths, processor}: LintRunOptions,
validateDependencyPaths: AbsoluteFilePathSet,
): LintWatchChanges {
const {master} = this;
@@ -283,7 +288,13 @@ class LintRunner {
const {fixedCount} = await this.runLint(opts);
const validateDependencyPaths = await this.runGraph(opts);
const changes = await this.computeChanges(opts, validateDependencyPaths);
- return {changes, fixedCount};
+ return {
+ evictedPaths: opts.evictedPaths,
+ changes,
+ fixedCount,
+ totalCount: validateDependencyPaths.size,
+ runner: this,
+ };
}
}
@@ -307,7 +318,10 @@ export default class Linter {
};
}
- createDiagnosticsProcessor(): DiagnosticsProcessor {
+ createDiagnosticsProcessor(
+ evictedPaths: AbsoluteFilePathSet,
+ runner: LintRunner,
+ ): DiagnosticsProcessor {
const processor = new DiagnosticsProcessor({
origins: [
{
@@ -319,6 +333,20 @@ export default class Linter {
processor.addAllowedUnusedSuppressionPrefix('bundler');
+ // Only display files that aren't absolute, are in the changed paths, or have had previous compiler diagnostics
+
+ // This hides errors that have been lint ignored but may have been produced by dependency analysis
+ processor.addFilter({
+ test: (diag) => {
+ const absolute =
+ this.request.master.projectManager.getFilePathFromUidOrAbsolute(
+ diag.location.filename,
+ );
+ return absolute === undefined || evictedPaths.has(absolute) ||
+ runner.compilerDiagnosticsCache.has(absolute);
+ },
+ });
+
return processor;
}
@@ -339,10 +367,10 @@ export default class Linter {
});
return this.request.watchFilesFromArgs(this.getFileArgOptions(), async (
- {paths: changedPaths, projects},
+ {paths: evictedPaths, projects},
initial,
) => {
- const processor = this.createDiagnosticsProcessor();
+ const processor = this.createDiagnosticsProcessor(evictedPaths, runner);
if (fixLocation !== undefined) {
for (const project of projects) {
@@ -355,8 +383,8 @@ export default class Linter {
}
}
- const result = await runner.run({changedPaths, processor});
- events.onChanges(result, initial);
+ const result = await runner.run({evictedPaths, processor});
+ events.onChanges(result, initial, runner);
});
}
@@ -379,11 +407,11 @@ export default class Linter {
return reporter.progress();
},
- onChanges: ({changes, fixedCount}) => {
+ onChanges: ({evictedPaths, changes, totalCount, fixedCount, runner}) => {
printer = createDiagnosticsPrinter(
request,
- this.createDiagnosticsProcessor(),
- changes.length,
+ this.createDiagnosticsProcessor(evictedPaths, runner),
+ totalCount,
fixedCount,
);

MODIFY
packages/@romejs/core/master/project/ProjectManager.ts
packages/@romejs/core/master/project/ProjectManager.ts
@@ -196,7 +196,13 @@ export default class ProjectManager {
return this.uidToFilename.get(uid);
}
- getFilePathFromUidOrAbsolute(uid: string): undefined | AbsoluteFilePath {
+ getFilePathFromUidOrAbsolute(
+ uid: undefined | string,
+ ): undefined | AbsoluteFilePath {
+ if (uid === undefined) {
+ return;
+ }
+
const uidToPath = this.getFilePathFromUid(uid);
if (uidToPath !== undefined) {
return uidToPath;

MODIFY
packages/@romejs/diagnostics/DiagnosticsProcessor.ts
packages/@romejs/diagnostics/DiagnosticsProcessor.ts
@@ -164,7 +164,7 @@ export default class DiagnosticsProcessor {
continue;
}
- if (filter.test !== undefined && !filter.test(diag)) {
+ if (filter.test !== undefined && filter.test(diag)) {
continue;
}

MODIFY
packages/@romejs/diagnostics/categories.ts
packages/@romejs/diagnostics/categories.ts
@@ -14,9 +14,7 @@ export type DiagnosticCategory =
| 'analyzeDependencies/cjsExportInES'
| 'args/fileNotFound'
| 'args/invalid'
- | 'bundler/importTypeMismatch'
| 'bundler/topLevelAwait'
- | 'bundler/unknownExport'
| 'bundler/moduleCycle'
| 'compile/jsx'
| 'compile/classes'
@@ -77,6 +75,8 @@ export type DiagnosticCategory =
| 'resolver/notFound'
| 'resolver/unsupported'
| 'resolver/fetchFailed'
+ | 'resolver/importTypeMismatch'
+ | 'resolver/unknownExport'
| 'suppressions/unused'
| 'suppressions/incorrectPrefix'
| 'suppressions/duplicate'
@@ -110,6 +110,7 @@ export type DiagnosticCategoryPrefix =
| 'lsp'
| 'parse'
| 'projectManager'
+ | 'resolver'
| 'tests'
| 'typeCheck'
| 'v8';

MODIFY
packages/@romejs/diagnostics/descriptions.ts
packages/@romejs/diagnostics/descriptions.ts
@@ -722,7 +722,9 @@ export const descriptions = createMessages({
],
};
},
+ },
+ RESOLVER: {
IMPORT_TYPE_MISMATCH: (
exportName: string,
source: string,
@@ -731,7 +733,7 @@ export const descriptions = createMessages({
exportLoc: undefined | SourceLocation,
) =>
({
- category: 'bundler/importTypeMismatch',
+ category: 'resolver/importTypeMismatch',
message: `The export <emphasis>${exportName}</emphasis> in <filelink emphasis target="${source}" /> was incorrectly imported as a <emphasis>${importedAsKing}</emphasis> when it's actually a <emphasis>${actualKind}</emphasis>`,
advice: exportLoc &&
[
@@ -759,7 +761,7 @@ export const descriptions = createMessages({
) =>
({
message: `Couldn't find export <emphasis>${name}</emphasis> in <filelink emphasis target="${source}" />`,
- category: 'bundler/unknownExport',
+ category: 'resolver/unknownExport',
advice: exportedNames.length === 0 ? [
{
type: 'log',
@@ -796,7 +798,7 @@ export const descriptions = createMessages({
) =>
({
message: markup`Couldn't find export <emphasis>${name}</emphasis> in <filelink emphasis target="${source}" />`,
- category: 'bundler/unknownExport',
+ category: 'resolver/unknownExport',
advice: [
{
type: 'log',

MODIFY
packages/@romejs/string-markup/format.ts
packages/@romejs/string-markup/format.ts
@@ -82,14 +82,13 @@ function formatFileLink(
// Normalize filename
let filename = attributes.get('target') || '';
- let origFilename = filename;
if (opts.normalizeFilename !== undefined) {
filename = opts.normalizeFilename(filename);
}
// Default text to a humanized version of the filename
if (text === '') {
- text = humanizeMarkupFilename([filename, origFilename], opts);
+ text = humanizeMarkupFilename(filename, opts);
const line = attributes.get('line');
if (line !== undefined) {
@@ -114,6 +113,34 @@ function formatApprox(attributes: TagAttributes, value: string) {
}
}
+function formatGrammarNumber(attributes: TagAttributes, value: string) {
+ const num = Number(value);
+
+ const none = attributes.get('none');
+ if (none !== undefined && num === 0) {
+ return none;
+ }
+
+ const singular = attributes.get('singular');
+ if (singular !== undefined && num === 1) {
+ return singular;
+ }
+
+ const plural = attributes.get('plural');
+ if (plural !== undefined) {
+ return plural;
+ }
+
+ return '';
+}
+
+function formatNumber(attributes: TagAttributes, value: string) {
+ const num = Number(value);
+ const human = humanizeNumber(num);
+ const humanWithApprox = formatApprox(attributes, human);
+ return humanWithApprox;
+}
+
export function stripMarkupTags(
input: string,
opts: MarkupFormatOptions = {},
@@ -124,7 +151,10 @@ export function stripMarkupTags(
return formatFileLink(attributes, value, opts).text;
case 'number':
- return formatApprox(attributes, value);
+ return formatNumber(attributes, value);
+
+ case 'grammarNumber':
+ return formatGrammarNumber(attributes, value);
case 'duration':
return formatApprox(attributes, humanizeTime(Number(value), true));
@@ -185,7 +215,10 @@ export function markupToAnsi(
return formatApprox(attributes, humanizeTime(Number(value), true));
case 'number':
- return formatApprox(attributes, humanizeNumber(Number(value)));
+ return formatNumber(attributes, value);
+
+ case 'grammarNumber':
+ return formatGrammarNumber(attributes, value);
case 'italic':
return formatAnsi.italic(value);
@@ -299,26 +332,15 @@ export function markupToAnsi(
}
export function humanizeMarkupFilename(
- filenames: Array<string>,
+ filename: string,
opts: MarkupFormatOptions = {},
): string {
if (opts.humanizeFilename !== undefined) {
- const override = opts.humanizeFilename(filenames[0]);
+ const override = opts.humanizeFilename(filename);
if (override !== undefined) {
return override;
}
}
- if (filenames.length === 0) {
- return 'unknown';
- }
-
- const names: Array<string> = [];
-
- for (const filename of filenames) {
- names.push(createUnknownFilePath(filename).format(opts.cwd));
- }
-
- // Get the shortest name
- return names.sort((a, b) => a.length - b.length)[0];
+ return createUnknownFilePath(filename).format(opts.cwd);
}

MODIFY
packages/@romejs/string-markup/parse.ts
packages/@romejs/string-markup/parse.ts
@@ -27,7 +27,8 @@ const globalAttributes: Array<string> = ['emphasis', 'dim'];
const tags: Map<string, Array<string>> = new Map();
tags.set('emphasis', []);
-tags.set('number', ['approx']);
+tags.set('number', ['approx', 'pluralSuffix', 'singularSuffix']);
+tags.set('grammarNumber', ['plural', 'singular', 'none']);
tags.set('hyperlink', ['target']);
tags.set('filelink', ['target', 'column', 'line']);
tags.set('inverse', []);

MODIFY
packages/@romejs/string-markup/types.ts
packages/@romejs/string-markup/types.ts
@@ -39,6 +39,7 @@ export type ChildNode = TextNode | TagNode;
export type Children = Array<ChildNode>;
export type TagName =
+ | 'grammarNumber'
| 'command'
| 'inverse'
| 'dim'

Clean up, fix lint, typescript errors