Tslint: Regra de recuo não reportando ou corrigindo violações de tamanho de recuo

Criado em 23 mai. 2017  ·  66Comentários  ·  Fonte: palantir/tslint

Relatório de erro

  • __TSLint version__: 5.3.2
  • __TypeScript version__: 2.3.2
  • __ Executando TSLint via__: CLI

Código TypeScript sendo vinculado

export function foo() {
  return 123;
}

com configuração tslint.json :

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

Comportamento real

Sem erros com tslint . Nenhuma correção com tslint --fix .

Comportamento esperado

Erros relatados com tslint , correções aplicadas com tslint --fix para que o arquivo resultante se pareça com:

export function foo() {
    return 123;
}

2723 não funcionou exatamente como eu esperava. O problema parece ser que uma falha só é relatada se usar o caractere de espaço em branco errado, não se o tamanho do recuo estiver desativado (como no meu exemplo). fonte relevante .

Available in ESLint Formatting rule P2 Declined Bug

Comentários muito úteis

Estou tendo o mesmo problema. A regra a seguir detectará tabulações sendo usadas em vez de espaços, mas não detectará um número incorreto de espaços. Posso alterar 2 para qualquer outro número e ainda não recebo erros. Estou usando o tslint 5.5.0.

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

Todos 66 comentários

@adidahiya Veja este comentário de @ nchen63.

De @ nchen63 :

Ele corrige tabulações -> espaços x e espaços x -> tabulações, mas não corrige espaços x -> espaços y

Ele DEVE fazer x spaces a y spaces embora.

Meu projeto usa 2 e 4 espaços. Corrigir a regra x spaces para y spaces seria muito útil.

Também encontrei esse problema esperando corrigir as violações de tamanho ou, pelo menos, relatá-los como erros para que eu possa corrigi-los. No momento, parece que a configuração do tamanho do indent documentado no site (https://palantir.github.io/tslint/rules/indent/) na verdade não faz nada.

Sim, por favor, corrija este bug. O Angular CLI usa 2 espaços para um nível de indentação ao gerar um arquivo ou projeto, e todas as aspas são aspas simples. Em seguida, ele executa o tslint para corrigi-los de acordo com o tslint.json do usuário. As citações funcionam bem (transformando em aspas duplas conforme minha preferência), mas o recuo fica em 2 espaços (enquanto eu prefiro 4). O Tslint só relata um erro se ele vê um caractere TAB real, mas parece razoável que ele também deve verificar o número de espaços

Parece-me que a implementação usada em https://github.com/palantir/tslint/blob/master/src/rules/indentRule.ts é bastante ingênua e não esperaria que funcionasse por x spaces -> y spaces . A abordagem parece ser boa com guias, com base no comentário aqui, mas não consigo ver essa abordagem como viável para espaços.

Digamos, por exemplo, que foi escolhida uma largura de indentação de 2 espaços e considere este código:

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

Como nossa implementação atual poderia falhar nisso? Cada sequência de espaços passa pela regex / / . Mesmo se procurássemos múltiplos de 2 espaços, isso passaria. Da mesma forma, em cenários de recuo de vários níveis, 4 espaços iniciais podem ser um cenário de passagem, enquanto iniciar um único nível de recuo com 4 espaços deve falhar.

Acho que qualquer solução precisaria atravessar o AST, semelhante ao que eslint faz (https://github.com/eslint/eslint/blob/master/lib/rules/indent.js). A desvantagem disso seria que receberíamos um leve impacto no desempenho de tabs -> spaces ou spaces -> tabs . Poderíamos contornar isso escolhendo a implementação com base nas configurações, mas prevejo que a implementação atual falhará se uma combinação de tabulações e espaços for usada, caso em que devemos usar apenas a solução baseada em AST.

Acho que pelo menos parte do trabalho AST feito na implementação do eslint pode ser tratado diretamente pela biblioteca do typescript, então a solução não deve ser muito difícil de escrever.

Como nossa implementação atual poderia falhar nisso?

Não é _tecnicamente_ necessário. A regra align impediria você de escrever um código assim. Claro, poderíamos seguir o AST na regra indent também. Tudo o que me importa é que alguma combinação de indent e align me permita realizar o que escrevi na descrição do problema.

A regra de alinhamento impediria você de escrever um código como esse.

Bom! Perdi isso quando estava examinando o código-fonte. Vou dar uma olhada lá também. TBH, eu meio que gosto da ideia de aproveitar as regras existentes para manter os outros tão ingênuos quanto possível.

Estou tendo o mesmo problema. A regra a seguir detectará tabulações sendo usadas em vez de espaços, mas não detectará um número incorreto de espaços. Posso alterar 2 para qualquer outro número e ainda não recebo erros. Estou usando o tslint 5.5.0.

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

Alguma atualização sobre isso? (Se alguém ainda não está trabalhando em uma correção, estou disposto a tentar.)

@mDibyo vá em frente

@mDibyo Você fez algum progresso nisso?

Eu tenho uma implementação parcial. Vou tentar concluí-lo e fazer uma RP no fim de semana

Só queria avisar que esse problema se tornou uma prioridade menor para mim desde que comecei a usar uma formatação mais bonita com tslint-plugin-mais bonita para meus projetos. Podemos tentar adicionar mais suporte oficial para mais bonito nas configurações integradas no futuro e, de forma correspondente, ajustar o foco às regras básicas que não estão relacionadas à formatação.

A Prettier, por outro lado, se esforça para encaixar o máximo de código em cada linha.

E se você não quiser isso?

Com a largura de impressão definida para 120, mais bonita pode produzir códigos excessivamente compactos ou indesejáveis.

Usamos 120 caracteres em nossos projetos.


Além disso, é mais uma dependência. Acho que prefiro usar apenas as regras regulares do TSLint.

Acho que prefiro usar apenas as regras regulares do TSLint.

@ glen-84 sim, tudo bem, é por isso que não estou dizendo que devemos remover todas as regras de formatação do TSLint e delegar completamente a um formatador externo. Mais bonito é obviamente opinativo e nem todo mundo vai escolher usá-lo. Esta edição ainda está aberta para PRs.

o que está acontecendo com esse problema?

meu pr está trabalhando em andamento, para muitos casos, ainda precisa de tempo. @cyberhck

então esperamos que seja mesclado em breve: ligeiramente_smiling_face:

Alguma atualização aqui?

Talvez pudéssemos pedir aos mantenedores do formatador de typescript para expor algumas APIs? O pacote já pode verificar se um arquivo de origem inteiro está formatado de

No entanto, pode precisar de ajuda para jogar bem com a configuração do fixador do TSLint.

O problema parece ser que uma falha só é relatada se usar o caractere de espaço em branco errado, não se o tamanho do recuo estiver desativado.

@adidahiya Não consigo fazer com que ele relate um erro se o caractere de indentação incorreto for usado. Se eu definir a regra para espaços / 4 e tiver algo como:

export function foo() {
return 123;
}

ou

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

Ele não relata um erro. De acordo com seu comentário original, você tem certeza que reporta se for o caractere de espaço em branco errado?

Algum avanço nisso? Só perguntando 😝

Adendo? Use mais bonito .

Alguém tentou tslint-eslint-rules ?

@jscharett tslint-eslint-rules funciona com a regra ter-indent . Infelizmente, não cobre o recuo JSX ...

Alguma esperança de conserto aqui?

Este bug ainda não foi corrigido na v5.10.0

Devo dizer que não imagino que o TSLint jamais será capaz de formatar código JS tão bem quanto mais bonito. Este é um problema complicado, e Prettier o resolveu melhor do que ninguém. Não acho que devamos depender do TSLint para isso, especialmente porque os projetos costumam usar as duas ferramentas em conjunto, e é provável que surjam conflitos ...

EDITAR: Para ter uma ideia melhor de _como_ complicado é esse problema, revise este PR ou dê uma olhada no código-fonte mais bonito. Se essas demonstrações não lhe parecerem "complicadas", ajude este projeto com um PR 😄!

@aervin Eu tendo a discordar aqui. Os 2 projetos, na minha opinião, têm finalidades diferentes. Mais bonito se enquadra na categoria de formatação, enquanto o TSLint está mais alinhado com a validação. Sim, o TSLint pode fazer a formatação de algumas regras, mas seu propósito pretendido como um linter, volta à validação.

O problema de confiar em Prettier é que ele é teimoso. Isso é ótimo se você concorda com o estilo dele, mas e se você não concordar? Costumávamos todos usar JSLint e todos reclamamos porque era muito opinativo. Depois vieram JSHint e JSCS, que nos deram algum controle. Agora temos ferramentas poderosas como o @eslint, que nos deu a capacidade de conectar e "corrigir" problemas automaticamente.

Embora eu tenha certeza de que mais bonito é um grande projeto, pessoalmente o vejo como um retrocesso. Está tirando o controle de mim. O TSLint não precisa "consertar" o código, se esse for o problema, apenas sinalize-o como um problema. Não tenho dúvidas de que esse problema seja complicado, mas o eslint o resolveu. A regra costumava funcionar; o que mudou para quebrá-lo?

@jscharett Obrigado por sua resposta agradável. Eu concordo que esses projetos têm finalidades diferentes, ou _devem_ ter. Meu argumento é que devemos limitar esses projetos a esses propósitos. Vamos deixar o mais bonito corrigir os problemas de indentação e deixar o TSLint alertar os desenvolvedores sobre as funções de seta que podem ser simplificadas.

Também concordo que Prettier é teimoso. Eu gosto disso no Prettier. Agora minha equipe não precisa discutir qual opinião de formatação é mais razoável. Todos nós podemos reclamar de Prettier: rindo:.

EDITAR:

A regra costumava funcionar; o que mudou para quebrá-lo?

O comentário da questão inicial me leva a acreditar que essa regra nunca funcionou como planejado.

Embora eu tenha certeza de que mais bonito é um grande projeto, pessoalmente o vejo como um retrocesso. Está tirando o controle de mim.

Minha experiência foi que pensei que me importava em ter um controle refinado sobre as regras de formatação até adicionar o mais bonito ... e logo depois percebi que não me importava tanto com a forma particular como as coisas eram formatadas, como o fato de que eles foram formatados de forma consistente. É uma enorme carga cognitiva não me preocupar mais com isso e me concentrar inteiramente no que eu quero que o código _faça_, em vez de em sua aparência.

tslint já valida outras coisas que se enquadrariam na categoria de formatação. Por exemplo, impor alinhamento, estilo de colchetes ou espaços entre nomes de variáveis ​​e operadores. Além disso, é desejável ser capaz de validar o recuo sem ter que contar com uma solução opinativa como mais bonita.

Precisa de menos discussão e mais divulgação. 😉😉

vá em frente @ffxsam

Meu comentário foi principalmente irônico. Embora eu esteja me perguntando por que esse problema tem mais de um ano e nenhum progresso foi feito. Parece que todo mundo está discutindo sobre linting vs mais bonito.

@ffxsam Porque há um debate sobre se tslint é mais sobre a parte ts ou sobre a parte lint

Esse é um ponto válido. Parece que há alguma sobreposição com TSLint / ESLint. Mas permanece o fato de que há uma opção indent que não está funcionando que está quebrada sabe-se lá quanto tempo. Parece que a coisa mais rápida / fácil seria alguém familiarizado com a base de código TSLint corrigi-lo ...?

Vote na correção de x spaces => y spaces . Este é um recurso em que nossa empresa depende muito. Não faz sentido simplesmente não consertar isso.

@ffxsam Estou observando esse problema há quase um ano, sim, faz muito tempo, mas como você pode ver, há duas tentativas de relações públicas e não funcionou até agora, acho que é mais difícil do que parece, mas de claro para os mantenedores pode ser mais fácil, só tenho muita paciência: ligeiramente_smiling_face:

Ainda reproduzível no projeto vazio
https://github.com/dimaShin/tslint-reproduce-2814

Olá @dimaShin , obrigado por

Estamos apenas esperando por esse recurso, possivelmente com opção de correção, mas isso não é um problema para mim. Da última vez que verifiquei, as pessoas estavam usando o mais bonito para verificar a indentação e o tslint para todo o resto.

Não estou dizendo que será uma boa opção para você, para mim certamente não é. Também sugiro usar .editorconfig para esta opção específica e mudar para tslint mais tarde, quando isso for resolvido.

Mais uma vez, obrigado por adicionar mais informações :)

Vamos determinar uma estratégia para verificar o recuo. Para referência, aqui está a estratégia usada pela eslint:

  1. Uma instância OffsetStorage armazena um mapa de deslocamentos desejados, onde cada token tem um deslocamento especificado de outro token especificado ou para a primeira coluna.
  2. Conforme o AST é percorrido, modifique os deslocamentos desejados de tokens de acordo. Por exemplo, ao inserir um BlockStatement, desloque todos os tokens no BlockStatement em 1 nível de recuo da chave de abertura do BlockStatement.
  3. Depois de percorrer o AST, calcule os níveis de indentação esperados de cada token de acordo com o contêiner OffsetStorage.
  4. Para cada linha, compare o recuo esperado do primeiro token com o recuo real no arquivo e relate o token se os dois valores não forem iguais.

Essa estratégia é baseada na sintaxe, que, com base em comentários anteriores, é muito opinativa porque exige que as linhas sejam quebradas de uma determinada maneira. Proponho uma maneira simples de verificar o recuo, independente de como o código é dividido em linhas:

  1. A unidade de recuo é definida nas configurações. Para tabulações, é um caractere de tabulação. Para espaços, são dois ou quatro caracteres de espaço.
  2. A primeira linha não vazia do arquivo deve ter zero unidades de recuo
  3. Cada linha não vazia subsequente deve ter
    uma. O mesmo número de unidades de recuo que a linha não vazia anterior ou
    b. Menor do que o número de unidades de recuo como a linha não vazia anterior ou
    c. Exatamente um a mais que o número de unidades de recuo da linha não vazia anterior

Algumas coisas adicionais para discutir:

  • O parâmetro de tamanho não tem efeito com guias (por quê?)
  • Não há razão para que o parâmetro de tamanho não possa ser um número inteiro positivo
  • A correção automática do tamanho do recuo provavelmente não pode ser implementada sem seguir a rota da estratégia de sintaxe

A regra

@maximelkin Os exemplos

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

Seria incrível se isso fosse corrigido.

Não consigo acreditar que algo tão fundamental como aplicar as regras de recuo ainda não está funcionando.

Então, não há como lintar esse código-ts em 2018?

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

Funciona para mim
./.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

a solução que encontrei para o problema de indentação no angular é adicionar mais bonito com as próximas etapas:
npm install --save-dev tslint-plugin-mais bonito mais bonito tslint-jasmine-rules
editar tslint.json ->
`" rulesDirectory ": [
"node_modules / codelyzer",
"node_modules / tslint-plugin-mais bonito",
"node_modules / tslint-jasmine-rules / dist"

],
"extends": "tslint-plugin-mais bonita",

"as regras": {
"mais bonita": verdade,
// adicione aqui suas regras desejadas`

e em packege.json add ->
"," mais bonita ": {
"singleQuote": verdadeiro,
"printWidth": 140,
"semi": verdadeiro,
"bracketSpacing": verdadeiro,
"arrowParens": "sempre",
"parser": "typescript"
} "

Essa é uma funcionalidade que quase todo mundo usa no dia a dia. Agradeceríamos se esse problema recebesse mais atenção.

Pessoal, Você pode usar a opção

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

Funcionou para mim Saúde!

@hiteshaleriya é o que eu tenho no meu projeto há algum tempo, mas na verdade não está corrigindo os erros, apenas os silenciando ... aqui está o meu 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
    }
}

e aqui está um exemplo relevante que terminou sem causar avisos ou erros:

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

Também não mostra erros quando as guias são usadas (embora isso possa ser por design quando 4 espaços estão presentes?).

@SpencerKaiser Você pode atualizar sua regra de indentação conforme mostrado abaixo e, em seguida, tente:

"ter-indent": [true, 4]

Tentei seu exemplo e está funcionando conforme o esperado no meu final (causando erros).

@hiteshaleriya obrigado por responder tão rápido! Portanto, agora ele está lançando erros conforme o esperado (👍), mas não está corrigindo nenhum deles com --fix . Alguma ideia?

@SpencerKaiser Você pode tentar executar o comando --fix duas vezes. Na primeira vez, ele recuará a primeira linha e, na segunda vez, recuará o resto (para o seu código de exemplo). Parece estranho, mas relate o problema se não funcionar.

@hiteshaleriya então algumas observações ... Eu não precisei executá-lo novamente, eu precisei executá-lo aproximadamente n/4 vezes onde n é o comprimento da indentação em espaços de linha recuada mais distante no projeto ¯ \ _ (ツ) _ / ¯

Depois de finalmente terminar todos eles, parece que está pulando erros básicos de indentação como este:

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

Se eu alterar o nível de indentação de const (linha 17) para 0 espaços, o restante será sinalizado com erros _excluindo_ a linha com o espaço quando eu deixar --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.

Com --fix , aqui está a primeira passagem:

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

E a segunda passagem:

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

Pensamentos??

@shubich acabei fazendo a mesma coisa ...

Existe alguma atualização sobre isso?

@MaKCbIMKo , tanto quanto eu entendo, toda a equipe estará se movendo para integrar eslint visit typescript-eslint e em um futuro próximo tslint será descontinuado, então é bom ignorar esta regra por agora (ou usar o comando tslint-config-mais bonito )

Fechando devido à complexidade desta tarefa e a mudança na direção do projeto: # 4534

A regra ESLint de typescript-eslint funciona perfeitamente para mim (consulte # 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"]
    }
}

🤖 Beep boop! 👉 TSLint está obsoleto 👈 e você deve mudar para typescript-eslint ! 🤖

🔒 Este problema está sendo bloqueado para evitar novas discussões desnecessárias. Obrigada! 👋

PS tslint-config-mais bonito - pare de usar _linters_ como TSLint para _formatar_ seu TypeScript. Isso é melhor feito por um _formatter_ como Prettier .

Esta página foi útil?
0 / 5 - 0 avaliações