Я унаследовал некоторый код, в котором у автора было отвращение к точкам с запятой. Можно ли исправить все сообщения mlint за один раз (по крайней мере, все с автоматическим исправлением), вместо того, чтобы щелкнуть каждый из них и нажать ALT + ENTER?Есть ли способ исправить все сообщения MintLab mlint сразу?
ответ
ПРИМЕЧАНИЕ: Этот ответ использует функцию 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
должен иметь точку с запятой в конце каждой строки. Если вы хотите, вы можете поместить вышеуказанный код в функцию, чтобы вы могли легко запустить его в каждом файле вашего унаследованного кода.
Если вы замените '-struct' на '-id' в своем вызове mlint, возвращаемая структура содержит дополнительное поле с именем 'id', которое является коротким идентификатором для сообщения mlint. Это может быть проще сопоставить с полным текстом сообщения. Структура также содержит поле под названием «fix», которое равно 0 для всех предупреждений в моем тестовом файле, и я еще не понял, что это такое - он не документирован. –
@ Знак высокой производительности: поле '' fix'' должно быть более новым, поскольку оно не отображается в MATLAB R2009a. – gnovice
да, я бегу 2010a здесь. –
Я знаю, что это старый пост, но я просто нуждался в этом недавно и немного улучшил исходный код, поэтому, если кому-то еще это нужно, он есть. Он ищет недостающие ";" в функциях, а не только в обычных скриптах, поддерживает пробелы в коде и записывает только файлы, которые что-то изменили.
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);
Спасибо, и добро пожаловать в СО. Даже старые вопросы стоит добавить. –
Для того, чтобы решить эту проблему в общем виде для всех доступных действий AUTOFIX, мы должны прибегать к ужасно недокументированным методам Java. Реализация mlint
(и теперь checkcode
) использует mlintmex
(встроенный, а не файл mexfile, как следует из названия), который просто возвращает текст , выводимый из 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
EDIT: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 отмечает в своем комментарии @gnoviceanswer; он кажется равным 1 при наличии исправления 2, когда сообщение является FIX MESSAGE
выше, и 4, когда сообщение является CHANGE MESSAGE
.
Вот быстрая и грязная функция Matlab, которая возвращает строку «fixed», заданную для пути к m-файлу. Нет проверки ошибок и т. Д., И он не сохраняет файл обратно, поскольку я не обещаю, что он сработает. Вы также можете использовать общедоступный (!) API matlab.desktop.editor
, чтобы получить активный документ (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
Удивительный, первый, похоже, именно то, что я искал! У вас не будет возможности проверить его до того, как истечет срок действия, но если кто-то не сможет это сделать, он подходит вам. –
Я добавил оценку Java в ярлык, нашел приятный значок инструмента, и он работает гладко до сих пор. Отличное решение. – Oleg
@OlegKomarov: Остерегайтесь, два изменения на одной линии могут повредить друг другу. Я изменил порядок итераций, который, по-видимому, фиксирует большинство случаев. Более надежным было бы итеративное выполнение mlint и исправление одного сообщения за раз. –
- 1. Есть ли способ слушать тройники питона сразу
- 2. Есть ли способ проверить все переменные контроллера сразу в Rails?
- 3. XmlApplicationContext: Есть ли способ узнать все проблемы с конфигурацией сразу?
- 4. Есть ли способ указать все библиотеки GDCM в CMakeList сразу?
- 5. Есть ли способ выполнить все тесты Modernizr сразу?
- 6. Есть ли способ очистить все таймеры JavaScript сразу?
- 7. Akka сообщения все останавливаются сразу
- 8. Resharper (Найти и) исправить все проблемы сразу
- 9. Есть ли способ исправить функцию «Закрыть все» на Eclipse Kepler?
- 10. Pydev-pylint исправить все ошибки сразу
- 11. Есть ли способ применить изменения темы сразу?
- 12. Есть ли способ исправить ошибку PostScript?
- 13. Есть ли канонический способ «исправить» «динамический» IEnumerable?
- 14. Есть ли способ исправить ширину выпадающего списка?
- 15. Есть ли способ исправить неправильно закодированные строки?
- 16. Есть ли способ исправить фоновое изображение UITableView
- 17. Есть ли способ исправить поставщика, используемого Vagrant?
- 18. Есть ли способ исправить ошибку Ruby Gem?
- 19. Есть ли способ исправить ответ json
- 20. Есть ли способ экспортировать сообщения об ошибках?
- 21. Есть ли способ подавить сообщения TensorFlow?
- 22. Все строки аккордеона, открывающиеся сразу, как исправить?
- 23. Есть ли способ изменить положение сообщения проверки
- 24. Есть ли способ подготовить сообщения тегов git?
- 25. Есть ли способ генерации сообщения из BroadcastReceiver
- 26. Есть ли способ отключить сообщения от zookeeper?
- 27. Есть ли способ воспроизвести сообщения quickFIX/J
- 28. Есть ли способ нажать все закладки на другое репо, все сразу? (Mercurial)
- 29. Есть ли способ отключить кучу элементов формы сразу?
- 30. Выполняет ли NSFetchedResultsController все результаты сразу?
Обратите внимание, что я ценю существующие ответы, но надеюсь найти более общеприменимое решение. –
Недавно они заменили mlint чек-кодом. Вы можете использовать его также. – NKN