js-compiler: Clean up suppressions
MODIFY
packages/@romejs/cli-diagnostics/DiagnosticsPrinter.ts
packages/@romejs/cli-diagnostics/DiagnosticsPrinter.ts
@@ -520,16 +520,6 @@ export default class DiagnosticsPrinter extends Error {
filterDiagnostics(): Diagnostics {
const diagnostics = this.getDiagnostics();
-
- if (diagnostics.length === 0) {
- this.reporter.error(
- 'No diagnostics provided. They have likely all been filtered, but this operation does not check for suppressions. Showing complete diagnostics instead.',
- );
- return this.processor.getCompleteUnfilteredDiagnostics(
- this.reporter.markupOptions,
- );
- }
-
const filteredDiagnostics: Diagnostics = [];
for (const diag of diagnostics) {

MODIFY
packages/@romejs/core/common/bridges/WorkerBridge.ts
packages/@romejs/core/common/bridges/WorkerBridge.ts
@@ -12,7 +12,7 @@ import {Program, ConstSourceType} from '@romejs/js-ast';
import {CompileResult, TransformStageName} from '@romejs/js-compiler';
import {Profile} from '@romejs/v8';
import {ProfilingStartData} from './MasterBridge';
-import {PartialDiagnostics, DiagnosticFilters} from '@romejs/diagnostics';
+import {PartialDiagnostics, DiagnosticSuppressions} from '@romejs/diagnostics';
import {ProjectConfigJSON} from '@romejs/project';
import {DiagnosticsError} from '@romejs/diagnostics';
import {Bridge} from '@romejs/events';
@@ -97,7 +97,7 @@ export type WorkerFormatResult = {
export type WorkerLintResult = {
diagnostics: PartialDiagnostics;
- filters: DiagnosticFilters;
+ suppressions: DiagnosticSuppressions;
};
export default class WorkerBridge extends Bridge {

MODIFY
packages/@romejs/core/common/fileHandlers.ts
packages/@romejs/core/common/fileHandlers.ts
@@ -9,7 +9,7 @@ import {ProjectConfig} from '@romejs/project';
import {FileReference} from '@romejs/core';
import {PrefetchedModuleSignatures} from '../common/bridges/WorkerBridge';
import Worker, {ParseResult} from '../worker/Worker';
-import {PartialDiagnostics, DiagnosticFilters} from '@romejs/diagnostics';
+import {PartialDiagnostics, DiagnosticSuppressions} from '@romejs/diagnostics';
import * as compiler from '@romejs/js-compiler';
import {check as typeCheck} from '@romejs/js-analysis';
import {parseJSON, stringifyJSON, consumeJSONExtra} from '@romejs/codec-json';
@@ -86,7 +86,7 @@ export type ExtensionLintResult = {
sourceText: string;
diagnostics: PartialDiagnostics;
formatted: string;
- filters: DiagnosticFilters;
+ suppressions: DiagnosticSuppressions;
};
export type ExtensionHandlerMethodInfo = {
@@ -210,7 +210,7 @@ const jsonHandler: ExtensionHandler = {
return {
sourceText,
diagnostics: [],
- filters: [],
+ suppressions: [],
formatted,
};
},
@@ -315,7 +315,7 @@ function buildJSHandler(
{
formatted: res.getCode(),
sourceText,
- filters: compiler.extractSuppressionsFromProgram(ast),
+ suppressions: compiler.extractSuppressionsFromProgram(ast),
diagnostics: ast.diagnostics,
},
generated,
@@ -365,7 +365,7 @@ function buildJSHandler(
return worker.api.interceptAndAddGeneratedToDiagnostics(
{
- filters: res.filters,
+ suppressions: res.suppressions,
diagnostics,
sourceText,
formatted: res.src,

MODIFY
packages/@romejs/core/master/bundler/BundleRequest.ts
packages/@romejs/core/master/bundler/BundleRequest.ts
@@ -170,13 +170,8 @@ export default class BundleRequest {
this.cached = false;
}
- if (res.diagnostics.length > 0) {
+ this.diagnostics.addSuppressions(res.suppressions);
this.diagnostics.addDiagnostics(res.diagnostics);
- }
-
- if (res.filters.length > 0) {
- this.diagnostics.addFilters(res.filters);
- }
this.compiles.set(source, res);
return res;

MODIFY
packages/@romejs/core/master/commands/compile.ts
packages/@romejs/core/master/commands/compile.ts
@@ -49,10 +49,14 @@ export default createMasterCommand({
res = await req.requestWorkerCompile(resolved.path, 'compile');
}
- const {compiledCode, diagnostics, filters}: WorkerCompileResult = res;
+ const {compiledCode, diagnostics, suppressions}: WorkerCompileResult = res;
if (diagnostics.length > 0) {
- throw new DiagnosticsError('Compile diagnostics', diagnostics, filters);
+ throw new DiagnosticsError(
+ 'Compile diagnostics',
+ diagnostics,
+ suppressions,
+ );
}
reporter.writeAll(compiledCode);

MODIFY
packages/@romejs/core/master/linter/CompilerLinter.ts
packages/@romejs/core/master/linter/CompilerLinter.ts
@@ -73,12 +73,12 @@ export default class CompilerLinter {
}
// TODO support `fix` flag
- const {diagnostics, filters} = await this.request.requestWorkerLint(
- path,
- false,
- );
+ const {
+ diagnostics,
+ suppressions,
+ } = await this.request.requestWorkerLint(path, false);
+ printer.processor.addSuppressions(suppressions);
printer.addDiagnostics(diagnostics);
- printer.processor.addFilters(filters);
spinner.tick();
}

MODIFY
packages/@romejs/core/worker/WorkerAPI.ts
packages/@romejs/core/worker/WorkerAPI.ts
@@ -212,7 +212,7 @@ export default class WorkerAPI {
if (lint === undefined && handler.format === undefined) {
return {
diagnostics: [],
- filters: [],
+ suppressions: [],
};
}
@@ -239,7 +239,7 @@ export default class WorkerAPI {
// These are fatal diagnostics
if (res.diagnostics !== undefined) {
return {
- filters: [],
+ suppressions: [],
diagnostics: res.diagnostics,
};
}
@@ -248,7 +248,7 @@ export default class WorkerAPI {
if (res.value === undefined) {
return {
diagnostics: [],
- filters: [],
+ suppressions: [],
};
}
@@ -257,7 +257,7 @@ export default class WorkerAPI {
formatted,
sourceText: raw,
diagnostics,
- filters,
+ suppressions,
}: ExtensionLintResult = res.value;
// If the file has pending fixes
@@ -276,13 +276,13 @@ export default class WorkerAPI {
if (!needsFix) {
return {
diagnostics,
- filters,
+ suppressions,
};
}
// Add pending autofix diagnostic
return {
- filters,
+ suppressions,
diagnostics: [
...diagnostics,
{

MODIFY
packages/@romejs/diagnostics/DiagnosticsProcessor.ts
packages/@romejs/diagnostics/DiagnosticsProcessor.ts
@@ -11,12 +11,15 @@ import {
PartialDiagnostic,
DiagnosticFilterWithTest,
DiagnosticOrigin,
+ DiagnosticSuppressions,
+ DiagnosticSuppression,
} from './types';
import {MarkupFormatOptions} from '@romejs/string-markup';
import {addOriginsToDiagnostics} from './derive';
import {naturalCompare} from '@romejs/string-utils';
import {DiagnosticsError} from './errors';
import {normalizeDiagnostics} from './normalize';
+import {add} from '@romejs/ob1';
type UniquePart =
| 'filename'
@@ -44,13 +47,13 @@ const DEFAULT_UNIQUE: UniqueRules = [
export default class DiagnosticsProcessor {
constructor(options: CollectorOptions) {
this.diagnostics = [];
- this.filters = options.filters === undefined ? [] : options.filters;
+ this.filters = [];
+ this.suppressions = new Set();
this.options = options;
this.includedKeys = new Set();
this.unique =
options.unique === undefined ? DEFAULT_UNIQUE : options.unique;
this.throwAfter = undefined;
- this.unfilteredDiagnostics = [];
}
static createImmediateThrower(
@@ -67,9 +70,9 @@ export default class DiagnosticsProcessor {
unique: UniqueRules;
includedKeys: Set<string>;
- unfilteredDiagnostics: PartialDiagnostics;
diagnostics: PartialDiagnostics;
filters: Array<DiagnosticFilterWithTest>;
+ suppressions: Set<DiagnosticSuppression>;
options: CollectorOptions;
throwAfter: undefined | number;
@@ -90,6 +93,12 @@ export default class DiagnosticsProcessor {
return this.diagnostics.length > 0;
}
+ addSuppressions(suppressions: DiagnosticSuppressions) {
+ for (const suppression of suppressions) {
+ this.suppressions.add(suppression);
+ }
+ }
+
addFilters(filters: Array<DiagnosticFilterWithTest>) {
this.filters = this.filters.concat(filters);
}
@@ -99,6 +108,19 @@ export default class DiagnosticsProcessor {
}
doesMatchFilter(diag: PartialDiagnostic): boolean {
+ for (const suppression of this.suppressions) {
+ const targetLine = add(suppression.loc.end.line, 1);
+ if (
+ diag.filename !== undefined &&
+ diag.start !== undefined &&
+ diag.filename === suppression.loc.filename &&
+ diag.start.line === targetLine
+ ) {
+ this.suppressions.delete(suppression);
+ return true;
+ }
+ }
+
for (const filter of this.filters) {
if (filter.message !== undefined && filter.message !== diag.message) {
continue;
@@ -185,6 +207,10 @@ export default class DiagnosticsProcessor {
diags: PartialDiagnostics,
origin?: DiagnosticOrigin,
): PartialDiagnostics {
+ if (diags.length === 0) {
+ return diags;
+ }
+
const {max} = this.options;
const added: PartialDiagnostics = [];
@@ -198,8 +224,6 @@ export default class DiagnosticsProcessor {
// Filter diagnostics
diagLoop: for (const diag of diags) {
- this.unfilteredDiagnostics.push(diag);
-
if (max !== undefined && this.diagnostics.length > max) {
break;
}
@@ -237,22 +261,23 @@ export default class DiagnosticsProcessor {
return added;
}
- getUnfilteredDiagnostics(): PartialDiagnostics {
- return [...this.unfilteredDiagnostics];
- }
-
- getCompleteUnfilteredDiagnostics(
- markupOptions: MarkupFormatOptions = {},
- ): Diagnostics {
- return normalizeDiagnostics(this.unfilteredDiagnostics, markupOptions);
+ getPartialDiagnostics(): PartialDiagnostics {
+ const diagnostics: PartialDiagnostics = [...this.diagnostics];
+
+ // Add errors for remaining suppressions
+ for (const suppression of this.suppressions) {
+ diagnostics.push({
+ ...suppression.loc,
+ message: 'Did not hide any error',
+ category: 'suppressions',
+ });
}
- getPartialDiagnostics(): PartialDiagnostics {
- return [...this.diagnostics];
+ return diagnostics;
}
getCompleteDiagnostics(markupOptions: MarkupFormatOptions = {}): Diagnostics {
- return normalizeDiagnostics(this.diagnostics, markupOptions);
+ return normalizeDiagnostics(this.getPartialDiagnostics(), markupOptions);
}
getCompleteSortedDiagnostics(

MODIFY
packages/@romejs/diagnostics/errors.ts
packages/@romejs/diagnostics/errors.ts
@@ -9,13 +9,13 @@ import {PartialDiagnostics, DiagnosticsProcessor} from '@romejs/diagnostics';
import {escapeMarkup} from '@romejs/string-markup';
import {stripAnsi} from '@romejs/string-ansi';
import {printDiagnosticsToString} from '@romejs/cli-diagnostics';
-import {PartialDiagnostic, DiagnosticFilters} from './types';
+import {PartialDiagnostic, DiagnosticSuppressions} from './types';
export class DiagnosticsError extends Error {
constructor(
message: string,
diagnostics: PartialDiagnostics,
- filters: DiagnosticFilters = [],
+ suppressions: DiagnosticSuppressions = [],
) {
if (diagnostics.length === 0) {
throw new Error('No diagnostics');
@@ -33,28 +33,27 @@ export class DiagnosticsError extends Error {
super(escapeMarkup(message));
this.diagnostics = diagnostics;
- this.filters = filters;
+ this.suppressions = suppressions;
this.name = 'DiagnosticsError';
}
diagnostics: PartialDiagnostics;
- filters: DiagnosticFilters;
+ suppressions: DiagnosticSuppressions;
}
export function createSingleDiagnosticError(
diag: PartialDiagnostic,
- filters?: DiagnosticFilters,
+ suppressions?: DiagnosticSuppressions,
): DiagnosticsError {
- return new DiagnosticsError(diag.message, [diag], filters);
+ return new DiagnosticsError(diag.message, [diag], suppressions);
}
export function getDiagnosticsFromError(
err: Error,
): undefined | PartialDiagnostics {
if (err instanceof DiagnosticsError) {
- const processor = new DiagnosticsProcessor({
- filters: err.filters,
- });
+ const processor = new DiagnosticsProcessor({});
+ processor.addSuppressions(err.suppressions);
processor.addDiagnostics(err.diagnostics);
return processor.getPartialDiagnostics();
}

MODIFY
packages/@romejs/diagnostics/types.ts
packages/@romejs/diagnostics/types.ts
@@ -21,6 +21,13 @@ export type DiagnosticFilter = {
export type DiagnosticFilters = Array<DiagnosticFilter>;
+export type DiagnosticSuppression = {
+ category: string;
+ loc: SourceLocation;
+};
+
+export type DiagnosticSuppressions = Array<DiagnosticSuppression>;
+
export type DiagnosticFilterWithTest = DiagnosticFilter & {
test?: (diagnostic: PartialDiagnostic) => boolean;
};

MODIFY
packages/@romejs/js-compiler/__rtests__/__rsnapshots__/suppressions.ts.rsnap
packages/@romejs/js-compiler/__rtests__/__rsnapshots__/suppressions.ts.rsnap
{
- "multiple categories": "Array [\n Object {\n category: 'foo'\n filename: 'unknown'\n line: 2\n }\n Object {\n category: 'bar'\n filename: 'unknown'\n line: 2\n }\n Object {\n category: 'foo'\n filename: 'unknown'\n line: 3\n }\n Object {\n category: 'bar'\n filename: 'unknown'\n line: 3\n }\n Object {\n category: 'foo'\n filename: 'unknown'\n line: 4\n }\n Object {\n category: 'bar'\n filename: 'unknown'\n line: 4\n }\n Object {\n category: 'foo'\n filename: 'unknown'\n line: 5\n }\n Object {\n category: 'bar'\n filename: 'unknown'\n line: 5\n }\n Object {\n category: 'cat'\n filename: 'unknown'\n line: 5\n }\n Object {\n category: 'dog'\n filename: 'unknown'\n line: 5\n }\n]",
- "single category": "Array [\n Object {\n category: 'foo'\n filename: 'unknown'\n line: 2\n }\n Object {\n category: 'foo'\n filename: 'unknown'\n line: 3\n }\n Object {\n category: 'foo'\n filename: 'unknown'\n line: 4\n }\n Object {\n category: 'foo'\n filename: 'unknown'\n line: 5\n }\n]"
+ "multiple categories": "Array [\n Object {\n category: 'foo'\n loc: Object {\n filename: 'unknown'\n end: Object {\n column: 0\n index: 0\n line: 1\n }\n start: Object {\n column: 0\n index: 0\n line: 1\n }\n }\n }\n Object {\n category: 'bar'\n loc: Object {\n filename: 'unknown'\n end: Object {\n column: 0\n index: 0\n line: 1\n }\n start: Object {\n column: 0\n index: 0\n line: 1\n }\n }\n }\n Object {\n category: 'foo'\n loc: Object {\n filename: 'unknown'\n end: Object {\n column: 0\n index: 0\n line: 2\n }\n start: Object {\n column: 0\n index: 0\n line: 2\n }\n }\n }\n Object {\n category: 'bar'\n loc: Object {\n filename: 'unknown'\n end: Object {\n column: 0\n index: 0\n line: 2\n }\n start: Object {\n column: 0\n index: 0\n line: 2\n }\n }\n }\n Object {\n category: 'foo'\n loc: Object {\n filename: 'unknown'\n end: Object {\n column: 0\n index: 0\n line: 3\n }\n start: Object {\n column: 0\n index: 0\n line: 3\n }\n }\n }\n Object {\n category: 'bar'\n loc: Object {\n filename: 'unknown'\n end: Object {\n column: 0\n index: 0\n line: 3\n }\n start: Object {\n column: 0\n index: 0\n line: 3\n }\n }\n }\n Object {\n category: 'foo'\n loc: Object {\n filename: 'unknown'\n end: Object {\n column: 0\n index: 0\n line: 4\n }\n start: Object {\n column: 0\n index: 0\n line: 4\n }\n }\n }\n Object {\n category: 'bar'\n loc: Object {\n filename: 'unknown'\n end: Object {\n column: 0\n index: 0\n line: 4\n }\n start: Object {\n column: 0\n index: 0\n line: 4\n }\n }\n }\n Object {\n category: 'cat'\n loc: Object {\n filename: 'unknown'\n end: Object {\n column: 0\n index: 0\n line: 4\n }\n start: Object {\n column: 0\n index: 0\n line: 4\n }\n }\n }\n Object {\n category: 'dog'\n loc: Object {\n filename: 'unknown'\n end: Object {\n column: 0\n index: 0\n line: 4\n }\n start: Object {\n column: 0\n index: 0\n line: 4\n }\n }\n }\n]",
+ "single category": "Array [\n Object {\n category: 'foo'\n loc: Object {\n filename: 'unknown'\n end: Object {\n column: 0\n index: 0\n line: 1\n }\n start: Object {\n column: 0\n index: 0\n line: 1\n }\n }\n }\n Object {\n category: 'foo'\n loc: Object {\n filename: 'unknown'\n end: Object {\n column: 0\n index: 0\n line: 2\n }\n start: Object {\n column: 0\n index: 0\n line: 2\n }\n }\n }\n Object {\n category: 'foo'\n loc: Object {\n filename: 'unknown'\n end: Object {\n column: 0\n index: 0\n line: 3\n }\n start: Object {\n column: 0\n index: 0\n line: 3\n }\n }\n }\n Object {\n category: 'foo'\n loc: Object {\n filename: 'unknown'\n end: Object {\n column: 0\n index: 0\n line: 4\n }\n start: Object {\n column: 0\n index: 0\n line: 4\n }\n }\n }\n]"
}
\ No newline at end of file

MODIFY
packages/@romejs/js-compiler/api/compile.ts
packages/@romejs/js-compiler/api/compile.ts
*/
import {Mappings} from '@romejs/codec-source-map';
-import {PartialDiagnostics, DiagnosticFilters} from '@romejs/diagnostics';
+import {PartialDiagnostics, DiagnosticSuppressions} from '@romejs/diagnostics';
import {CompileRequest} from '../types';
import {Cache} from '@romejs/js-compiler';
import {generateJS} from '@romejs/js-generator';
@@ -15,7 +15,7 @@ import transform from '../methods/transform';
export type CompileResult = {
mappings: Mappings;
diagnostics: PartialDiagnostics;
- filters: DiagnosticFilters;
+ suppressions: DiagnosticSuppressions;
cacheDependencies: Array<string>;
compiledCode: string;
sourceText: string;
@@ -38,7 +38,7 @@ export default async function compile(
const {
ast: transformedAst,
diagnostics,
- filters,
+ suppressions,
cacheDependencies,
} = await transform(req);
const generator = generateJS(
@@ -58,7 +58,7 @@ export default async function compile(
mappings: generator.getMappings(),
diagnostics: [...ast.diagnostics, ...diagnostics],
cacheDependencies,
- filters,
+ suppressions,
sourceText,
};
compileCache.set(query, res);

MODIFY
packages/@romejs/js-compiler/api/lint.ts
packages/@romejs/js-compiler/api/lint.ts
* LICENSE file in the root directory of this source tree.
*/
-import {PartialDiagnostics, DiagnosticFilters} from '@romejs/diagnostics';
+import {PartialDiagnostics, DiagnosticSuppressions} from '@romejs/diagnostics';
import {TransformRequest} from '../types';
import {lintTransforms} from '../transforms/lint/index';
import {program} from '@romejs/js-ast';
@@ -15,7 +15,7 @@ import {extractSuppressionsFromProgram} from '../suppressions';
export type LintResult = {
diagnostics: PartialDiagnostics;
- filters: DiagnosticFilters;
+ suppressions: DiagnosticSuppressions;
src: string;
};
@@ -27,7 +27,7 @@ export default async function lint(req: TransformRequest): Promise<LintResult> {
if (!project.config.lint.enabled) {
return {
diagnostics: [],
- filters: extractSuppressionsFromProgram(ast),
+ suppressions: extractSuppressionsFromProgram(ast),
src: sourceText,
};
}
@@ -73,7 +73,7 @@ export default async function lint(req: TransformRequest): Promise<LintResult> {
program.assert(context.reduce(ast, lintTransforms, {frozen: true}));
const result: LintResult = {
- filters: extractSuppressionsFromProgram(ast),
+ suppressions: extractSuppressionsFromProgram(ast),
diagnostics: [...ast.diagnostics, ...context.diagnostics],
src: formattedCode,
};

MODIFY
packages/@romejs/js-compiler/methods/transform.ts
packages/@romejs/js-compiler/methods/transform.ts
*/
import {Program} from '@romejs/js-ast';
-import {PartialDiagnostics, DiagnosticFilters} from '@romejs/diagnostics';
+import {PartialDiagnostics, DiagnosticSuppressions} from '@romejs/diagnostics';
import {TransformRequest, TransformVisitors} from '../types';
import {program} from '@romejs/js-ast';
import {stageTransforms, stageOrder, hookVisitors} from '../transforms/index';
@@ -16,7 +16,7 @@ import {extractSuppressionsFromProgram} from '../suppressions';
type TransformResult = {
ast: Program;
- filters: DiagnosticFilters;
+ suppressions: DiagnosticSuppressions;
diagnostics: PartialDiagnostics;
cacheDependencies: Array<string>;
};
@@ -75,7 +75,7 @@ export default async function transform(
const compiledAst = program.assert(context.reduce(ast, visitors));
const res: TransformResult = {
- filters: extractSuppressionsFromProgram(ast),
+ suppressions: extractSuppressionsFromProgram(ast),
diagnostics: [...prevStageDiagnostics, ...context.diagnostics],
cacheDependencies: [
...prevStageCacheDeps,

MODIFY
packages/@romejs/js-compiler/suppressions.ts
packages/@romejs/js-compiler/suppressions.ts
*/
import {Program, AnyComment} from '@romejs/js-ast';
-import {DiagnosticFilters} from '@romejs/diagnostics';
-import {add} from '@romejs/ob1';
+import {DiagnosticSuppressions} from '@romejs/diagnostics';
const SUPPRESSION_START = 'rome-suppress';
-function extractFiltersFromComment(
+function extractSuppressionsFromComment(
comment: AnyComment,
-): undefined | DiagnosticFilters {
+): undefined | DiagnosticSuppressions {
const {loc} = comment;
if (loc === undefined) {
return undefined;
}
- const targetLine = add(loc.end.line, 1);
- const filters: DiagnosticFilters = [];
+ const suppressions: DiagnosticSuppressions = [];
const lines = comment.value.split('\n');
const cleanLines = lines.map(line => {
@@ -39,43 +37,53 @@ function extractFiltersFromComment(
.split(' ');
const cleanCategories = categories.map(category => category.trim());
- for (const category of cleanCategories) {
+ for (let category of cleanCategories) {
if (category === '') {
continue;
}
- filters.push({
- filename: loc.filename,
+ // If a category ends with a colon then all the things that follow it are an explanation
+ let shouldBreak = false;
+ if (category[category.length - 1] === ':') {
+ shouldBreak = true;
+ category = category.slice(-1);
+ }
+
+ suppressions.push({
category,
- line: targetLine,
+ loc,
});
+
+ if (shouldBreak) {
+ break;
+ }
}
}
- if (filters.length === 0) {
+ if (suppressions.length === 0) {
return undefined;
} else {
- return filters;
+ return suppressions;
}
}
export function extractSuppressionsFromComments(
comments: Array<AnyComment>,
-): DiagnosticFilters {
- let filters: DiagnosticFilters = [];
+): DiagnosticSuppressions {
+ let suppressions: DiagnosticSuppressions = [];
for (const comment of comments) {
- const commentFilters = extractFiltersFromComment(comment);
- if (commentFilters !== undefined) {
- filters = filters.concat(commentFilters);
+ const commentSuppressions = extractSuppressionsFromComment(comment);
+ if (commentSuppressions !== undefined) {
+ suppressions = suppressions.concat(commentSuppressions);
}
}
- return filters;
+ return suppressions;
}
export function extractSuppressionsFromProgram(
ast: Program,
-): DiagnosticFilters {
+): DiagnosticSuppressions {
return extractSuppressionsFromComments(ast.comments);
}

js-compiler: Clean up suppressions