Есть ли способ принудительного использования табуляции вместо пробелов в Java? - PullRequest
14 голосов
/ 15 апреля 2011

CheckStyle предлагает проверять согласованное использование пробелов, но, к сожалению, отсутствует противоположная идея: заставить исходный код использовать вкладки.Есть ли способ добавить эту функциональность?Это не обязательно должен быть CheckStyle, приветствуются и другие инструменты.

То же, что и этот вопрос , но для Java.

РЕДАКТИРОВАТЬ

Мне не нужен beautifier кода, так как нормальным состоянием кодовой базы будут все вкладки.Мне просто нужен инструмент, который может сообщать о наличии альтернативного отступа.Таким образом, я могу настроить новую конфигурацию непрерывной сборки, которая не будет работать при вводе пробелов.

Ответы [ 7 ]

7 голосов
/ 15 апреля 2011

Использование отступов вместо вкладок для отступа является предпочтительным, поскольку оно обеспечивает согласованность макета для всех редакторов / средств просмотра. Но если вы все еще хотите это сделать, вы всегда можете сделать собственную проверку чекстайла или пользовательскую задачу плагина / муравья maven. Логика также не должна быть сложной для реализации - все, что вам нужно, это проверить, больше ли начальный пробел в любой строке, чем длина табуляции.

Редактировать: включая пример муравья. Прошло две недели с тех пор, как вы написали, и вы все еще не счастливы, и у меня было немного свободного времени :) Поэтому я приготовил для тебя небольшое решение для муравья.

Задача Муравья

public class SpaceDetectorTask extends Task {
    public static final String REGEX = "^[ ]+";
    public static final Pattern p = Pattern.compile(REGEX);

    private FileSet fileSet;
    private boolean failOnDetection;

    // Usual getters/setters

    public void addFileSet(FileSet fileSet) {
        this.fileSet = fileSet;
    }

    public void execute() {
        DirectoryScanner ds = fileSet.getDirectoryScanner();
        String[] files = ds.getIncludedFiles();
        for (int x = 0; x <= files.length -1; x++) {
            process(ds.getBasedir(), files[x]);
        }
    }

    public void process(File dir, String file) {
        try {
            BufferedReader reader = new BufferedReader(new FileReader(new File(dir, file)));
            String line;
            int linecount = 0;
            System.out.println("File: " + file);
            boolean ignore = false;
            while((line = reader.readLine()) != null) {
                linecount++;

                // exclude comment blocks
                if (line.contains("/**") || line.contains("*/")) {
                    ignore = !ignore;
                    continue;
                }

                if (!ignore) {
                    if (p.matcher(line).find()) {
                        int spcCount = line.length() - (line.replaceAll(REGEX, "")).length();
                        if (spcCount >= 4) { // break whenever 4 leading spaces are detected. Configure as you need.
                            String msg = "File: "+ file + " is using spaces as indentation.";
                            if (failOnDetection) {
                                throw new BuildException(msg);
                            } else {
                                getProject().log(msg);
                            }
                        }
                    }
                    reader.close();
                }
            }
        } catch (IOException e) {
            if (failOnDetection) {
                throw new BuildException(e);
            } else {
                getProject().log("File: " + file + "\n" + e.getMessage());
            }
        }
    }

In ant build.xml

  1. Сначала скомпилируйте задачу
  2. Объявить это

    <taskdef name="detect-spaces"
             classname="com.blah.blah.build.tools.SpaceDetectorTask">
            <classpath>
                <pathelement path="${dir.classes}"/>
                <fileset dir="C:/apache-ant-1.7.1/lib">
                    <include name="**/*.jar"/>
                </fileset>
            </classpath>
    </taskdef>
    
  3. используйте это

    <target name="rules.spaces">
        <detect-spaces
            failOnDetection="true">
            <fileset dir="${dir.src.java}">
                <include name="**/*.java"/>
            </fileset>
        </detect-spaces>
    </target>
    

Трудно написать и плагин maven / checkstyle.

7 голосов
/ 31 декабря 2013

Хотя Checkstyle не имеет встроенной проверки для этого, вы можете применить отступ только для вкладок, используя проверку RegexpSinglelineJava. Обратите внимание, что проверяется только то, какой символ используется для отступа, а не для правильного уровня отступа.

Бесстыдно похищенный из Hibernate OGM источника :

<module name="RegexpSinglelineJava">
    <property name="format" value="^\t* +\t*\S"/>
    <property name="message" value="Line has leading space characters; indentation should be performed with tabs only."/>
    <property name="ignoreComments" value="true"/>
</module>
4 голосов
/ 23 августа 2012

Этот способ намного проще, чем другие предложенные методы.

Создайте тест Regexp в группе Разное и установите

Формат: ^[ \t]*Сообщение: отступы должны быть вкладкамиНелегальная картина: (проверено)

2 голосов
/ 25 апреля 2011

Найдите начальный пробел с помощью этой команды:

grep -e "^\t* " `find . -name *.java`

Затем переверните состояние выхода.

1 голос
/ 01 мая 2011

Jalopy может быть то, что вы ищете.Некоторое время он не обновлялся, но все равно должен работать.Существует также коммерческая версия, доступная от Triemax .

0 голосов
/ 01 мая 2011

В IntelliJ у меня он выполняет форматирование кода в стандартный формат при регистрации. Таким образом, вы можете иметь пробелы / табуляции при вводе, но код периодически меняется на стандартный формат и всегда корректен в управлении версиями(где он должен быть общим)

Должно быть что-то подобное, что вы можете сделать без IntelliJ, как предварительная проверка в скрипте.

Использование табуляции вместо пробелов было хорошей идеей в 80-х, ноВы действительно думаете, что это имеет значение в 10-х?Это, конечно, не должно быть места на диске!

0 голосов
/ 17 апреля 2011

Наш Java Formatter сделает это напрямую. JavaFormatter prettyprints исходный текст (для некоторого определения prettyprint :-) и отступы логически блокируют фиксированное количество пробелов на вложенный блок (например, indent = 3 [по умолчанию]).

Можно заставить Java Formatter использовать символы табуляции на левом поле для пробела, и он будет использовать табуляцию для перехода к следующему столбцу, который соответствует предоставленной пользователем поставке номеров столбцов табуляции. Если вы определяете табуляцию так, чтобы разделение соответствовало расстоянию между отступами, вы получите один символ табуляции на отступ, просто отформатировав код. Если вы задаете отступ = 8, с табуляцией через каждые 8 ​​столбцов (1, 9, 17, ...) вы, как правило, получаете вкладки, которые работают со многими редакторами, так как интерпретация вкладок по умолчанию - «каждые 8 ​​столбцов».

...