fix: error cannot read 'charAt'
This commit is contained in:
parent
437bbf0c9d
commit
ef67a8107a
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -1,4 +1,6 @@
|
||||||
node_modules
|
node_modules
|
||||||
*.vsix
|
*.vsix
|
||||||
/scrapper/discovered_mnemonics.txt
|
/scrapper/discovered_mnemonics.txt
|
||||||
/scrapper/mnemonic_url_mappings.txt
|
/scrapper/mnemonic_url_mappings.txt
|
||||||
|
*.s
|
||||||
|
*.asm
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"name": "x86-assembly-syntax",
|
"name": "x86-assembly-syntax",
|
||||||
"displayName": "Universal Assembly Syntax Highlighting",
|
"displayName": "Universal Assembly Syntax Highlighting",
|
||||||
"description": "Syntax highlighting extension for x86, x64 and ARM assembly both for Intel and AT&T syntax",
|
"description": "Syntax highlighting extension for x86, x64 and ARM assembly both for Intel and AT&T syntax",
|
||||||
"version": "1.2.3",
|
"version": "1.2.4",
|
||||||
"engines": {
|
"engines": {
|
||||||
"vscode": "^1.75.0"
|
"vscode": "^1.75.0"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
246
src/extension.js
246
src/extension.js
|
|
@ -2,43 +2,41 @@ const vscode = require("vscode");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
let languageConfigDisposable = null;
|
|
||||||
let instructionData = null;
|
let instructionData = null;
|
||||||
|
|
||||||
function activate(context) {
|
function activate(context) {
|
||||||
// Load instruction data from local JSON file
|
// Load instruction data from local JSON file
|
||||||
loadInstructionData();
|
loadInstructionData();
|
||||||
|
|
||||||
// Set up initial language configuration
|
|
||||||
updateLanguageConfiguration();
|
|
||||||
|
|
||||||
// Listen for configuration changes
|
|
||||||
const configChangeListener = vscode.workspace.onDidChangeConfiguration(
|
|
||||||
(event) => {
|
|
||||||
if (event.affectsConfiguration("assembly.comments")) {
|
|
||||||
updateLanguageConfiguration();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Hover provider for mnemonics
|
// Hover provider for mnemonics
|
||||||
const hoverProvider = vscode.languages.registerHoverProvider("x86asm", {
|
const hoverProvider = vscode.languages.registerHoverProvider("x86asm", {
|
||||||
provideHover(document, position, token) {
|
provideHover(document, position, token) {
|
||||||
const range = document.getWordRangeAtPosition(
|
try {
|
||||||
position,
|
const range = document.getWordRangeAtPosition(
|
||||||
/\b[a-zA-Z0-9_]+\b/
|
position,
|
||||||
);
|
/\b[a-zA-Z0-9_]+\b/
|
||||||
const word = document.getText(range);
|
);
|
||||||
|
|
||||||
if (word && instructionData) {
|
// Add null check for range to prevent charAt error
|
||||||
// Check if the word is a valid mnemonic by looking it up in the instruction data
|
if (!range) {
|
||||||
const instructionInfo = getInstructionInfo(word.toLowerCase());
|
return undefined;
|
||||||
if (instructionInfo) {
|
|
||||||
return new vscode.Hover(instructionInfo);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
const word = document.getText(range);
|
||||||
|
|
||||||
|
if (word && instructionData) {
|
||||||
|
// Check if the word is a valid mnemonic by looking it up in the instruction data
|
||||||
|
const instructionInfo = getInstructionInfo(word.toLowerCase());
|
||||||
|
if (instructionInfo) {
|
||||||
|
return new vscode.Hover(instructionInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error in hover provider:", error);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -47,22 +45,23 @@ function activate(context) {
|
||||||
"x86asm",
|
"x86asm",
|
||||||
{
|
{
|
||||||
async provideDefinition(document, position, token) {
|
async provideDefinition(document, position, token) {
|
||||||
const range = document.getWordRangeAtPosition(position);
|
try {
|
||||||
if (!range) {
|
const range = document.getWordRangeAtPosition(position);
|
||||||
return;
|
if (!range) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const word = document.getText(range);
|
const word = document.getText(range);
|
||||||
return await findDefinition(word);
|
return await findDefinition(word);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error in definition provider:", error);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
context.subscriptions.push(
|
context.subscriptions.push(hoverProvider, definitionProvider);
|
||||||
hoverProvider,
|
|
||||||
definitionProvider,
|
|
||||||
configChangeListener
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadInstructionData() {
|
function loadInstructionData() {
|
||||||
|
|
@ -97,130 +96,95 @@ function loadInstructionData() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateLanguageConfiguration() {
|
|
||||||
// Dispose previous language configuration if it exists
|
|
||||||
if (languageConfigDisposable) {
|
|
||||||
languageConfigDisposable.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get current configuration
|
|
||||||
const config = vscode.workspace.getConfiguration("assembly.comments");
|
|
||||||
const lineComment = config.get("lineComment", ";");
|
|
||||||
const blockComment = config.get("blockComment", ["/*", "*/"]);
|
|
||||||
|
|
||||||
// Register new language configuration
|
|
||||||
languageConfigDisposable = vscode.languages.setLanguageConfiguration(
|
|
||||||
"x86asm",
|
|
||||||
{
|
|
||||||
comments: {
|
|
||||||
lineComment: lineComment,
|
|
||||||
blockComment: blockComment,
|
|
||||||
},
|
|
||||||
brackets: [
|
|
||||||
["{", "}"],
|
|
||||||
["[", "]"],
|
|
||||||
["(", ")"],
|
|
||||||
],
|
|
||||||
autoClosingPairs: [
|
|
||||||
["{", "}"],
|
|
||||||
["[", "]"],
|
|
||||||
["(", ")"],
|
|
||||||
['"', '"'],
|
|
||||||
["'", "'"],
|
|
||||||
],
|
|
||||||
surroundingPairs: [
|
|
||||||
["{", "}"],
|
|
||||||
["[", "]"],
|
|
||||||
["(", ")"],
|
|
||||||
['"', '"'],
|
|
||||||
["'", "'"],
|
|
||||||
],
|
|
||||||
folding: {
|
|
||||||
markers: {
|
|
||||||
start: "\\.section",
|
|
||||||
end: "\\.endsection",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getInstructionInfo(instruction) {
|
function getInstructionInfo(instruction) {
|
||||||
if (!instructionData) {
|
try {
|
||||||
|
if (!instructionData) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const info = instructionData[instruction.toLowerCase()];
|
||||||
|
if (!info) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format the hover content using the syntaxes/x86_instructions.json format
|
||||||
|
// Keep title as is since it usually doesn't need paragraph breaks
|
||||||
|
let hoverContent = `**${info.title || "Unknown Instruction"}**\n\n`;
|
||||||
|
|
||||||
|
if (info.opcode) {
|
||||||
|
hoverContent += `**Opcode:** ${info.opcode}\n\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.description) {
|
||||||
|
// Replace single \n with double \n for proper markdown paragraph breaks
|
||||||
|
const formattedDescription = info.description.replace(/\n/g, "\n\n");
|
||||||
|
hoverContent += `**Description:** ${formattedDescription}\n\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.url) {
|
||||||
|
hoverContent += `[View Documentation](${info.url})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hoverContent;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error in getInstructionInfo:", error);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const info = instructionData[instruction.toLowerCase()];
|
|
||||||
if (!info) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format the hover content using the syntaxes/x86_instructions.json format
|
|
||||||
// Keep title as is since it usually doesn't need paragraph breaks
|
|
||||||
let hoverContent = `**${info.title}**\n\n`;
|
|
||||||
|
|
||||||
if (info.opcode) {
|
|
||||||
hoverContent += `**Opcode:** ${info.opcode}\n\n`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info.description) {
|
|
||||||
// Replace single \n with double \n for proper markdown paragraph breaks
|
|
||||||
const formattedDescription = info.description.replace(/\n/g, "\n\n");
|
|
||||||
hoverContent += `**Description:** ${formattedDescription}\n\n`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info.url) {
|
|
||||||
hoverContent += `[View Documentation](${info.url})`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hoverContent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function findDefinition(word) {
|
async function findDefinition(word) {
|
||||||
// Get all x86 assembly files in the workspace
|
try {
|
||||||
const files = await vscode.workspace.findFiles(
|
// Get all x86 assembly files in the workspace
|
||||||
"**/*.s",
|
const files = await vscode.workspace.findFiles(
|
||||||
"**/node_modules/**"
|
"**/*.s",
|
||||||
);
|
"**/node_modules/**"
|
||||||
|
);
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const document = await vscode.workspace.openTextDocument(file);
|
const document = await vscode.workspace.openTextDocument(file);
|
||||||
const text = document.getText();
|
const text = document.getText();
|
||||||
const lines = text.split("\n");
|
const lines = text.split("\n");
|
||||||
|
|
||||||
// Check for definitions in each file
|
// Check for definitions in each file
|
||||||
const location = searchForDefinition(lines, word, document);
|
const location = searchForDefinition(lines, word, document);
|
||||||
if (location) {
|
if (location) {
|
||||||
return location;
|
return location;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If no definition is found, return undefined
|
// If no definition is found, return undefined
|
||||||
return undefined;
|
return undefined;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error in findDefinition:", error);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function searchForDefinition(lines, word, document) {
|
function searchForDefinition(lines, word, document) {
|
||||||
const externRegex = new RegExp(`^extern\\s+${word}\\s*`, "i");
|
try {
|
||||||
const globalRegex = new RegExp(`^global\\s+${word}\\s*`, "i");
|
const externRegex = new RegExp(`^extern\\s+${word}\\s*`, "i");
|
||||||
const labelRegex = new RegExp(`^${word}:`, "i");
|
const globalRegex = new RegExp(`^global\\s+${word}\\s*`, "i");
|
||||||
|
const labelRegex = new RegExp(`^${word}:`, "i");
|
||||||
|
|
||||||
for (let i = 0; i < lines.length; i++) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
if (
|
if (
|
||||||
externRegex.test(lines[i]) ||
|
externRegex.test(lines[i]) ||
|
||||||
globalRegex.test(lines[i]) ||
|
globalRegex.test(lines[i]) ||
|
||||||
labelRegex.test(lines[i])
|
labelRegex.test(lines[i])
|
||||||
) {
|
) {
|
||||||
return new vscode.Location(document.uri, new vscode.Position(i, 0));
|
return new vscode.Location(document.uri, new vscode.Position(i, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return undefined; // If no match is found
|
return undefined; // If no match is found
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error in searchForDefinition:", error);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function deactivate() {
|
function deactivate() {
|
||||||
if (languageConfigDisposable) {
|
// No cleanup needed
|
||||||
languageConfigDisposable.dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue