From ef67a8107a8f3eb5cfacf7d4e39c7ee757409c12 Mon Sep 17 00:00:00 2001 From: kapitche <142559040+kapitche@users.noreply.github.com> Date: Sat, 5 Jul 2025 17:00:55 -0400 Subject: [PATCH] fix: error cannot read 'charAt' --- .gitignore | 4 +- package.json | 2 +- src/extension.js | 246 ++++++++++++++++++++--------------------------- 3 files changed, 109 insertions(+), 143 deletions(-) diff --git a/.gitignore b/.gitignore index 8dc600d..43d2752 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ node_modules *.vsix /scrapper/discovered_mnemonics.txt -/scrapper/mnemonic_url_mappings.txt \ No newline at end of file +/scrapper/mnemonic_url_mappings.txt +*.s +*.asm \ No newline at end of file diff --git a/package.json b/package.json index ec8f337..0d66c50 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "x86-assembly-syntax", "displayName": "Universal Assembly Syntax Highlighting", "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": { "vscode": "^1.75.0" }, diff --git a/src/extension.js b/src/extension.js index df71fdf..c989b6b 100644 --- a/src/extension.js +++ b/src/extension.js @@ -2,43 +2,41 @@ const vscode = require("vscode"); const fs = require("fs"); const path = require("path"); -let languageConfigDisposable = null; let instructionData = null; function activate(context) { // Load instruction data from local JSON file 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 const hoverProvider = vscode.languages.registerHoverProvider("x86asm", { provideHover(document, position, token) { - const range = document.getWordRangeAtPosition( - position, - /\b[a-zA-Z0-9_]+\b/ - ); - const word = document.getText(range); + try { + const range = document.getWordRangeAtPosition( + position, + /\b[a-zA-Z0-9_]+\b/ + ); - 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); + // Add null check for range to prevent charAt error + if (!range) { + return undefined; } - } - 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", { async provideDefinition(document, position, token) { - const range = document.getWordRangeAtPosition(position); - if (!range) { - return; - } + try { + const range = document.getWordRangeAtPosition(position); + if (!range) { + return; + } - const word = document.getText(range); - return await findDefinition(word); + const word = document.getText(range); + return await findDefinition(word); + } catch (error) { + console.error("Error in definition provider:", error); + return undefined; + } }, } ); - context.subscriptions.push( - hoverProvider, - definitionProvider, - configChangeListener - ); + context.subscriptions.push(hoverProvider, definitionProvider); } 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) { - 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; } - - 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) { - // Get all x86 assembly files in the workspace - const files = await vscode.workspace.findFiles( - "**/*.s", - "**/node_modules/**" - ); + try { + // Get all x86 assembly files in the workspace + const files = await vscode.workspace.findFiles( + "**/*.s", + "**/node_modules/**" + ); - for (const file of files) { - const document = await vscode.workspace.openTextDocument(file); - const text = document.getText(); - const lines = text.split("\n"); + for (const file of files) { + const document = await vscode.workspace.openTextDocument(file); + const text = document.getText(); + const lines = text.split("\n"); - // Check for definitions in each file - const location = searchForDefinition(lines, word, document); - if (location) { - return location; + // Check for definitions in each file + const location = searchForDefinition(lines, word, document); + if (location) { + return location; + } } - } - // If no definition is found, return undefined - return undefined; + // If no definition is found, return undefined + return undefined; + } catch (error) { + console.error("Error in findDefinition:", error); + return undefined; + } } function searchForDefinition(lines, word, document) { - const externRegex = new RegExp(`^extern\\s+${word}\\s*`, "i"); - const globalRegex = new RegExp(`^global\\s+${word}\\s*`, "i"); - const labelRegex = new RegExp(`^${word}:`, "i"); + try { + const externRegex = new RegExp(`^extern\\s+${word}\\s*`, "i"); + const globalRegex = new RegExp(`^global\\s+${word}\\s*`, "i"); + const labelRegex = new RegExp(`^${word}:`, "i"); - for (let i = 0; i < lines.length; i++) { - if ( - externRegex.test(lines[i]) || - globalRegex.test(lines[i]) || - labelRegex.test(lines[i]) - ) { - return new vscode.Location(document.uri, new vscode.Position(i, 0)); + for (let i = 0; i < lines.length; i++) { + if ( + externRegex.test(lines[i]) || + globalRegex.test(lines[i]) || + labelRegex.test(lines[i]) + ) { + 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() { - if (languageConfigDisposable) { - languageConfigDisposable.dispose(); - } + // No cleanup needed } module.exports = {