Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(SourceFileReporter): Improve addMessage signature #251

Merged
merged 13 commits into from
Sep 4, 2024
Merged
42 changes: 19 additions & 23 deletions src/linter/linterReporting.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,23 @@
export const MESSAGES = {
SHORT__NO_DIRECT_DATATYPE_ACCESS: "Deprecated access to DataType pseudo module '{0}'",
DETAILS__NO_DIRECT_DATATYPE_ACCESS:
"{@link topic:00737d6c1b864dc3ab72ef56611491c4 Migrating Access to Pseudo Modules}",

SHORT__DEPRECATED_ACCESS_ENUM: "Deprecated access to enum pseudo module '{0}'",
DETAILS__DEPRECATED_ACCESS_ENUM:
"{@link topic:00737d6c1b864dc3ab72ef56611491c4 Migrating Access to Pseudo Modules}",

SHORT__DEPRECATED_PROP_OF_CLASS: "Use of deprecated property '{0}' of class '{1}'",
import type {MESSAGE_INFO} from "./messages.js";

export const MESSAGES = {
// Used by ManifestLinter
SHORT__DEPRECATED_PROP: "Use of deprecated property {0}",

SHORT__DEPRECATED_FUNCTION_ACCESS: "Call to deprecated function {0}",

SHORT__DEPRECATED_API_ACCESS: "Use of deprecated API '{0}'",

SHORT__DEPRECATED_PROP_ACCESS: "Access of deprecated property '{0}'",

SHORT__DEPRECATED_MODULE_IMPORT: "Import of deprecated module '{0}'",

// Used by ManifestLinter
SHORT__DEPRECATED_COMPONENT: "Use of deprecated component '{0}'",

SHORT__GLOBAL_VAR_ACCESS: "Access of global variable '{0}' ({1})",

SHORT__LIB_INIT_2: "Call to {0}() must be declared with property {apiVersion: 2}",
DETAILS__LIB_INIT_2: "{@link sap.ui.core.Lib.init Lib.init}",

// Used by DotLibraryLinter, ManifestLinter, YamlLinter
SHORT__DEPRECATED_LIBRARY: "Use of deprecated library '{0}'",

// Used by ManifestLinter
SHORT__DEPRECATED_MODEL_TYPE: "Use of deprecated model type '{0}'",
};

// TODO: Migrate to enum instead of Object/Map
// Currently, it's done this way to avoid pollution of the test snapshots
export const RULES = {
"ui5-linter-async-component-flags": "ui5-linter-async-component-flags",
"ui5-linter-no-deprecated-api": "ui5-linter-no-deprecated-api",
"ui5-linter-no-partially-deprecated-api": "ui5-linter-no-partially-deprecated-api",
"ui5-linter-no-deprecated-property": "ui5-linter-no-deprecated-property",
Expand All @@ -51,3 +35,15 @@ export function formatMessage(message: string, ...params: string[]) {

return message;
}

export type MessageInfo = typeof MESSAGE_INFO[keyof typeof MESSAGE_INFO] & {fatal?: boolean};

type ExtractArgs<F> = F extends (args: infer P) => unknown ? P : never;
type CombineArgs<M, D> = M & D extends object ? M & D : never;

export type MessageArgs = {
[K in keyof typeof MESSAGE_INFO]:
CombineArgs<
ExtractArgs<typeof MESSAGE_INFO[K]["message"]>, ExtractArgs<typeof MESSAGE_INFO[K]["details"]>
>;
};
148 changes: 148 additions & 0 deletions src/linter/messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import {LintMessageSeverity} from "./LinterContext.js";
import {RULES} from "./linterReporting.js";

export enum MESSAGE {
COMPONENT_MISSING_ASYNC_INTERFACE,
COMPONENT_MISSING_MANIFEST_DECLARATION,
COMPONENT_REDUNDANT_ASYNC_FLAG,
DEPRECATED_API_ACCESS,
DEPRECATED_FUNCTION_CALL,
DEPRECATED_LIBRARY,
DEPRECATED_MODULE_IMPORT,
DEPRECATED_PROPERTY_OF_CLASS,
DEPRECATED_PROPERTY,
LIB_INIT_API_VERSION,
NO_DIRECT_DATATYPE_ACCESS,
NO_DIRECT_ENUM_ACCESS,
NO_GLOBALS,
}
export const MESSAGE_INFO = {

[MESSAGE.COMPONENT_MISSING_ASYNC_INTERFACE]: {
severity: LintMessageSeverity.Error,
ruleId: RULES["ui5-linter-async-component-flags"],

message: () =>
`Component is not configured for asynchronous loading.`,
details: ({componentFileName, asyncFlagMissingIn}: {componentFileName: string; asyncFlagMissingIn: string}) =>
`{@link topic:676b636446c94eada183b1218a824717 Use Asynchronous Loading}. ` +
`Implement sap.ui.core.IAsyncContentCreation interface in ${componentFileName}. ` +
`Alternatively, set the "async" flag to "true" in ${asyncFlagMissingIn} in the component manifest.`,
},

[MESSAGE.COMPONENT_MISSING_MANIFEST_DECLARATION]: {
severity: LintMessageSeverity.Warning,
ruleId: RULES["ui5-linter-async-component-flags"],

message: () =>
`Component does not specify that it uses the descriptor via the manifest.json file`,
details: () =>
`A manifest.json has been found in the same directory as the component. Although it will be used at ` +
`runtime automatically, this should still be expressed in the ` +
`{@link topic:0187ea5e2eff4166b0453b9dcc8fc64f metadata of the component class}.`,
},

[MESSAGE.COMPONENT_REDUNDANT_ASYNC_FLAG]: {
severity: LintMessageSeverity.Warning,
ruleId: RULES["ui5-linter-async-component-flags"],

message: ({asyncFlagLocation}: {asyncFlagLocation: string}) =>
`Component implements the sap.ui.core.IAsyncContentCreation interface. ` +
`The redundant "async" flag at "${asyncFlagLocation}" should be removed from the component manifest`,
details: () =>
`{@link sap.ui.core.IAsyncContentCreation sap.ui.core.IAsyncContentCreation}`,
},

[MESSAGE.DEPRECATED_API_ACCESS]: {
severity: LintMessageSeverity.Error,
ruleId: RULES["ui5-linter-no-deprecated-api"],

message: ({apiName}: {apiName: string}) =>
`Use of deprecated API '${apiName}'`,
details: ({details}: {details: string}) => details,
},

[MESSAGE.DEPRECATED_FUNCTION_CALL]: {
severity: LintMessageSeverity.Error,
ruleId: RULES["ui5-linter-no-deprecated-api"],

message: ({functionName, additionalMessage}: {functionName: string; additionalMessage: string}) =>
`Call to deprecated function '${functionName}'${additionalMessage ? ` ${additionalMessage}` : ""}`,
details: ({details}: {details: string}) => details,
},

[MESSAGE.DEPRECATED_LIBRARY]: {
severity: LintMessageSeverity.Error,
ruleId: RULES["ui5-linter-no-deprecated-library"],

message: ({libraryName}: {libraryName: string}) =>
`Use of deprecated library '${libraryName}'`,
details: () => undefined,
},

[MESSAGE.DEPRECATED_MODULE_IMPORT]: {
severity: LintMessageSeverity.Error,
ruleId: RULES["ui5-linter-no-deprecated-api"],

message: ({moduleName}: {moduleName: string}) =>
`Import of deprecated module '${moduleName}'`,
details: ({details}: {details: string}) => details,
},

[MESSAGE.DEPRECATED_PROPERTY_OF_CLASS]: {
severity: LintMessageSeverity.Error,
ruleId: RULES["ui5-linter-no-deprecated-api"],

message: ({propertyName, className}: {propertyName: string; className: string}) =>
`Use of deprecated property '${propertyName}' of class '${className}'`,
details: ({details}: {details: string}) => details,
},

[MESSAGE.DEPRECATED_PROPERTY]: {
severity: LintMessageSeverity.Error,
ruleId: RULES["ui5-linter-no-deprecated-property"],

message: ({propertyName}: {propertyName: string}) =>
`Use of deprecated property '${propertyName}'`,
details: ({details}: {details: string}) => details,
},

[MESSAGE.LIB_INIT_API_VERSION]: {
severity: LintMessageSeverity.Error,
ruleId: RULES["ui5-linter-no-partially-deprecated-api"],

message: ({libInitFunction}: {libInitFunction: string}) =>
`Call to ${libInitFunction}() must be declared with property {apiVersion: 2}`,
details: () => `{@link sap.ui.core.Lib.init Lib.init}`,
},

[MESSAGE.NO_DIRECT_DATATYPE_ACCESS]: {
severity: LintMessageSeverity.Error,
ruleId: RULES["ui5-linter-no-pseudo-modules"],

message: ({moduleName}: {moduleName: string}) =>
`Deprecated access to DataType pseudo module '${moduleName}'`,
details: () =>
"{@link topic:00737d6c1b864dc3ab72ef56611491c4 Migrating Access to Pseudo Modules}",
},

[MESSAGE.NO_DIRECT_ENUM_ACCESS]: {
severity: LintMessageSeverity.Error,
ruleId: RULES["ui5-linter-no-pseudo-modules"],

message: ({moduleName}: {moduleName: string}) =>
`Deprecated access to enum pseudo module '${moduleName}'`,
details: () =>
"{@link topic:00737d6c1b864dc3ab72ef56611491c4 Migrating Access to Pseudo Modules}",
},

[MESSAGE.NO_GLOBALS]: {
severity: LintMessageSeverity.Error,
ruleId: RULES["ui5-linter-no-globals-js"],

message: ({variableName, namespace}: {variableName: string; namespace: string}) =>
`Access of global variable '${variableName}' (${namespace})`,
details: () => undefined,
},

} as const;
Loading