Um IDE para o desenvolvimento da Lua tiped estaticamente.
Derivado de Emmylua.

self é um tipo real@shape@not Type Casts@type Anotações em declarações de retorno 






O lançamento mais recente está disponível para download no Intellij ou no site do plug -in do JetBrains.
A Luanalysis é derivada de Emmylua e suporta toda a funcionalidade básica de edição e refatoração fornecida por Emmylua.
Além dos recursos básicos de edição da LUA, a Luanalysis suporta uma quantidade significativa de funcionalidade adicional necessária para digitar estaticamente bases de código avançadas.
*Nota*: Os recursos são listados aproximadamente na ordem em que foram implementados, de maneira alguma a ordem de importância.
Uma ótima maneira de ver o que é possível em termos de digitação estática é verificar o projeto Demo Luanalysis.

Além de definir novos tipos, a tag @type agora também pode ser usada para lançar o resultado de uma expressão Lua.
Isso é mais útil com o suporte recém -adicionado para os comentários do bloco Emmydoc, pois podemos especificar facilmente os elencos do tipo embutido:

https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/type_casts.lua
Emmylua tenta determinar se um tipo é atribuível a outro tipo simplesmente verificando se o primeiro for um "subtipo" do último, no entanto, a variação adequada dos tipos complexos não é implementada. Por exemplo, as funções podem ser covariantes ou contravariantes de outros tipos de funções, dependendo dos parâmetros e dos tipos de valor de retorno:

Emmylua não relata o erro acima.
Além disso, a detecção de variância da união foi corrigida:

Como acima, a versão atual do Emmylua não recebe esse erro.

https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/string_literals.lua

https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/function_generics_scope.lua
O tipo de verificação do tipo IE agora funciona dentro da função "Lambdas" atribuída a uma variável com uma definição do EmmyDoc.

https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/lambda_params.lua
Várias melhorias, por exemplo, emmydoc "matrizes" agora são atribuíveis a tipos de tabela compatíveis, por exemplo,

A versão atual do Emmylua relatará um erro aqui, mesmo que isso seja sólido.
https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/tables.lua

https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/generic_class_fields.lua

https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/function_generics.lua#l5526249
A versão atual do Emmylua é incapaz de inferir genéricos corretamente em várias situações e, portanto, relata erros de tipo em que não existe erro e também perde erros onde os erros devem existir, por exemplo,
https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/function_generics.lua#l1544442
Por padrão, os erros de segurança do tipo agora são relatados como erros em vez de avisos. Isso é viável por três coisas:
Muitas melhorias na capacidade de especificar tipos complexos
Digite correções de bug de segurança
Elenco
Ficar em particular significa que, se um usuário estiver fazendo algo que o sistema de tipos considera inseguro, mas sabe que no tempo de execução ficará bem, ele pode apenas adicionar um elenco para significar isso e o erro desaparecerá.

O sombreamento de um parâmetro genérico é proibido e um erro relata:

https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/generic_class_scope.lua

https://github.com/Benjamin-Dobell/LuanalysisTypesDemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/generic_class_fields.lua#L44-L45
self é um tipo real Verificação de tipo aprimorada para self , por exemplo, self pode ser atribuído a uma variável que corresponde ao tipo pai de um método. No entanto, esse tipo de pai não pode ser atribuído a self , pois a classe pode ser sub-classa (nesse caso, refere self se a um tipo mais específico).

https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/self.lua

A liberação atual do Emmylua permitirá esta atribuição inválida.
Quando uma função retorna vários valores, a liberação atual de Emmylua inferirá valores e os coloca no cache. Isso é impreciso, pois a análise de tipos genéricos pode resultar no mesmo parâmetro genérico sendo resolvido de maneira diferente com base no valor atribuído, portanto o cache não pode ser usado nessa circunstância. Atualmente, isso resulta em erros ausentes e erros imprecisos adicionais, dependendo da tarefa.
@shapeUma forma pode ser definida de maneira semelhante a uma classe, exceto que a contravariância é determinada pela compatibilidade dos membros e não pela hierarquia da herança.
Isso é mais útil ao trabalhar com "estruturas" (por exemplo, JSON) em vez de classes OOP.

https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/shape.lua
O que torna as formas particularmente úteis é que elas apóiam genéricos e herança (na hora da definição, não na tarefa), assim como as aulas:
https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/shape.lua#l36--l744
Melhor ainda, as inspeções de tipo não são apenas relatadas sobre `tabela incompatíveis como todo, mas as inspeções sabem como atravessar literais da tabela e fornecer anotações detalhadas de incompatibilidades entre duas formas, por exemplo,

Os aliases agora podem levar parâmetros genéricos, assim como uma classe ou forma.

https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/generic_alias.lua
Os tipos de função agora podem usar …: T como uma alternativa para vararg T :

Agora apoiamos os valores de retorno variúdico:

Internamente, TyTuple foi substituído por TyMultipleResults para refletir o fato de que esse construto não é do tamanho fixo. Além disso, vários resultados agora são tratados adequadamente em mais locais.
Várias melhorias nas tímidas de Lua Build-ins aproveitando os valores de retorno variúdico etc.
Agora podemos digitar todas as propriedades das tabelas, não apenas constantes de string. Dado que a Luanalysis também adiciona suporte para tipos literais primitivos, podemos usar isso de várias maneiras diferentes, por exemplo,

Aqui temos campos regulares de identificador de cordas, campos literais numéricos [1] , [2] e [3] e um campo [boolean] . Esse último é realmente poderoso, porque não é uma constante, é um tipo real.
Podemos digitar estruturas de dados personalizadas, por exemplo
--- @class Dictionary < K , V >
--- @field [ K] V Isso funcionará corretamente para qualquer K e tudo será estaticamente digitado como você esperaria.
Também há sintaxe para tipos de tabela, ele funciona para literais de tabela e aulas anônimas (por exemplo, tabelas que não são digitadas explicitamente):

Agora, apoiamos tipos fun com listas de parâmetros opcionais e valores de retorno opcionais, ou seja, fun: boolean e fun(arg: boolean) . fun (com nenhum especificado) também funciona para a posteridade, mas é funcionalmente equivalente ao tipo function existente.
As funções parcialmente digitadas são extremamente úteis para implementar padrões de chamada e manipuladores. Por exemplo, é bastante comum ter um sistema de eventos extensível em que cada evento tenha argumentos exclusivos, mas o manipulador deve retornar true para indicar que o evento foi tratado:

Este é outro recurso realmente útil. Agora podemos indicar corretamente que um objeto é chamável (ou seja, uma table cujo metatível possui um método __call ).

Isso é feito usando a palavra -chave @overload existente e funciona da mesma forma, ou seja, podemos especificar muitas sobrecargas e a verificação e a conclusão do tipo funcionarão como você esperaria:

As tuplas podem ser implementadas como formas com índices literais numéricos:

ou como aliases dos tipos literais de tabela:

Como pode ser visto acima, quando uma tupla é compatível com uma matriz, ela pode ser atribuída a uma, mas não vice -versa.
A anotação @type suporta uma lista de tipos. Isso pode ser usado ao declarar variáveis:

ou para lançar vários resultados retornados por uma expressão (por exemplo, chamada de função):

@not Type Casts Um elenco do tipo @not elimina tipos de uma união. É útil em várias circunstâncias, a mais direta da qual está eliminando nil :

Como @type , também suporta listas de tipos para lançar vários valores de retorno de uma função e pode eliminar sindicatos:

Quando você simplesmente deseja eliminar os tipos de um sindicato, geralmente é mais seguro usar @not Cast do que um elenco @type porque um elenco @type essencialmente desativa todo o tipo de verificação de tipo para a tarefa, onde, como @not elenco exclui certos tipos.
@type Anotações em declarações de retornoAs declarações de retorno agora aceitam anotações do tipo, que são uma maneira segura para digitar o valor de retorno dos lambdas anônimos.

Ao contrário de um elenco do tipo, estes são seguros de tipo:

Agora, os tipos de alias estão resolvidos preguiçosamente, o que nos permite digitar estruturas de dados recursivas. Por exemplo, JSON:

Uma API de funções pode retornar um número desconhecido de resultados. No entanto, ao chamar essas funções, você tende a saber quantos resultados esperam de volta.
Um valor de retorno variúdico pode ser lançado em uma lista de tipo de concreto por @not lançando nil :

Um tipo variadico também pode ser lançado para outro:

Agora suportamos parâmetros opcionais em definições de tipo de função curta e longa, por exemplo,

É importante ressaltar que opcional não é de mão curta para nil | type .

Você não pode fornecer nil a menos que o próprio tipo de parâmetro opcional inclua nil como parte de um sindicato em sua definição de tipo. Isso é desejável para fins de correção ao implementar funções em Lua, digamos, por exemplo, se a implementação fizer uso de [ select('#', …) ] (https://www.lua.org/manual/5.3/manual.html#pdf-select). No entanto, além disso, o Lua é usado regularmente como uma linguagem de script, vinculando chamadas de função Lua para implementações em outros idiomas que têm suporte para sobrecarga etc. onde o número e o tipo de argumentos são importantes.
As inspeções que impedem a ordem de parâmetros opcionais incorretas também foram implementadas:
Construa o plugin com:
./gradlew buildPara mais detalhes sobre a plataforma JetBrains SDK, consulte a documentação oficial.
O plug -in resultante .zip acabará no diretório ./build/distributions/ .
Para instalar o .zip que você construiu, você precisará ir para o Intellij…
Preferências -> Plugins -> Icon de configurações de cog -> Instale o plug -in do disco ...

Selecione o .zip e, quando solicitado, reinicie o Intellij.
Luanalysis por: Benjamin Dobell
Emmylua por: @Tangzx 阿唐
Colaboradores
Consulte o GitHub para obter uma lista completa de colaboradores.
Obrigado aos patrocinadores e apoiadores da Luanalysis que ajudam a garantir o desenvolvimento contínuo da Luanalysis.