fix: native/forward multilinha e doc comment após #pragma deprecated - #37
Open
NullSablex wants to merge 13 commits into
Open
fix: native/forward multilinha e doc comment após #pragma deprecated#37NullSablex wants to merge 13 commits into
native/forward multilinha e doc comment após #pragma deprecated#37NullSablex wants to merge 13 commits into
Conversation
Dois defeitos que se somavam justamente nos includes do open.mp, onde
assinaturas longas quebradas em várias linhas são comuns.
**Assinatura multilinha descartada.** Ao fechar o `)`, o parser só criava o
símbolo se o resto da linha trouxesse `{`; sem isso, guardava em
`pending_plain` à espera de um corpo na linha seguinte. `native` e `forward`
declaram sem corpo e terminam em `;`, então a espera nunca terminava e o
símbolo se perdia — sem hover, sem autocomplete, sem signature help. Um
`ApplyActorAnimation` do omp_actor, com nove parâmetros em nove linhas, era
invisível para a engine.
**Doc perdido quando a diretiva estava no meio.** `extract_doc` caminha para
cima a partir da declaração e para na primeira linha que não é comentário —
`#pragma deprecated` entre o bloco e a declaração cortava o caminho. Passa a
pular a diretiva. Regressão da mudança anterior, que trouxe o `#pragma`: com
`@DEPRECATED` o marcador era um comentário e não interrompia a varredura.
`pragma_deprecated_message` monta uma `String` e era chamada em toda linha do arquivo — tanto no laço principal quanto na varredura para cima do `extract_doc` — só para responder se a linha é a diretiva. Separa o reconhecimento (`is_pragma_deprecated`, sem alocação) da extração da mensagem, e faz o `extract_doc` acumular fatias em vez de `String` por linha. Num arquivo com 600 nativas documentadas, ~2,5 ms → ~2,1 ms; com a diretiva e sem doc, ~2,1 ms → ~1,96 ms. Medido com 20 repetições após aquecimento — medições únicas variam demais para servir de base.
O compilador rejeita uma diretiva que não conheça (erro 207), mas só na
compilação. O diagnóstico antecipa isso e oferece a correção.
Dois casos, ambos com quick fix:
- **nome não reconhecido** — comparado com a lista de `sc2.c`; havendo uma
diretiva próxima (distância de edição pequena, mais estrita para nomes
curtos), ela é sugerida;
- **mensagem de `deprecated` entre aspas** — a diretiva toma o resto da linha
como texto livre (`strdupwithouta` sobre `lptr`, em `sc2.c:1240`), então as
aspas entrariam na mensagem em vez de delimitá-la. Aspas no meio do texto
são literais legítimas e não são sinalizadas.
A forma correta, confirmada no compilador, é sem aspas:
#pragma deprecated Use BanPlayerFor
Estende as correções rápidas aos diagnósticos cuja correção é
determinística:
- `PP0002`/`PP0003` — remove o corpo `{ … }` que o compilador não aceita em
`native`/`forward`. Por ser erro de sintaxe, é oferecido também em `.inc`,
ao contrário das remoções por "não utilizado";
- `PP0004` — duas ações: dar um corpo vazio, ou converter `public`/`stock`
em `forward`, que é a forma de declarar sem corpo;
- `PP0010` — troca por um símbolo conhecido de nome parecido, entre os do
arquivo e de todos os includes transitivos. É o mesmo universo do
autocomplete, então a sugestão nunca aponta para algo invisível ao arquivo;
- `PP0011`/`PP0012` — remove a linha da diretiva, arrastando continuações
com `\` no fim;
- `PP0017` — reindenta a linha pelo formatador, com o estilo configurado no
workspace (preset e overrides), em vez de uma indentação fixa.
`PP0014`/`PP0015` ficam de fora de propósito: remover uma `native` ou um
`forward` de uma include quebraria quem a consome.
A distância de edição que o PP0019 usava sai de `pragmas.rs` para
`similar.rs`, agora compartilhada com o PP0010, com tolerância proporcional
ao tamanho do nome — um `max` fixo trata mal os extremos.
O `sort_text` punha os símbolos globais em `0_` e as variáveis locais em `1_`: dentro de uma função, os parâmetros e as locais apareciam **abaixo** de milhares de nativas dos includes — o inverso do útil. A ordem passa a ser explícita, num `Rank`: locais e parâmetros, símbolos do próprio arquivo, símbolos dos includes, palavras-chave, e por último os marcados com `#pragma deprecated`. Um descontinuado continua na lista, mas nunca à frente de uma alternativa viva. Dentro do grupo, a ordem é alfabética sem diferenciar caixa — sem isso "Zebra" viria antes de "alfa". A lista também era enviada inteira a cada tecla. Passa a ser cortada em 1000 itens com `isIncomplete`, o mecanismo do LSP para listas grandes: o editor pede de novo conforme o prefixo cresce. A ordenação acontece antes do corte, então o que se descarta são os itens mais distantes do cursor.
**Doc de um símbolo no hover de outro.** Ao ver uma linha terminada em `*/`, `extract_doc` empurrava a linha e procurava o `/*` de abertura a partir da **anterior** — mas um bloco de uma linha (`/** … */`) já está completo. A busca então atravessava o código acima até casar com o `/**` de outro comentário, e o hover de um `#define` saía com a documentação da função anterior mais o código do meio. Um bloco de uma linha passa a encerrar ali mesmo, e um `*/` sem abertura devolve `None` em vez de arrastar o arquivo até o topo. **Hover desalinhado.** O aviso de depreciado era um blockquote (`> …`): o editor recuava o bloco e lia o `---` seguinte como continuação, desalinhando a documentação. Vira texto normal, e passa a mostrar a mensagem do `#pragma deprecated` — que até então só aparecia no aviso de uso.
Um cabeçalho de seção acima de uma função era tratado como documentação
dela, e o hover mostrava a régua mais o texto da seção:
// ---------------------------------------------------
// 9. Símbolos vindos dos includes
// ---------------------------------------------------
stock TesteIncludes(playerid) // hover exibia o bloco acima
Uma linha de comentário composta só de ornamento (`-`, `=`, `*`, `_`, `#`,
`~`) encerra a varredura: além de não documentar nada, o que está acima dela
pertence a outra seção do arquivo.
Comentários `//` com texto seguem valendo como documentação — é convenção
legítima em Pawn, e só a régua sai.
Explicavam o mecanismo onde bastava dizer o que fazer.
"`#pragma x` não é reconhecido pelo compilador" → "`#pragma x` não existe"
"… — você quis dizer `deprecated`?" → "… — use `deprecated`"
"toma o resto da linha como texto — as aspas
entrariam na mensagem" → "A mensagem não leva
aspas — elas entrariam
no texto"
"\"x\" está marcado como depreciado" → "\"x\" está depreciado"
Nos títulos das ações, o alvo já está no contexto do cursor: "Remover o corpo
da declaração" → "Remover o corpo"; "Corrigir a indentação desta linha" →
"Corrigir a indentação"; "Renomear \"a\" para \"b\"" → "Renomear para \"b\"".
Nos cinco idiomas.
A correção anterior só reconhecia a régua pura (`// --------`). O cabeçalho
que traz texto entre ornamentos continuava virando documentação:
// --- PP0004: `stock` sem corpo ---------------------
stock FuncaoSemCorpo(playerid); // hover exibia a linha acima
Passa a valer também quando a linha abre e fecha com uma corrida de três ou
mais ornamentos. O limite de três é o que separa cabeçalho de prosa: um
hífen isolado é comum em texto (`// vale -1 quando ausente`) e segue sendo
documentação.
A varredura subia o arquivo acumulando linhas de comentário, e trazia para o hover réguas, cabeçalhos de seção e o texto de outras funções. As correções anteriores atacavam cada sintoma — reconhecer régua pura, depois cabeçalho com texto entre ornamentos — quando o problema era a varredura não ter fim. Passa a valer a regra do Javadoc/PHPDoc: **um bloco só, o imediatamente acima da declaração**. Um `/* … */` colado nela, ou uma sequência contígua de linhas `//`. Linha em branco ou código entre os dois separa. Com isso saem `is_comment_rule` e a heurística de ornamentos: não é mais preciso adivinhar o que é separador, porque nada além do bloco vizinho é lido. O `#pragma deprecated` entre o comentário e a declaração continua sendo pulado — é a diretiva que marca aquele símbolo.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Duas correções de parsing que se somavam justamente nos includes do open.mp.
native/forwardcom assinatura multilinha eram ignoradosAo fechar o
), o parser só criava o símbolo se o resto da linha trouxesse{; sem isso, guardava empending_plainesperando um corpo na linha seguinte. Masnativeeforwarddeclaram sem corpo e terminam em;— a espera nunca terminava e o símbolo se perdia por completo: sem hover, sem autocomplete, sem signature help.O impacto é grande nos includes do open.mp, onde assinaturas longas quebradas em várias linhas são a norma. Um
ApplyActorAnimationdoomp_actor, com nove parâmetros em nove linhas, era simplesmente invisível para a engine.Doc comment perdido quando
#pragma deprecatedficava no meioextract_doccaminha para cima a partir da declaração e para na primeira linha que não é comentário — a diretiva cortava o caminho:Regressão da mudança anterior, que trouxe o
#pragma: com@DEPRECATEDo marcador era um comentário e não interrompia a varredura. Passa a pular a diretiva.Verificação
202 testes (5 novos cobrindo os dois defeitos),
cargo fmtlimpo, clippy pedantic sem avisos. Validado contra uma amostra real doomp-stdlib: o símbolo multilinha é reconhecido, com os 9 parâmetros e o doc preservado.