Parser throws on tuple `@type` tags and `= {}` initializers, and silently drops unresolvable types
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Aptitud para principiantes
- 68/100
- Tipo de issue
- Error
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Stack tecnológico
- typescript
- Área
- tooling
Línea de trabajo
Comienza en src/parsers/script-parser.ts, en extractAttributes(), al que se llega a través de parseAttributes(), y reproduce los tres snippets con los tipos de playcanvas cargados tal como se describe en test/utils.ts. Sigue las rutas de ParsingError adyacentes y añade cobertura de regresión para los tipos tupla, los inicializadores de objetos vacíos y las referencias @type no resueltas. La tarea estará terminada cuando estos casos ya no provoquen una interrupción ni desaparezcan silenciosamente, y los atributos válidos sigan analizándose.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Found while investigating a forum report about the Interface Attribute Arrays docs example (docs fix: playcanvas/developer-site#1200). Interface arrays themselves work correctly — these are three separate robustness problems I hit while narrowing it down.
All three reproduce on main (fa36853, v1.11.0) through parseAttributes(), with the playcanvas types loaded as in test/utils.ts. Each snippet below is a complete script file.
1. TypeError when @type is a tuple
import { Script } from 'playcanvas';
class GameLogic extends Script {
static scriptName = 'gameLogic';
/**
* @attribute
* @type {[number]}
*/
values;
}
export { GameLogic };
TypeError: Cannot read properties of undefined (reading 'declarations')
at ScriptParser.extractAttributes
at JSDocParser.parseAttributes
src/parsers/script-parser.ts:497-498:
const symbol = type.aliasSymbol || type.symbol;
const typeNode = (symbol?.valueDeclaration || symbol.declarations?.[0]) as InternalNode;
A tuple type has no symbol, so symbol?.valueDeclaration is undefined and the second term dereferences undefined. symbol?.declarations?.[0] would fall through to the if (!typeNode) continue guard on the next line. Same for @type {[number, number]}.
2. TypeError when an attribute is initialized with an empty object literal
import { Script } from 'playcanvas';
class GameLogic extends Script {
static scriptName = 'gameLogic';
/**
* @attribute
*/
data = {};
}
export { GameLogic };
TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))
at Array.from (<anonymous>)
at ScriptParser.extractAttributes
at JSDocParser.parseAttributes
src/parsers/script-parser.ts:553-560:
const members: readonly ts.Node[] =
typeNode.members ??
typeNode.properties ??
Array.from(type.symbol.members as unknown as Iterable<[string, ts.Symbol]>).map(
(entry) => entry[1].declarations[0]
) ??
[];
For = {} both typeNode.members and typeNode.properties are nullish and type.symbol.members is undefined, so Array.from throws. Note the trailing ?? [] can never catch this, since the throw happens while evaluating the operand. data = { x: 1 } is fine — only the empty literal hits it.
This also fires for a member of an /** @interface */ class, e.g. data = {}; inside class Enemy.
Why 1 and 2 matter
Both throw out of extractAttributes, so the consumer gets no attributes and no diagnostics for the whole file instead of one error on the offending member. A half-written type annotation is a normal intermediate state while typing in the Editor's code editor, so these are easy to hit. Reporting a ParsingError for the member (as the neighbouring paths do) would keep the rest of the script parsing.
3. An unresolvable @type is dropped silently
import { Script } from 'playcanvas';
class GameLogic extends Script {
static scriptName = 'gameLogic';
/**
* @attribute
* @type {Enemy[]}
*/
enemies;
}
export { GameLogic };
With Enemy undefined (not declared, not imported, or a typo), parseAttributes() returns no attribute and no error; getAttributes() doesn't list the member either. Non-array @type {Enemy} behaves the same, as does @type {{}}.
The type resolves to TypeScript's error type, which has no symbol, so the if (!typeNode) continue at src/parsers/script-parser.ts:500 skips the member before any of the reporting paths below it run. An error type is detectable and could be reported with the existing "…" is not a valid attribute type message.
This is the one that makes a typo'd or missing Interface import hard to diagnose: the attribute just never appears in the Editor, with nothing in the editor's problem list to explain why.
- Lenguaje dominante
- TypeScript
- Estrellas
- 1
- Forks
- 2
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
Aún no hemos revisado los archivos de configuración de este proyecto. Empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de playcanvas/attribute-parser
-
Dependency DashboardAbierto
Dificultad 4/5 3-5 días Aptitud para principiantes 15/100
Todos los issues de playcanvas/attribute-parser
Issues similares
-
bug via-triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
pingdotgg/t3code#14452 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
solana-foundation/program-examples#747 · 1 comentario ·
Los mantenedores suelen responder en 9 días
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
remotion-dev/remotion#11847 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
openwatersio/slackwater#355 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
melgarafael/DeskcommCRM#1998 · 3 comentarios ·
Los mantenedores suelen responder en 1 día