Skip to content

Commit

Permalink
Provide suggestions for invalid class references
Browse files Browse the repository at this point in the history
  • Loading branch information
szapp committed May 6, 2024
1 parent 12a35b3 commit 5afb0d7
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 27 deletions.
36 changes: 33 additions & 3 deletions __tests__/write.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ describe('annotations', () => {
{
numSymbols: 4,
namingViolations: [{ name: 'SYMBOL1', file: 'path/to/file1', line: 2 }],
referenceViolations: [{ name: 'SYMBOL2', file: 'path/to/file2', line: 3 }],
referenceViolations: [
{ name: 'SYMBOL2', file: 'path/to/file2', line: 3 },
{ name: 'C_FOCUS', file: 'path/to/file2', line: 5 },
{ name: 'NPC_DEFAULT', file: 'path/to/file2', line: 7 },
],
overwriteViolations: [{ name: 'SYMBOL3', file: 'path/to/file3', line: 4 }],
} as unknown as Parser,
]
Expand Down Expand Up @@ -122,12 +126,38 @@ describe('annotations', () => {
annotation_level: 'failure',
title: 'Reference violation: SYMBOL2',
message:
'The symbol "SYMBOL2" might not exist ("Unknown identifier"). Reference only symbols that are declared in the patch or safely search for other symbols by their name.',
'The symbol "SYMBOL2" might not exist ("Unknown identifier").\nReference only symbols that are declared in the patch or safely search for other symbols by their name.',
raw_details: `if (MEM_FindParserSymbol("SYMBOL2") != -1) {
var zCPar_Symbol symb; symb = _^(MEM_GetSymbol("SYMBOL2"));
// Access content with symb.content
} else {
// Fallback to a default if the symbol does not exist
};`,
},
{
path: 'path/to/file2',
start_line: 5,
end_line: 5,
annotation_level: 'failure',
title: 'Reference violation: C_FOCUS',
message:
'The symbol "C_FOCUS" might not exist ("Unknown identifier").\nAlthough that class is very standard, it technically does not have to exist or might even have a different name!\nIt is safer to define a copy of that class and use that instead to ensure compatibility.',
raw_details: `// Copy of C_FOCUS to ensure it exists
class PATCH_C_FOCUS {
// ...
};`,
},
{
path: 'path/to/file2',
start_line: 7,
end_line: 7,
annotation_level: 'failure',
title: 'Reference violation: NPC_DEFAULT',
message:
'The symbol "NPC_DEFAULT" might not exist ("Unknown identifier").\nAlthough that prototype is very standard, it technically does not have to exist or might even have a different name!\nIt is safer to define a copy of the prototype and use that instead to ensure compatibility.',
raw_details: `// Copy of NPC_DEFAULT to ensure it exists
prototype PATCH_NPC_DEFAULT( /* class name */ ) {
// ...
};`,
},
{
Expand Down Expand Up @@ -157,7 +187,7 @@ describe('annotations', () => {
},
]
const expectedOutput = {
title: '5 violations',
title: '7 violations',
summary,
text:
'The patch validator checked 4 script symbols and 3 resource files.\n\n' +
Expand Down
77 changes: 67 additions & 10 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

80 changes: 67 additions & 13 deletions src/write.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,37 @@ import { formatDuration } from './utils.js'
import { Resource } from './resources.js'
import fs from 'fs'

const commonClasses = [
'C_MISSION',
'C_FOCUS',
'C_ITEMREACT',
'C_SPELL',
'C_SVM',
'C_GILVALUES',
'C_FIGHTAI',
'CCAMSYS',
'C_MENU_ITEM',
'C_MENU',
'C_PARTICLEFXEMITKEY',
'CFX_BASE',
'C_SFX',
'C_SNDSYS_CFG',
'C_MUSICSYS_CFG',
'C_MUSICTHEME',
'C_MUSICJINGLE',
]
const commonPrototypes = [
'NPC_DEFAULT',
'C_SPELL_PROTO',
'CCAMSYS_DEF',
'C_MENU_ITEM_DEF',
'C_MENU_DEF',
'C_MUSICTHEME_DEF',
'C_MUSICJINGLE_DEF',
'C_SFX_DEF',
'CFX_BASE_PROTO',
]

export type Annotation = {
path: string
start_line: number
Expand Down Expand Up @@ -67,23 +98,46 @@ export async function annotations(
})

// Reference violations
const refVio = p.referenceViolations.map(
(v) =>
({
path: v.file,
start_line: v.line,
end_line: v.line,
annotation_level: 'failure',
title: `Reference violation: ${v.name}`,
message: `The symbol "${v.name}" might not exist ("Unknown identifier"). Reference only symbols that are declared in the patch or safely search for other symbols by their name.`,
raw_details: `if (MEM_FindParserSymbol("${v.name}") != -1) {
const refVio = p.referenceViolations.map((v) => {
let raw_details: string
let suggestion: string
if (commonClasses.includes(v.name)) {
// Check for common classes and suggest a fix
suggestion =
'Although that class is very standard, it technically does not have to exist or might even have a different name!\nIt is safer to define a copy of that class and use that instead to ensure compatibility.'
raw_details = `// Copy of ${v.name} to ensure it exists
class ${prefix[0]}_${v.name} {
// ...
};`
} else if (commonPrototypes.includes(v.name)) {
// Check for common protoypes and suggest a fix
suggestion =
'Although that prototype is very standard, it technically does not have to exist or might even have a different name!\nIt is safer to define a copy of the prototype and use that instead to ensure compatibility.'
raw_details = `// Copy of ${v.name} to ensure it exists
prototype ${prefix[0]}_${v.name}( /* class name */ ) {
// ...
};`
} else {
// Give general advice on how to handle unknown identifiers
suggestion = 'Reference only symbols that are declared in the patch or safely search for other symbols by their name.'
raw_details = `if (MEM_FindParserSymbol("${v.name}") != -1) {
var zCPar_Symbol symb; symb = _^(MEM_GetSymbol("${v.name}"));
// Access content with symb.content
} else {
// Fallback to a default if the symbol does not exist
};`,
}) as Annotation
)
};`
}

return {
path: v.file,
start_line: v.line,
end_line: v.line,
annotation_level: 'failure',
title: `Reference violation: ${v.name}`,
message: `The symbol "${v.name}" might not exist ("Unknown identifier").\n${suggestion}`,
raw_details,
} as Annotation
})

// Overwrite violations
const overVio = p.overwriteViolations.map(
Expand Down

0 comments on commit 5afb0d7

Please sign in to comment.