You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VS Code扩展问题:C/C++与汇编代码的对比高亮功能失效

问题根源与修复方案

你的高亮功能失效主要由以下几个核心问题导致,对应的修复方案如下:

1. 行号映射的数据源错误

原代码试图从编译命令的stdout/stderr中提取C/C++行与汇编行的映射,但g++/clang++使用-S参数编译时,并不会将行号关联信息输出到控制台,而是将这些信息以注释形式(如# line 5 "test.c")写入生成的.s文件中。因此需要从生成的汇编文件本身提取映射关系。

2. 行号的索引不匹配

VSCode的文档行号是0-based(从0开始计数),而编译器输出的行号是1-based(从1开始计数),原代码没有做转换,导致映射关系错位。

3. 映射表未重置

每次执行生成汇编命令时,mapping对象没有被清空,多次生成后会残留旧的映射数据,导致高亮错误。

4. 高亮残留问题

每次hover时没有清除之前的高亮装饰,导致旧的高亮不会消失,影响体验。

修复后的完整代码

const { exec } = require("child_process");
const vscode = require("vscode");
const path = require('path');

function activate(context) {
  let decorationType = vscode.window.createTextEditorDecorationType({
    backgroundColor: 'rgba(200, 200, 200, 0.5)'
  });

  // 存储当前生成的汇编文档URI,确保只对当前生成的文件高亮
  let currentAssemblyUri = null;
  let mapping = {};

  // 清除现有高亮
  function clearHighlights(editor) {
    if (editor) {
      editor.setDecorations(decorationType, []);
    }
  }

  // Register the hover provider
  vscode.languages.registerHoverProvider(['c', 'cpp'], {
    provideHover(document, position) {
      // 先清除之前的高亮
      const assemblerEditor = vscode.window.visibleTextEditors.find(e => 
        e.document.uri.toString() === currentAssemblyUri?.toString()
      );
      clearHighlights(assemblerEditor);

      // 转换为1-based行号查找映射
      let cLineNum1Based = position.line + 1;
      let assemblerLineNum0Based = mapping[cLineNum1Based];
      if (assemblerEditor && assemblerLineNum0Based !== undefined) {
        assemblerEditor.setDecorations(decorationType, [
          new vscode.Range(assemblerLineNum0Based, 0, assemblerLineNum0Based, Number.MAX_SAFE_INTEGER)
        ]);
      }
    }
  });

  // Register the command that generates the assembly code and opens it
  let disposable = vscode.commands.registerCommand(
    "extension.showAssembly",
    function () {
      let editor = vscode.window.activeTextEditor;
      if (!editor) {
        return;
      }

      // 重置映射表和当前汇编文件标记
      mapping = {};
      currentAssemblyUri = null;

      // Choice compiler
      let config = vscode.workspace.getConfiguration();
      let compiler = config.get("cvass.compiler.choice");
      let currentFilePath = editor.document.uri.fsPath;
      let dirPath = path.dirname(currentFilePath);
      let oFile = path.join(dirPath, 'output.s');
      let iFile = currentFilePath;

      exec(`${compiler} -S -o "${oFile}" "${iFile}"`, (error, stdout, stderr) => {
        if (error) {
          vscode.window.showErrorMessage(error.message || JSON.stringify(error));
          return;
        }

        // 从生成的汇编文件中提取行号映射
        vscode.workspace.openTextDocument(oFile).then(doc => {
          const lines = doc.getText().split('\n');
          lines.forEach((line, asmLineIndex) => {
            // 匹配类似 # line 5 "test.c" 的行
            const match = line.match(/^#\s*line\s*(\d+)\s*"([^"]+)"/);
            if (match && match[2] === path.basename(currentFilePath)) {
              const cLineNum1Based = parseInt(match[1]);
              // 存储0-based的汇编行号
              mapping[cLineNum1Based] = asmLineIndex;
            }
          });

          currentAssemblyUri = doc.uri;
          vscode.window.showTextDocument(doc, vscode.ViewColumn.Beside, true);
        });
      });
    });

  context.subscriptions.push(disposable);
}

exports.activate = activate;

function deactivate() { }

module.exports = {
  activate,
  deactivate
};

额外优化说明

  • 添加了currentAssemblyUri变量,确保只对当前生成的汇编文件进行高亮,避免干扰其他打开的汇编文档。
  • 新增clearHighlights函数,每次hover时先清除之前的高亮,保证界面整洁。
  • 错误提示优化,使用error.message显示更友好的编译错误信息。

内容的提问来源于stack exchange,提问作者mikheeffff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 15:00:46