有没有办法立即修复所有MATLAB mlint消息?

时间:2010-07-14 16:24:01

标签: matlab mlint

我继承了一些作者厌恶分号的代码。是否有可能一次性修复所有mlint消息(至少是所有具有自动修复的消息),而不是必须单击每个消息并按ALT + ENTER?

3 个答案:

答案 0 :(得分:8)

注意: 此答案使用函数MLINT,在较新版本的MATLAB中不再推荐使用该函数。较新的函数CHECKCODE是首选,下面的代码仍然可以通过调用这个较新的函数来简单地替换对MLINT的调用。


我不知道一般的方式可以根据MLINT消息自动修复代码。但是,在特定的情况下,您可以通过自动方式向引发MLINT警告的行添加分号。

首先,让我们从这个示例脚本junk.m开始:

a = 1
b = 2;
c = 'a'
d = [1 2 3]
e = 'hello';

第一行,第三行和第四行将为您提供MLINT警告消息“使用分号终止语句以禁止输出(在脚本中)。”。使用MLINT的函数形式,我们可以在文件中找到发生此警告的行。然后,我们可以从文件中读取所有代码行,在发生警告的行的末尾添加分号,然后将代码行写回文件。这是代码:

%# Find the lines where a given mlint warning occurs:

fileName = 'junk.m';
mlintID = 'NOPTS';                       %# The ID of the warning
mlintData = mlint(fileName,'-id');       %# Run mlint on the file
index = strcmp({mlintData.id},mlintID);  %# Find occurrences of the warnings...
lineNumbers = [mlintData(index).line];   %#   ... and their line numbers

%# Read the lines of code from the file:

fid = fopen(fileName,'rt');
linesOfCode = textscan(fid,'%s','Delimiter',char(10));  %# Read each line
fclose(fid);

%# Modify the lines of code:

linesOfCode = linesOfCode{1};  %# Remove the outer cell array encapsulation
linesOfCode(lineNumbers) = strcat(linesOfCode(lineNumbers),';');  %# Add ';'

%# Write the lines of code back to the file:

fid = fopen(fileName,'wt');
fprintf(fid,'%s\n',linesOfCode{1:end-1});  %# Write all but the last line
fprintf(fid,'%s',linesOfCode{end});        %# Write the last line
fclose(fid);

现在文件junk.m应该在每一行的末尾都有分号。如果需要,可以将上面的代码放在一个函数中,这样就可以在继承代码的每个文件上轻松运行它。

答案 1 :(得分:7)

为了以一般方式解决所有可用的自动修复操作的问题,我们必须采用可怕的未记录的java方法。 mlint(现在checkcode)的实现使用mlintmex(内置;顾名思义不是mexfile),它只返回 text 输出短绒。没有暴露自动修复;偶数行和列号以纯文本形式发出。它似乎与Matlab安装中的mlint二进制文件的输出相同($(matlabroot)/bin/$(arch)/mlint

所以我们必须回到编辑器本身使用的java实现。请注意:此处遵循R2013a完全未记录的代码。

%// Get the java component for the active matlab editor
ed = matlab.desktop.editor.getActive().JavaEditor.getTextComponent();
%// Get the java representation of all mlint messages
msgs = com.mathworks.widgets.text.mcode.MLint.getMessages(ed.getText(),ed.getFilename())

%// Loop through all messages and apply the autofix, if it exits 
%// Iterate backwards to try to prevent changing the location of subsequent
%// fixes... but two nearby fixes could still mess each other up.
for i = msgs.size-1:-1:0
  if msgs.get(i).hasAutoFix()
    com.mathworks.widgets.text.mcode.analyzer.CodeAnalyzerUtils.applyAutoFixes(ed,msgs.get(i).getAutoFixChanges);
  end
end

编辑: AHA!您可以获取mlint二进制文件以返回带有-fix标志的修补程序...这适用于内置{{ 1}},也是!仍然没有记载(据我所知),但可能比上述更强大:

checkcode

分配到结构时,这也会显示@High Performance Mark@gnoviceanswer评论中注意到的新>> checkcode(matlab.desktop.editor.getActiveFilename(),'-fix') L 2 (C 3): Terminate statement with semicolon to suppress output (in functions). (CAN FIX) ----FIX MESSAGE <Add a semicolon.> ----CHANGE MESSAGE L 2 (C 13); L 2 (C 12): <;> L 30 (C 52-53): Input argument 'in' might be unused. If this is OK, consider replacing it by ~. (CAN FIX) ----FIX MESSAGE <Replace name by ~.> ----CHANGE MESSAGE L 30 (C 52); L 30 (C 53): <~> 字段的用途;当有可用的修复时,它似乎为1,当消息为上面的fix时为2,当消息为FIX MESSAGE时为4。

这是一个快速而又脏的Matlab函数,它返回一个给定m文件路径的“固定”字符串。没有错误检查等,它不会保存文件,因为我不保证它会工作。您还可以使用CHANGE MESSAGE public(!)API来获取活动文档(matlab.desktop.editor)并使用getActive属性上的getter和setter来修改文档而不保存它

Text

答案 2 :(得分:6)

我知道这是一个老帖子,但我最近刚需要这个,并且对原始代码有所改进,所以如果有人需要它,那么它就是。它寻找缺少的“;”在函数中,不仅仅是在常规脚本中,在代码中维护空格,只写入有变化的文件。

function [] = add_semicolon(fileName)
%# Find the lines where a given mlint warning occurs:

mlintIDinScript = 'NOPTS';                       %# The ID of the warning
mlintIDinFunction = 'NOPRT';
mlintData = mlint(fileName,'-id');       %# Run mlint on the file
index = strcmp({mlintData.id},mlintIDinScript) | strcmp({mlintData.id},mlintIDinFunction);  %# Find occurrences of the warnings...
lineNumbers = [mlintData(index).line];   %#   ... and their line numbers

if isempty(lineNumbers)
    return;
end;
%# Read the lines of code from the file:

fid = fopen(fileName,'rt');
%linesOfCode = textscan(fid,'%s', 'Whitespace', '\n\r');  %# Read each line
lineNo = 0;
tline = fgetl(fid);
while ischar(tline)
    lineNo = lineNo + 1;
    linesOfCode{lineNo} = tline;
    tline = fgetl(fid);
end
fclose(fid);
%# Modify the lines of code:

%linesOfCode = linesOfCode{1};  %# Remove the outer cell array encapsulation
linesOfCode(lineNumbers) = strcat(linesOfCode(lineNumbers),';');  %# Add ';'

%# Write the lines of code back to the file:

fim = fopen(fileName,'wt');
fprintf(fim,'%s\n',linesOfCode{1:end-1});  %# Write all but the last line
fprintf(fim,'%s',linesOfCode{end});        %# Write the last line
fclose(fim);