Tslint: Правило отступа не сообщает или не исправляет нарушения размера отступа

Созданный на 23 мая 2017  ·  66Комментарии  ·  Источник: palantir/tslint

Сообщение об ошибке

  • __TSLint версия__: 5.3.2
  • __TypeScript version__: 2.3.2
  • __ Запуск TSLint через__: CLI

Линтинг кода TypeScript

export function foo() {
  return 123;
}

с конфигурацией tslint.json :

{
  "extends": ["tslint:latest"],
  "rules": {
    "indent": {
      "options": ["spaces", 4]
    }
  }
}

Фактическое поведение

Нет ошибок с tslint . Никаких исправлений с tslint --fix .

Ожидаемое поведение

Об ошибках сообщалось с помощью tslint , исправления применялись с помощью tslint --fix чтобы полученный файл выглядел так:

export function foo() {
    return 123;
}

2723 работал не совсем так, как я ожидал. Проблема, похоже, заключается в том, что об ошибке сообщается только при использовании неправильного символа пробела, а не при отключенном размере отступа (как в моем примере). соответствующий источник .

Available in ESLint Formatting rule P2 Declined Bug

Самый полезный комментарий

У меня такая же проблема. Приведенное ниже правило будет обнаруживать табуляции, используемые вместо пробелов, но не будет обнаруживать неправильное количество пробелов. Я могу заменить 2 на любое другое, но ошибок все равно не будет. Я использую tslint 5.5.0.

"indent": [true, "spaces", 2],

Все 66 Комментарий

@adidahiya См. этот комментарий @ nchen63.

От @ nchen63 :

Он исправляет табуляции -> x пробелов и x пробелов -> табуляции, но не исправляет x пробелов -> y пробелов

Однако он ДОЛЖЕН делать x spaces to y spaces .

В моем проекте используются как 2, так и 4 пробела. Исправить правило x spaces до y spaces было бы очень полезно.

Я также столкнулся с этой проблемой, ожидая, что она исправит нарушения размера или, по крайней мере, сообщит о них как об ошибках, чтобы я мог их исправить. На данный момент кажется, что конфигурация размера отступа, задокументированная на сайте (https://palantir.github.io/tslint/rules/indent/), на самом деле ничего не делает.

Да, пожалуйста, исправьте эту ошибку. Angular CLI использует 2 пробела для уровня отступа при создании файла или проекта, и все кавычки являются одинарными кавычками. Затем он запускает tslint, чтобы исправить их в соответствии с tslint.json пользователя. Цитаты работают хорошо (трансформируются в двойные кавычки в соответствии с моими предпочтениями), но отступ остается на 2 пробела (в то время как я предпочитаю 4). Tslint сообщает об ошибке только в том случае, если видит фактический символ TAB, но кажется разумным, что он также должен проверить количество пробелов.

Мне кажется, что реализация, используемая в https://github.com/palantir/tslint/blob/master/src/rules/indentRule.ts , довольно наивна, и я бы не ожидал, что она сработает за x spaces -> y spaces . Подход, кажется, подходит для вкладок, исходя из комментария здесь, но я не считаю этот подход жизнеспособным для пробелов.

Скажем, например, была выбрана ширина отступа в 2 пробела, и рассмотрим этот код:

foo = {
    a: {
  b: {
    c: 'c'
  }
    },
    d: 'd'
}

Как наша текущая реализация узнает, что это вообще не удастся? Каждая последовательность пробелов передает регулярное выражение / / . Даже если мы будем искать кратные 2 пробела, это пройдет. Точно так же в сценариях многоуровневого отступа 4 ведущих пробела могут быть проходящим сценарием, тогда как начало одного уровня отступа с 4 пробелами должно завершиться ошибкой.

Я думаю, что любое решение должно проходить через AST, аналогично тому, что делает eslint (https://github.com/eslint/eslint/blob/master/lib/rules/indent.js). Обратной стороной этого будет то, что мы получим небольшое снижение производительности за tabs -> spaces или spaces -> tabs . Мы могли бы обойти это, выбрав реализацию на основе настроек, но я ожидаю, что текущая реализация потерпит неудачу, если используется комбинация табуляции и пробелов, и в этом случае мы должны использовать только решение на основе AST.

Я думаю, что по крайней мере часть работы AST, выполненной в реализации eslint, может быть обработана библиотекой машинописного текста напрямую, так что решение не должно быть слишком сложным для написания.

Как наша текущая реализация узнает, что это вообще не удастся?

Это не требуется _технически_. Правило align не позволит вам писать подобный код. Конечно, мы могли бы пройти AST в правиле indent . Все, что меня волнует, это то, что некоторая комбинация indent и align позволяет мне выполнить то, что я написал в описании проблемы.

Правило align не позволит вам писать подобный код.

Хороший! Я пропустил это, когда изучал исходный код. Я тоже возьму пик там. ТБХ, мне нравится идея использовать существующие правила, чтобы сделать других как можно более наивными.

У меня такая же проблема. Приведенное ниже правило будет обнаруживать табуляции, используемые вместо пробелов, но не будет обнаруживать неправильное количество пробелов. Я могу заменить 2 на любое другое, но ошибок все равно не будет. Я использую tslint 5.5.0.

"indent": [true, "spaces", 2],

Есть обновления по этому поводу? (Если кто-то еще не работает над исправлением, я хочу попробовать.)

@mDibyo дерзай

@mDibyo Добились ли вы в этом прогресса?

У меня частичная реализация. Постараюсь доделать и на выходных устроить пиар

Просто хотел предупредить, что эта проблема стала для меня менее приоритетной, так как я начал использовать более tslint-plugin-prettier для своих проектов. Мы могли бы попытаться добавить больше официальной поддержки prettier во встроенные конфигурации в будущем и, соответственно, настроить фокус на основные правила, не связанные с форматированием.

Prettier, с другой стороны, стремится вместить как можно больше кода в каждую строку.

Что, если ты этого не хочешь?

Если для ширины печати установлено значение 120, более красивое изображение может привести к чрезмерно компактному или иному нежелательному коду.

В наших проектах мы используем 120 символов.


Кроме того, это еще одна зависимость. Я думаю, что предпочел бы просто использовать обычные правила TSLint.

Я думаю, что предпочел бы просто использовать обычные правила TSLint.

@ glen-84 да, это нормально, поэтому я не говорю, что мы должны удалить все правила форматирования из TSLint и полностью делегировать их внешнему форматеру. Prettier, очевидно, самоуверен, и не все захотят его использовать. Этот вопрос все еще открыт для PR.

что происходит с этой проблемой?

мой PR работает, во многих случаях все еще нужно время. @cyberhck

так что мы ожидаем, что вскоре он будет объединен: слегка_smiling_face:

Есть обновления здесь?

Может быть, мы могли бы попросить сопровождающих машинного форматирования предоставить пару API? Пакет уже может проверить, что весь исходный файл отформатирован в

Однако может потребоваться помощь, чтобы хорошо поиграть с установкой фиксатора TSLint.

Проблема, похоже, в том, что об ошибке сообщается только при использовании неправильного символа пробела, а не при отключенном размере отступа.

@adidahiya Я не могу заставить его сообщить об ошибке, если используется неправильный символ отступа. Если я установлю правило на пробелы / 4 и получу что-то вроде:

export function foo() {
return 123;
}

или

export function foo() {
<tab>return 123;
}

Он не сообщает об ошибке. Согласно вашему исходному комментарию, вы уверены, что он сообщает об этом, если это неправильный пробельный символ?

Есть какие-нибудь продвижения по этому поводу? Просто спрашиваю 😝

Совет? Используйте Prettier .

Кто-нибудь пробовал tslint-eslint-rules ?

@jscharett tslint-eslint-rules работает с правилом ter-indent . К сожалению, это не касается отступов JSX ...

Есть надежда на исправление здесь?

Эта ошибка до сих пор не исправлена ​​в версии 5.10.0.

Должен сказать, я не думаю, что TSLint когда-либо сможет форматировать JS-код так же хорошо, как Prettier. Это сложная проблема, и Prettier решил ее лучше, чем кто-либо другой. Я не думаю, что мы должны полагаться в этом на TSLint, тем более, что проекты часто используют оба инструмента в тандеме, и могут возникнуть конфликты ...

РЕДАКТИРОВАТЬ: Чтобы лучше понять, насколько сложна эта проблема, просмотрите этот PR или взгляните на исходный код Prettier. Если эти демонстрации не кажутся вам "сложными", пожалуйста, помогите этому проекту с помощью пиара 😄!

@aervin Я здесь не согласен. На мой взгляд, два проекта преследуют разные цели. Prettier относится к категории форматирования, тогда как TSLint больше соответствует проверке. Да, TSLint может выполнять форматирование для некоторых правил, но его предполагаемые цели в качестве линтера возвращаются к проверке.

Проблема с тем, чтобы полагаться на Prettier, заключается в том, что он самоуверен. Замечательно, согласны ли вы с его стилем, но что, если нет? Раньше все мы использовали JSLint, и все мы жаловались, потому что он был очень самоуверенным. Затем пришли JSHint и JSCS, которые дали нам некоторый контроль. Теперь у нас есть такие мощные инструменты, как @eslint, которые дали нам возможность автоматически подключать и «исправлять» проблемы.

Хотя я уверен, что Prettier - отличный проект, я лично считаю его шагом назад. Он забирает у меня контроль. TSLint не нужно «исправлять» код, если это проблема, просто отметьте это как проблему. Не сомневаюсь, что это сложный вопрос, но eslint решил его. Правило раньше работало; что изменилось, чтобы его сломать?

@jscharett Спасибо за благоприятный ответ. Я согласен с тем, что эти проекты преследуют разные цели или _должны_ иметь. Я считаю, что мы должны ограничить эти проекты этими целями. Оставим Prettier для исправления проблем с отступами, а TSLint оставим предупреждать разработчиков о функциях стрелок, которые можно упростить.

Я также согласен с тем, что Prettier самоуверен. Мне это больше нравится в Prettier. Теперь моей команде не нужно обсуждать, чье мнение по форматированию более разумно. Мы все можем жаловаться на Prettier: смеется:.

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

Правило раньше работало; что изменилось, чтобы его сломать?

Комментарий к открытию проблемы наводит меня на мысль, что это правило никогда не работало так, как предполагалось.

Хотя я уверен, что Prettier - отличный проект, я лично считаю его шагом назад. Он забирает у меня контроль.

По моему опыту, я думал, что меня беспокоит детальный контроль над правилами форматирования вплоть до добавления Prettier ... и вскоре после этого я понял, что меня не столько заботит конкретный способ форматирования, сколько тот факт, что они были отформатированы последовательно. Это огромная когнитивная нагрузка - больше не беспокоиться об этом и полностью сосредоточиться на том, что я хочу, чтобы код выполнял, а не на том, как он выглядит.

tslint уже проверяет другие вещи, которые подпадают под категорию форматирования. Например, принудительное выравнивание, стиль скобок или пробелы между именами переменных и операторами. Кроме того, желательно иметь возможность проверять отступы, не полагаясь на такое самоуверенное решение, как prettier.

Требуется меньше обсуждений и больше пиара. 😉😉

давай @ffxsam

Мой комментарий был в основном насмешливым. Хотя мне интересно, почему этой проблеме больше года, а прогресса нет. Кажется, все просто спорят о линтинге против Prettier.

@ffxsam Потому что есть споры о том, является ли tslint больше частью ts или частью lint

Это верный момент. Похоже, есть некоторое совпадение с TSLint / ESLint. Но факт остается фактом: есть нерабочая опция indent которая не работает уже неизвестно сколько времени. Похоже, что самый быстрый / простой способ для кого-то, знакомого с кодовой базой TSLint, исправить это ...?

Проголосуйте за исправление x spaces => y spaces . Это функция, на которую наша компания очень полагается. Нет смысла просто не исправлять это.

@ffxsam Я слежу за этим выпуском уже почти год, да, это было давно, но, как вы видите, было две PR-попытки, и до сих пор ничего не вышло, я думаю, что это сложнее, чем кажется, но из Конечно, для сопровождающих это может быть проще, просто у меня есть много терпения: little_smiling_face:

Все еще воспроизводится в пустом проекте
https://github.com/dimaShin/tslint-reproduce-2814

Привет @dimaShin , спасибо, что

Мы просто ждем появления этой функции, возможно, с возможностью исправления, но для меня это не проблема. В прошлый раз, когда я проверял, люди использовали prettier для проверки отступов и tslint для всего остального.

Я не говорю, что это подойдет вам, для меня это определенно нет, я также предлагаю использовать .editorconfig для этого конкретного варианта и переключиться на tslint позже, когда проблема будет решена.

Опять же, спасибо, что нашли время добавить больше информации :)

Определимся со стратегией проверки отступов. Для справки, вот стратегия, используемая eslint:

  1. Экземпляр OffsetStorage хранит карту желаемых смещений, где каждый токен имеет заданное смещение от другого указанного токена или до первого столбца.
  2. По мере прохождения AST измените желаемые смещения токенов соответствующим образом. Например, при вводе BlockStatement сместите все токены в BlockStatement на 1 уровень отступа от открывающей фигурной скобки BlockStatement.
  3. После прохождения AST вычислите ожидаемые уровни отступа каждого токена в соответствии с контейнером OffsetStorage.
  4. Для каждой строки сравните ожидаемый отступ первого токена с фактическим отступом в файле и сообщите токен, если два значения не равны.

Эта стратегия основана на синтаксисе, который, судя по предыдущим комментариям, является слишком самоуверенным, поскольку требует, чтобы строки были разбиты определенным образом. Я предлагаю простой способ проверить отступы, не зависящие от того, как код разбит на строки:

  1. Единица отступа определяется в настройках. Для вкладок это один символ табуляции. Для пробелов это два или четыре символа пробела.
  2. Первая непустая строка файла должна иметь нулевые единицы отступа.
  3. Каждая последующая непустая строка должна иметь либо
    а. То же количество единиц отступа, что и в предыдущей непустой строке или
    б. Меньше, чем количество единиц отступа в предыдущей непустой строке или
    c. Ровно на единицу больше, чем количество единиц отступа в предыдущей непустой строке

Некоторые дополнительные вещи для обсуждения:

  • Параметр размера не влияет на вкладки (почему?)
  • Нет причин, по которым параметр размера не может быть положительным целым числом.
  • Автоматическое исправление размера отступа, вероятно, не может быть реализовано без следования синтаксической стратегии.

@stifflerus Также правило должно работать с функцией if / for / arrow без блоков {}

@maximelkin Приведенные вами примеры не имеют отступа во второй строке? Можете ли вы привести пример того, где предложенная стратегия потерпит неудачу?

if(this) that(); //okay because it's all one line

if(this)
  that(); //also okay because the second line is indented

let x = () => f(); //okay because it's all one line

let y = () =>
  f(); // I have not seen any code but like this but it would be okay

Было бы здорово, если бы это было исправлено.

Я не могу поверить, что такая фундаментальная вещь, как соблюдение правил отступов, все еще не работает.

Значит, в 2018 году такой ц-код не проклеить?

const x = {
  a: 1,
   b: 2,
}

Работает для меня
./.eslintrc.ts.js :

module.exports = {
  'parser': 'typescript-eslint-parser',
  'parserOptions': {
    'ecmaVersion': 6,
    'sourceType': 'module',
    'ecmaFeatures': {
      'jsx': true,
    }
  },
  'plugins': [
    'react',
  ],
  'rules': {
    'indent': ['error', 2],
  },
}

yarn eslint --no-eslintrc --config ./.eslintrc.ts.js --ext .tsx src

https://github.com/eslint/typescript-eslint-parser

Решение, которое я нашел для проблемы с отступом в angular, - это добавить красивее с помощью следующих шагов:
npm install --save-dev tslint-plugin-prettier красивее tslint-jasmine-rules
отредактировать tslint.json ->
`" rulesDirectory ": [
"node_modules / codelyzer",
"node_modules / tslint-plugin-prettier",
"node_modules / tslint-jasmine-rules / dist"

],
"extends": "tslint-plugin-prettier",

"правила": {
"красивее": правда,
// добавьте сюда желаемые правила`

и в packege.json добавить ->
"," красивее ": {
"singleQuote": правда,
"printWidth": 140,
"полу": правда,
"bracketSpacing": true,
"arrowParens": "всегда",
"синтаксический анализатор": "машинописный текст"
} "

Это функция, которую почти все используют ежедневно. Буду признателен, если этому вопросу будет уделено больше внимания.

Ребята, вы можете использовать опцию ter-indent, предоставленную tslint-eslint-rules.

"ter-indent": [true, 4, {"SwitchCase": 1}]

У меня это сработало. Ваше здоровье!

@hiteshaleriya это то, что у меня есть в моем проекте уже некоторое время, но на самом деле это не исправляет ошибки, а просто заставляет их замолчать ... вот мой tslint.json :

{
    "extends": "tslint-config-airbnb",
    "rules": {
        "ter-indent": ["error", "spaces", 4],
        "no-unused-vars": ["warn"],
        "no-multi-spaces": false,
        "no-console": false,
        "max-line-length": false,
        "import-name": false
    }
}

и вот соответствующий пример, который завершился без предупреждений или ошибок:

function retrieveAndSetConfig(): Promise<any> {
  return new Promise((resolve, _) => {
  // ^ 2 spaces, expected 4
    const ghe = new GHEUtils();
    // ^ 4 spaces, expected 8
    // ...
}

Он также не показывает ошибок при использовании вкладок (хотя это может быть намеренно, когда присутствуют 4 пробела?).

@SpencerKaiser Не могли бы вы обновить правило ter-indent, как показано ниже, а затем попробовать:

"ter-indent": [true, 4]

Я пробовал ваш пример, и он работает, как ожидалось, с моей стороны (вызывая ошибки).

@hiteshaleriya, спасибо, что так быстро --fix . Любые идеи?

@SpencerKaiser Можете попробовать дважды запустить команду --fix. В первый раз он сделает отступ в первой строке, только затем во второй раз он сделает отступ для остальных (для вашего примера кода). Выглядит странно, но, пожалуйста, сообщите о проблеме, если это не сработает.

@hiteshaleriya, так что пара наблюдений ... Мне не нужно было запускать его снова, мне нужно было запустить его примерно n/4 раз, где n - это длина отступа в пробелах самая дальняя строка в проекте с отступом ¯ \ _ (ツ) _ / ¯

После того, как наконец все они закончились, кажется, что он пропускает основные ошибки отступа, подобные этой:

class Something {
    function myFunc() {
        const myThing = {
            wat: 1,
         wattt: 5,    // 9 spaces, expected 12
        };
    }
}

Если я испортил уровень отступа const (строка 17) до 0 пробелов, остальная часть помечается ошибками _excluding_ строка с пробелом, когда я оставляю --fix :

ERROR: 17:1  ter-indent  Expected indentation of 8 spaces but found 0.
ERROR: 18:1  ter-indent  Expected indentation of 4 spaces but found 12.
ERROR: 20:1  ter-indent  Expected indentation of 0 spaces but found 8.

С --fix вот первый проход:

        const myThing = {
    wat: 1,
         wattt: 5,
};

И второй проход:

        const myThing = {
            wat: 1,
         wattt: 5,
        };

Мысли??

@shubich В итоге я сделал то же самое ...

Есть какие-нибудь обновления по этому поводу?

@MaKCbIMKo, насколько я понимаю, вся команда будет переходить к интеграции eslint visit typescript-eslint, и в ближайшем будущем tslint будет устаревшим, так что пока можно игнорировать это правило (или использовать tslint-config-prettier )

Закрытие в связи со сложностью задачи и сменой направления проекта: # 4534

Правило ESLint из typescript-eslint у меня отлично работает (см. # 4534):

module.exports = {
    "env": {
        "browser": true,
    },
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaVersion": 2019,
        "sourceType": "module",
        "ecmaFeatures": {
            "jsx": true
        },
        "project": "./tsconfig.json",
    },
    "plugins": ["@typescript-eslint"],
    "rules": {
        "@typescript-eslint/indent": ["error", 2] // or ["error", "tab"]
    }
}

🤖 Бип-буп! 👉 TSLint устарел 👈 и вам следует перейти на typescript-eslint ! 🤖

🔒 Эта проблема заблокирована, чтобы предотвратить дальнейшие ненужные обсуждения. Спасибо! 👋

PS tslint-config-prettier - пожалуйста, прекратите использовать _linters_, например TSLint, для _format_ вашего TypeScript. Это лучше , сделано путем _formatter_ таких как похорошела .

Была ли эта страница полезной?
0 / 5 - 0 рейтинги