Buscar/Corrija e teste um gerador de wrappers de bibliotecas nativas para muitas linguagens

Corrija e teste um gerador de wrappers de bibliotecas nativas para muitas linguagens

Use ao alterar uma ferramenta que gera wrappers de bibliotecas nativas para muitas linguagens. Procura a etapa onde o erro começa, roda testes do tamanho certo, adiciona testes de regressão e atualiza o registro de alterações.

Para usar estas regras de IA
## Leia primeiro os guias de cada tarefa e corrija as entradas, não os arquivos gerados ### Comece pelas orientações específicas da tarefa Antes de alterar código ou executar comandos especializados, localize os guias breves do repositório para tarefas específicas. Leia o guia correspondente ao trabalho, em vez de reconstruir procedimentos a partir de uma visão geral ampla. Os guias típicos abrangem: - executar toda a suíte, uma suíte de linguagem de destino ou um único caso de teste; - depurar o compilador, inspecionar árvores sintáticas e rastrear falhas de memória; - editar o manual do usuário e validar sua estrutura; - formatar o código-fonte e tratar comentários, convenções de contribuição e mensagens de commit; - reproduzir falhas que ocorrem apenas na integração contínua. Trate esses guias direcionados como oficiais quando fornecerem comandos, opções ou convenções exatas. Se atalhos de descoberta ou links simbólicos espelharem o mesmo guia em vários locais específicos de ferramentas, mantenha uma única fonte oficial e confirme que os links sejam criados corretamente na plataforma de quem contribui. ### Entenda o sistema antes de editá-lo O repositório implementa um gerador no estilo de compilador. Ele lê declarações nativas e descrições de interface e depois gera wrappers que expõem bibliotecas nativas a várias linguagens de destino. Esse modelo tem três consequências práticas: - arquivos gerados são produtos, não o principal local para corrigir comportamentos; - entradas de interface compartilhadas devem conter o comportamento entre linguagens, enquanto verificações de execução específicas de um destino pertencem ao diretório de testes correspondente; - uma alteração na análise sintática, resolução de tipos, propriedade ou geração de wrappers pode afetar vários backends, mesmo quando o sintoma relatado aparece em apenas um. Use os próprios guias, arquivos de build e testes do repositório como evidências. Não deduza um fluxo apenas de nomes de diretórios que pareçam familiares ou de convenções usadas por outro projeto. ## Compile com o sistema de build da CI e escolha o menor teste útil ### Compile a partir da forma correta do código-fonte Use o sistema principal de build utilizado pela integração contínua. Uma cópia de trabalho obtida do controle de versão pode exigir uma etapa de inicialização para gerar arquivos de configuração, enquanto um pacote de versão pode já incluí-los. A sequência normal é inicializar quando necessário, configurar e então compilar. Preserve as opções de configuração aceitas, como prefixo de instalação e controles de dependências opcionais. Pode existir um sistema de build secundário, mas não o substitua silenciosamente ao diagnosticar uma falha do pipeline principal. Testes e exemplos podem chamar um iniciador para a árvore ainda não instalada que direcione o ambiente de execução ao diretório da biblioteca recém-compilada; use esse iniciador para que os testes avaliem a cópia atual, não uma versão instalada. Se um componente auxiliar de cache do compilador fizer parte do grafo padrão de build e teste, inclua-o, a menos que o guia oficial limite expressamente a execução. ### Escolha o menor teste significativo Ajuste o comando ao escopo da alteração: - execute um teste de wrapper gerado enquanto itera sobre um comportamento localizado; - execute toda a suíte da linguagem de destino afetada quando o comportamento do backend mudar; - execute as suítes compartilhadas quando houver mudanças no parser, no sistema de tipos, na propriedade ou na lógica comum de geração; - use execução paralela apenas quando o repositório oferecer suporte; - use um modo que continue após falhas em execuções amplas quando coletar todas elas for mais útil que parar na primeira. Os alvos de teste costumam codificar a forma do código-fonte, como modo de linguagem nativa, modo orientado a objetos ou modo de vários módulos. Use o sufixo correspondente ao caso e execute o alvo de limpeza relacionado antes de concluir que um artefato gerado antigo é uma falha nova. ### Verifique o mesmo caminho usado pela automação Quando uma falha ocorrer apenas na integração contínua, reproduza o ambiente do executor com a imagem de contêiner mantida pelo repositório e os scripts reais de instalação. Prefira o recurso auxiliar que reproduz o executor hospedado a um ambiente improvisado. Confirme as mesmas versões de dependências, variáveis de ambiente, modo de build e alvo de teste antes de atribuir a diferença ao código-fonte. Uma correção ou funcionalidade normalmente deve incluir um teste de regressão. Não afirme que uma alteração foi verificada apenas porque o compilador foi construído com sucesso; a geração do wrapper, a compilação do código gerado e o comportamento de execução na linguagem de destino são pontos de verificação separados. ## Encontre a etapa do pipeline onde o erro começa e nunca reentre no parser ### Siga as etapas de processamento Rastreie o comportamento pelo pipeline nesta ordem: 1. O pré-processador expande entradas de interface e diretivas condicionais. 2. O scanner converte o texto de entrada em tokens. 3. O parser aplica a gramática e cria uma árvore de nós com atributos. 4. O sistema de tipos resolve nomes, equivalências, modelos e conversões. 5. As passagens sobre a árvore acrescentam ou normalizam as informações exigidas pelas etapas posteriores. 6. Um backend da linguagem de destino percorre a árvore e gera o código do wrapper. Localize a primeira etapa em que o estado real diverge do esperado. Um wrapper malformado não prova que o backend seja responsável; ele pode estar gerando fielmente um nó sintático, tipo, indicador de propriedade ou regra de conversão incorretos criados anteriormente. ### Use as abstrações centrais do modelo Nós sintáticos se comportam como objetos de chave e valor e são percorridos por passagens compartilhadas e backends de linguagem. Inspecione os atributos no ponto em que são criados e novamente quando são consumidos. Mapas de conversão de tipos controlam como valores nativos atravessam o limite para se tornar valores da linguagem de destino; quando o comportamento da conversão estiver errado, verifique a precedência de seleção e a equivalência de tipos antes de alterar o texto gerado. A instanciação de modelos depende do mesmo mecanismo de equivalência de tipos, portanto separe a correspondência de especializações da formatação do wrapper. Examine a análise compartilhada de propriedade e alocação antes de adicionar contornos locais de ciclo de vida a um backend. ### Respeite os limites de um parser não reentrante Presuma que o parser não seja reentrante, a menos que a implementação prove o contrário. Os pontos de entrada que envolvem o parser podem sobrescrever seu estado global, incluindo a posição atual de entrada, os valores semânticos e a antecipação. Nunca chame esses pontos de entrada de forma recursiva dentro de uma ação gramatical. Quando uma regra gramatical precisar construir uma nova lista de parâmetros ou uma subsintaxe relacionada, reutilize as produções existentes da gramática dentro da análise ativa, em vez de iniciar uma análise aninhada. Valide a alteração com um caso de regressão para o padrão de linguagem mais antigo que introduziu o recurso gramatical. ### Use os recursos de depuração aceitos Use as opções de depuração documentadas no repositório, despejos textuais ou estruturados da árvore, recursos auxiliares do depurador, wrappers de execução, variáveis de seleção de funcionalidades e diagnósticos do pool de memória. Para uma falha exclusiva da automação, reproduza o ambiente automatizado antes de ampliar a instrumentação. Mantenha temporárias as alterações de diagnóstico e não transforme um contorno local em comportamento de produção sem um teste falho que demonstre a necessidade. ## Coloque cada teste de regressão na entrada compartilhada ou no script da linguagem ### Coloque o comportamento na camada correta Um teste normalmente inclui uma entrada de interface compartilhada que conduz a geração e um script opcional de execução na linguagem de destino que exercita o wrapper gerado. Coloque na entrada compartilhada os requisitos de gramática e wrapper independentes da linguagem. Coloque no script correspondente a sintaxe da linguagem de destino, as asserções de execução e os casos limítrofes específicos da linguagem. Registre novos casos no grupo da suíte que corresponda ao escopo real. Um prefixo de nome de teste associado a um padrão de linguagem deve representar o padrão mais antigo que introduziu o recurso gramatical, não um padrão mais recente usado por um exemplo conveniente. Determine o recurso isoladamente e depois coloque o teste no grupo do padrão correspondente. ### Torne as falhas observáveis Use recursos auxiliares de asserção que permaneçam ativos nos modos de execução otimizados. Se uma linguagem de destino puder remover sua instrução de asserção integrada durante a otimização, nunca dependa dela para a cobertura de regressão. Use recursos auxiliares explícitos de igualdade, condição e exceção esperada que informem valores úteis quando houver falha. Mantenha os comentários de teste breves e restritos ao que não for óbvio. Explique um contorno do compilador ou uma armadilha semântica em uma linha concisa; não narre o que o código já declara. Um teste de regressão deve falhar antes da correção, passar depois dela e exercitar o comportamento público, não um recurso auxiliar interno ocasional. ### Valide o impacto compartilhado Para alterações no parser ou no sistema de tipos comum, teste outros backends além daquele que falhou originalmente quando o caminho afetado for compartilhado. Para comportamento exclusivo do backend, evite ampliar a execução sem evidências. Limpe os arquivos gerados entre configurações de teste materialmente diferentes e diferencie no relatório as falhas de geração, compilação nativa e execução. ## Não misture mudanças alheias nos commits e anote cada mudança visível no registro de alterações ### Siga as convenções de código-fonte e comentários Use as verificações de formatação e o formatador do repositório, em vez de normalizar manualmente código alheio. Siga o estilo estabelecido de comentários da linguagem nativa, a forma de citar tokens, a largura de linha e as convenções de cabeçalho de funções. Arquivos de gramática podem impor regras mais rígidas ao código novo; siga essas regras e evite refatorações alheias ao alterar um parser de produção. Antes de confirmar alterações, revise o diff em busca de arquivos gerados, substituições amplas acidentais e mudanças fora do subsistema pretendido. O texto do commit deve ser simples, conciso e correto. Não atribua uma ferramenta automatizada como coautora. Se o projeto exigir a divulgação de assistência automatizada significativa, use o rodapé de assistência aprovado sem uma identidade de e-mail. ### Registre alterações visíveis para os usuários Toda correção de falha, funcionalidade, mudança de comportamento, mudança de aviso ou descontinuação visível para os usuários deve incluir uma entrada no registro de alterações atual. Descreva o que um usuário observa, não nomes de recursos auxiliares internos nem detalhes de refatoração. Siga o formato estabelecido de data e issue, coloque as novas entradas na ordem esperada e indique explicitamente os riscos de compatibilidade. Alterações puramente internas sem efeito observável não precisam de uma entrada voltada aos usuários. ### Mantenha a documentação para desenvolvimento e uso Ao editar o manual, preserve âncoras de títulos estáveis e descritivas, em vez de âncoras numéricas geradas. Use as classes de conteúdo documentadas para código, exemplos da linguagem de destino, sessões de shell e diagramas. Mantenha links entre documentos ancorados em destinos estáveis e depois execute o gerador do sumário e as verificações da documentação. A documentação para desenvolvimento deve explicar o modelo interno de objetos, os atributos da árvore, o sistema de tipos e o caminho de extensão. A documentação para usuários deve se concentrar na sintaxe aceita e no comportamento observável. Verifique tanto a estrutura renderizada quanto os destinos dos links; uma edição bem-sucedida do código-fonte, por si só, não prova que o manual continue navegável.