Move into js-compiler, in addLocation return whether this would be marked as a duplicate
DELETE
packages/@romejs/diagnostics/DiagnosticsDuplicateHelper.ts
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
-
-import DiagnosticsProcessor from './DiagnosticsProcessor';
-import {DiagnosticLocation, DiagnosticDescription} from './types';
-import {buildDuplicateLocationAdvice} from './helpers';
-
-type DescriptionFactory = (key: string) => DiagnosticDescription;
-
-export class DiagnosticsDuplicateHelper {
- constructor(
- processor: DiagnosticsProcessor,
- descriptionFactory: DescriptionFactory,
- ) {
- this.processor = processor;
- this.descriptionFactory = descriptionFactory;
- this.locations = new Map();
- }
-
- descriptionFactory: DescriptionFactory;
- locations: Map<string, Array<DiagnosticLocation>>;
- processor: DiagnosticsProcessor;
-
- addLocation(key: string, location: undefined | DiagnosticLocation) {
- if (location === undefined) {
- // This shouldn't really happen. We'll normally be passing in `node.loc` into here
- // which can possibly be `undefined`. We don't want to error though in case it was
- // inserted dynamically as we'd have nowhere to point to.
- return;
- }
-
- let locations = this.locations.get(key);
- if (locations === undefined) {
- locations = [];
- this.locations.set(key, locations);
- }
- locations.push(location);
- }
-
- process() {
- for (const [key, locations] of this.locations) {
- if (locations.length === 1) {
- continue;
- }
-
- const description = this.descriptionFactory(key);
- const firstLocation = locations[0];
- const restLocations = locations.slice(1);
-
- this.processor.addDiagnostic({
- location: firstLocation,
- description: {
- ...description,
- advice: [
- ...(description.advice || []),
- ...buildDuplicateLocationAdvice(restLocations),
- ],
- },
- });
- }
- }
-}

MODIFY
packages/@romejs/js-compiler/lib/Context.ts
packages/@romejs/js-compiler/lib/Context.ts
@@ -24,6 +24,7 @@ import {
DiagnosticSuppressions,
DiagnosticCategory,
DiagnosticsProcessor,
+ DiagnosticLocation,
} from '@romejs/diagnostics';
import Record from './Record';
import {RootScope} from '../scope/Scope';
@@ -108,7 +109,7 @@ export default class Context {
}
hasLocSuppression(
- loc: undefined | SourceLocation,
+ loc: undefined | DiagnosticLocation,
category: DiagnosticCategory,
): boolean {
if (loc === undefined) {
@@ -156,7 +157,7 @@ export default class Context {
}
addLocDiagnostic(
- loc: undefined | SourceLocation,
+ loc: undefined | DiagnosticLocation,
description: DiagnosticDescription,
diag: ContextDiagnostic = {},
): AddDiagnosticResult {

ADD
packages/@romejs/js-compiler/lib/DiagnosticsDuplicateHelper.ts
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import {
+ DiagnosticLocation,
+ DiagnosticDescription,
+ buildDuplicateLocationAdvice,
+ DiagnosticCategory,
+} from '@romejs/diagnostics';
+import Context from './Context';
+
+type DescriptionFactory = (key: string) => DiagnosticDescription;
+
+export class DiagnosticsDuplicateHelper {
+ constructor(context: Context, descriptionFactory: DescriptionFactory) {
+ this.context = context;
+ this.category = descriptionFactory('').category;
+ this.descriptionFactory = descriptionFactory;
+ this.locations = new Map();
+ }
+
+ category: DiagnosticCategory;
+ descriptionFactory: DescriptionFactory;
+ locations: Map<string, Array<DiagnosticLocation>>;
+ context: Context;
+
+ addLocation(
+ key: string,
+ location: undefined | DiagnosticLocation,
+ ): {duplicate: boolean} {
+ let locations = this.locations.get(key);
+ if (locations === undefined) {
+ locations = [];
+ this.locations.set(key, locations);
+ }
+
+ if (location !== undefined) {
+ // We allow passing in `node.loc` which could be undefined, we don't want to point to it
+ // since it would have been injected dynamically
+
+ const isSuppressed = this.context.hasLocSuppression(
+ location,
+ this.category,
+ );
+ if (!isSuppressed) {
+ // If this location has had it's diagnostic suppressed then we don't want to return
+ // that it was a duplicate even if there's multiple occurences
+ return {duplicate: false};
+ }
+
+ locations.push(location);
+ }
+
+ return {duplicate: locations.length > 1};
+ }
+
+ process() {
+ for (const [key, locations] of this.locations) {
+ if (locations.length <= 1) {
+ continue;
+ }
+
+ const description = this.descriptionFactory(key);
+ const firstLocation = locations[0];
+ const restLocations = locations.slice(1);
+
+ this.context.addLocDiagnostic(firstLocation, {
+ ...description,
+ advice: [
+ ...(description.advice || []),
+ ...buildDuplicateLocationAdvice(restLocations),
+ ],
+ });
+ }
+ }
+}

MODIFY
packages/@romejs/js-compiler/transforms/lint/noDuplicateGroupNamesInRegularExpressions.ts
packages/@romejs/js-compiler/transforms/lint/noDuplicateGroupNamesInRegularExpressions.ts
import {AnyNode} from '@romejs/js-ast';
import {Path} from '@romejs/js-compiler';
import {descriptions} from '@romejs/diagnostics';
-import {
- DiagnosticsDuplicateHelper,
-} from '@romejs/diagnostics/DiagnosticsDuplicateHelper';
+import {DiagnosticsDuplicateHelper} from '../../lib/DiagnosticsDuplicateHelper';
export default {
name: 'noDuplicateGroupNamesInRegularExpressions',
@@ -19,7 +17,7 @@ export default {
if (node.type === 'RegExpSubExpression') {
const duplicates = new DiagnosticsDuplicateHelper(
- context.diagnostics,
+ context,
descriptions.LINT.DUPLICATE_REGEX_GROUP_NAME,
);

MODIFY
packages/@romejs/js-compiler/transforms/lint/noDuplicateKeys.ts
packages/@romejs/js-compiler/transforms/lint/noDuplicateKeys.ts
@@ -9,9 +9,7 @@ import {Path} from '@romejs/js-compiler';
import {ObjectProperty, ObjectMethod, SpreadProperty} from '@romejs/js-ast';
import {TransformExitResult} from '@romejs/js-compiler/types';
import {descriptions} from '@romejs/diagnostics';
-import {
- DiagnosticsDuplicateHelper,
-} from '@romejs/diagnostics/DiagnosticsDuplicateHelper';
+import {DiagnosticsDuplicateHelper} from '../../lib/DiagnosticsDuplicateHelper';
function extractPropertyKey(
node: ObjectProperty | ObjectMethod | SpreadProperty,
@@ -42,7 +40,7 @@ export default {
if (node.type === 'ObjectExpression') {
const duplicates = new DiagnosticsDuplicateHelper(
- context.diagnostics,
+ context,
descriptions.LINT.NO_DUPLICATE_KEYS,
);

Move into js-compiler, in addLocation return whether this would be marked as a duplicate