Un IDE para el desarrollo de Lua escrita estáticamente.
Derivado de Emmylua.

self es un tipo real@shape@not Tipo Casts@type Annotations en declaraciones de retorno 






El último lanzamiento está disponible para descargar dentro de IntelliJ o desde el sitio web del complemento JetBrains.
Luanalysis se deriva de Emmylua y admite toda la funcionalidad básica de edición y refactorización proporcionada por Emmylua.
Más allá de las capacidades básicas de edición de LUA, Luanalysis admite una cantidad significativa de funcionalidad adicional necesaria para escribir estáticamente las bases de código avanzadas.
*Nota*: Las características se enumeran aproximadamente en el orden en que se implementaron, de ninguna manera orden de importancia.
Una excelente manera de ver lo que es posible en términos de escritura estática es pagar el proyecto de demostración de Luanalysis.

Además de definir nuevos tipos, la etiqueta @type ahora también se puede usar para lanzar el resultado de una expresión de LUA.
Esto es más útil con el soporte recientemente agregado para los comentarios de Bloque EMMYDOC, ya que podemos especificar fácilmente moldes de tipo en línea:

https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/type_casts.lua
Emmylua intenta determinar si un tipo es asignable a otro tipo simplemente verificando si el primero es un "subtipo" de segundo, sin embargo, no se implementa la varianza de tipo adecuada de los tipos complejos. Por ejemplo, las funciones pueden ser covariantes o contravariables de otros tipos de funciones, dependiendo de los parámetros y los tipos de valor de retorno:

Emmylua no informa el error anterior.
Además, se ha solucionado la detección de varianza sindical:

Como se indicó anteriormente, la liberación actual de Emmylua no capta este error.

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
La comprobación de tipo IE ahora funciona de la función interna "Lambdas" asignada a una variable con una definición EMMYDOC.

https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/lambda_params.luA
Varias mejoras, por ejemplo, las "matrices" de EMMYDOC ahora están asignables a tipos de tabla compatibles, por ejemplo,

La versión actual de Emmylua informará un error aquí a pesar de que esto es 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#l226-l249
La versión actual de Emmylua no puede inferir genéricos correctamente en varias situaciones y, por lo tanto, informa errores de tipo donde no existe ningún error, y también pierde errores en los que deberían existir errores, por ejemplo,
https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/function_generics.lua#l154-l181
Por defecto, los errores de seguridad de tipo ahora se informan como errores en lugar de advertencias. Esto se hace factible por tres cosas:
Muchas mejoras en la capacidad de especificar tipos complejos
Escriba correcciones de errores de seguridad
Fundición
La emisión en particular significa que si un usuario está haciendo algo, el sistema de tipos considera inseguro, pero saben que en tiempo de ejecución estará bien, puede agregar un elenco para indicar esto y el error desaparecerá.

El sombreado de un parámetro genérico está prohibido y un error informa:

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 es un tipo real Verificación de tipo mejorado para self , por ejemplo self se puede asignar a una variable que coincida con el tipo principal de un método. Sin embargo, ese tipo de padre no se puede asignar a self , ya que la clase puede ser subclase (en cuyo caso self se refiere a un tipo más específico).

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

La versión actual de Emmylua permitirá esta asignación no válida.
Cuando una función devuelve múltiples valores, la liberación de Emmylua actual inferirá los valores y los pondrá en el caché. Esto es inexacto ya que el análisis de tipos genéricos puede dar como resultado que el mismo parámetro genérico se resuelva de manera diferente en función del valor asignado, por lo que el caché no se puede usar en esta circunstancia. Actualmente esto da como resultado errores faltantes y errores inexactos adicionales, dependiendo de la asignación.
@shapeUna forma se puede definir de manera similar a una clase, excepto que la contravarianza se determina por la compatibilidad de los miembros, no por la jerarquía de herencia.
Esto es más útil cuando se trabaja con "estructuras" (por ejemplo, JSON) en lugar de clases de OOP.

https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/shape.lua
Lo que hace que las formas sean particularmente útiles es que admiten genéricos y herencia (en el momento de la definición, no de la tarea) al igual que las clases:
https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/shape.lua#l36-l74
Aún mejor , las inspecciones de tipos no solo se informan sobre `table 'incompatibles, sino que las inspecciones saben cómo atravesar literales de tabla y proporcionar anotaciones detalladas de incompatibilidades entre dos formas, por ejemplo,

Los alias ahora pueden tomar parámetros genéricos, al igual que una clase o forma.

https://github.com/benjamin-dobell/luanalysistypesdemo/blob/cfea19c9fd744078f50f61e74e620b7505b58c65/src/generic_alias.lua
Los tipos de funciones ahora pueden usar …: T como una alternativa a vararg T :

Ahora admitimos valores de retorno variádicos:

Internamente, TyTuple ha sido reemplazado por TyMultipleResults para reflejar el hecho de que esta construcción no es de tamaño fijo. Además, múltiples resultados ahora se manejan adecuadamente en más ubicaciones.
Varias mejoras en las tipificantes de los empotrados de lua aprovechando los valores de retorno variádicos, etc.
Ahora podemos escribir todas las propiedades de las tablas, no solo las constantes de cadena. Dado que Luanalysis también agrega soporte para tipos literal primitivos, podemos usar esto de muchas maneras diferentes, por ejemplo,

Aquí tenemos campos de identificador de cadena regulares, campos literarios de números [1] , [2] y [3] y un campo [boolean] . Ese último es realmente poderoso, porque no es una constante, es un tipo real.
Podemos escribir estructuras de datos personalizadas, por ejemplo,
--- @class Dictionary < K , V >
--- @field [ K] V Esto funcionará correctamente para cualquier K y todo se verificará estáticamente como era de esperar.
También hay sintaxis para los tipos de mesa, funciona para literales de mesa y clases anónimas (es decir, tablas que no se escriben explícitamente):

Ahora admitimos tipos fun con listas de parámetros opcionales y valores de retorno opcionales, es decir fun: boolean y fun(arg: boolean) . fun (sin ninguna especificada) también funciona para la posteridad, pero es funcionalmente equivalente al tipo function existente.
Las funciones parcialmente escrita son extremadamente útiles para implementar patrones de devolución de llamada y controlador. Por ejemplo, es bastante común tener un sistema de eventos extensible donde cada evento tenga argumentos únicos, pero el controlador debe devolver true para indicar que el evento se manejó:

Esta es otra característica realmente útil. Ahora podemos indicar correctamente que un objeto es llamable (es decir, es una table cuyo metatible tiene un método __call ).

Esto se hace utilizando la palabra clave @overload emmydoc existente, y funciona de manera similar, es decir, podemos especificar muchas sobrecargas y la comprobación y finalización del tipo funcionará como era de esperar:

Las tuplas se pueden implementar como formas con índices literal de números:

o como alias de tipos literales de tabla:

Como se puede ver anteriormente, cuando una tupla es compatible con una matriz, se puede asignar a una, pero no viceversa.
La anotación @type admite una lista de tipos. Esto se puede usar al declarar variables:

o para lanzar múltiples resultados devueltos por una expresión (por ejemplo, llamada de función):

@not Tipo Casts Un elenco de tipo @not elimina los tipos de una unión. Es útil en una variedad de circunstancias, la más directa de las cuales es eliminar nil :

Al igual que @type , también es compatible con listas de tipos para lanzar múltiples valores de retorno de una función, y puede eliminar los sindicatos:

Cuando simplemente desea eliminar los tipos de un sindicato, generalmente es más seguro usar @not elenco que un elenco @type porque un elenco @type esencialmente deshabilita todos los tipos de verificación para la tarea, donde, como @not elenco, solo excluye ciertos tipos.
@type Annotations en declaraciones de retornoLas declaraciones de retorno ahora aceptan anotaciones de tipo, que son una forma tipográfica de escribir el valor de retorno de los lambdas anónimos.

A diferencia de un elenco de tipo, estos son de tipo seguro:

Los tipos de alias ahora se resuelven perezosamente, lo que nos permite escribir estructuras de datos recursivas. Por ejemplo, JSON:

Una API de funciones puede devolver un número desconocido de resultados. Sin embargo, al llamar a estas funciones, tiende a saber cuántos resultados espera.
Se puede lanzar un valor de retorno variádico a una lista de tipos concretos por @not lanza nil :

También se puede lanzar un tipo variádico a otro:

Ahora admitimos parámetros opcionales en definiciones de tipo de función de forma corta y larga, por ejemplo,

Es importante destacar que el opcional no es de mano corta para nil | type .

No puede proporcionar nil a menos que el tipo de parámetro opcional en sí mismo incluya nil como parte de una unión en su definición de tipo. Esto es deseable para fines de corrección al implementar funciones en LUA, por ejemplo, si la implementación utiliza [ select('#', …) ] (https://www.lua.org/manual/5.3/manual.html#pdf-select). Sin embargo, más allá de eso, Lua se usa regularmente como un lenguaje de secuencias de comandos, vinculando la función LUA llamadas a implementaciones en otros idiomas que tienen soporte para sobrecargas, etc., donde el número y el tipo de argumentos son importantes.
También se han implementado inspecciones que evitan el orden de parámetros opcionales incorrectos:
Construya el complemento con:
./gradlew buildPara obtener más detalles sobre el SDK de la plataforma JetBrains, consulte la documentación oficial.
El complemento resultante .zip terminará en el directorio ./build/distributions/ .
Para instalar el .zip que construyó, deberá ir a IntelliJ's ...
Preferencias -> Plugins -> Configuración icono Cog -> Instalar complemento desde el disco ...

Seleccione el .zip y luego, cuando se le solicite, reinicie IntelliJ.
Luanálisis de: Benjamin Dobell
Emmylua por: @tangzx 阿唐
Colaboradores
Consulte GitHub para obtener una lista completa de contribuyentes.
Gracias a los patrocinadores y partidarios de Luanalysis que ayudan a garantizar el desarrollo continuo de Luanalysis.