代码之家  ›  专栏  ›  技术社区  ›  Richie Cotton Joris Meys

有没有一种方法可以一次修复所有的matlabmlint消息?

  •  11
  • Richie Cotton Joris Meys  · 技术社区  · 15 年前

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

    3 回复  |  直到 15 年前
        1
  •  8
  •   gnovice    13 年前

    注: 此答案使用函数 MLINT ,这在较新版本的MATLAB中不再推荐。更新的函数 CHECKCODE 下面的代码仍然可以工作,只需将对MLINT的调用替换为对这个较新函数的调用。


    一般来说 姆林特 具体的 姆林特 警告。

    junk.m :

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

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

    %# 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);
    

    现在是文件 垃圾。m 每行末尾都应该有分号。如果需要,可以将上述代码放在函数中,以便可以轻松地在继承代码的每个文件上运行它。

        2
  •  7
  •   Community CDub    8 年前

    为了以一种通用的方式解决所有可用的autofix操作的这个问题,我们必须求助于可怕的没有文档的java方法。实施 mlint checkcode )用途 mlintmex 文本 $(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
    

    啊哈! 您可以让mlint二进制文件返回带有 -fix 标记。。。这适用于内置 校验码

    >> 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):   <~>
    

    在分配给结构时,这也揭示了新结构的用途 fix @High Performance Mark @gnovice answer FIX MESSAGE 当消息是 CHANGE MESSAGE .

    matlab.desktop.editor 公共(!)获取活动文档的API( getActive )并在屏幕上使用getter和setter Text

    function str = applyAutoFixes(filepath)
    
    msgs = checkcode(filepath,'-fix');
    
    fid = fopen(filepath,'rt');
    iiLine = 1;
    lines = cell(0);
    line = fgets(fid);
    while ischar(line)
        lines{iiLine} = line;
        iiLine = iiLine+1;
        line = fgets(fid);
    end
    fclose(fid);
    
    pos = [0 cumsum(cellfun('length',lines))];
    str = [lines{:}];
    
    fixes = msgs([msgs.fix] == 4);
    %// Iterate backwards to try to prevent changing the indexing of 'str'
    %// Note that two changes could still conflict with eachother. You could check
    %// for this, or iteratively run mlint and fix one problem at a time.
    for fix = fliplr(fixes(:)')
        %'// fix.column is a 2x2 - not sure what the second column is used for
        change_start = pos(fix.line(1)) + fix.column(1,1);
        change_end   = pos(fix.line(2)) + fix.column(2,1);
    
        if change_start >= change_end
            %// Seems to be an insertion
            str = [str(1:change_start) fix.message str(change_start+1:end)];
        else
            %// Seems to be a replacement
            str = [str(1:change_start-1) fix.message str(change_end+1:end)];
        end
    end
    
        3
  •  6
  •   Vlad    13 年前

    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);
    
    推荐文章