Чтобы решить эту проблему в общем виде для всех доступных действий автофикса, мы должны прибегнуть к ужасно недокументированным java-методам. Реализация mlint
(и теперь checkcode
) использует mlintmex
(встроенный; не мексфайл, как следует из названия), который просто возвращает вывод text из linter. Автофиксы не выставляются; четные номера строк и столбцов выводятся в виде простого текста. Кажется, что он совпадает с выводом двоичного файла mlint при установке Matlab ($(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
... и это также относится к встроенному checkcode
! Все еще без документов (насколько я знаю), но, вероятно, гораздо более надежный, чем выше:
>> 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 '* ответ ; Похоже, что это 1, когда доступно исправление, 2, когда сообщение - FIX MESSAGE
выше, и 4, когда сообщение - CHANGE MESSAGE
.
Вот быстрая и грязная функция Matlab, которая возвращает «фиксированную» строку с указанием пути к m-файлу. Нет проверки ошибок и т. Д., И он не сохраняет файл обратно, так как я не обещаю, что он будет работать. Вы также можете использовать matlab.desktop.editor
открытый (!) API для получения активного документа (getActive
) и использовать метод получения и установки в свойстве 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