Catálogo e referência de diagnóstico de linguagem antes: Tratamento de erros e exceções. Depois: Analisador Semântico AST. Índice geral: Documentação Joss. — ## O que é um diagnóstico em Joss? Um diagnóstico é um relatório técnico estruturado emitido pelas ferramentas Joss (o compilador, o analisador semântico joss analyze, o linter ou o tempo de execução defensivo) quando uma violação da sintaxe, tipo ou regras de segurança da linguagem é detectada. Ao contrário das mensagens de erro genéricas de ferramentas mais antigas, cada diagnóstico Joss é projetado seguindo estes princípios: 1. Identificador único e estável: Cada regra possui um código imutável (por exemplo JOSS-TYPE-001). 2. Local exato: Arquivo, linha e coluna precisos onde o conflito se originou. 3. Explicação pedagógica: Descreva claramente qual regra foi violada e por quê. 4. Sugestão acionável: propõe a correção canônica recomendada. ### Níveis de gravidade - error: Impede a execução do programa (joss run e o compilador para). Representa uma falha estrutural ou de segurança. - warning: Aviso informativo (como uma variável declarada que nunca foi usada ou uma convenção de nomenclatura desalinhada). joss analyze termina com o código de saída 0 se houver apenas avisos, permitindo que a execução continue. — ## 1. Analisador, carregamento do projeto e tabela de símbolos | Código | Categoria | Significado e Causa | Exemplo errado | Solução e caso correto | |—|—|—|—|—| | JOSS-IO-001 | Entrada/Saída | Não é possível ler o arquivo de origem no disco (as permissões ou o caminho não existem). | joss run fantasma.joss | Verifique se o arquivo existe no caminho indicado com permissões de leitura. | | JOSS-PARSE-001 | Sintaxe | Token ou estrutura gramatical inválida: falta de aspas, chaves ou visibilidade necessária. | class MiClase {}func prueba() {} | Use sintaxe canônica:public class MiClase {}public func prueba() {} | | JOSS-SYM-001 | Símbolos | Variável indefinida: é feita uma tentativa de ler uma variável antes de ser criada. | print($variable) | Declare e inicialize a variável antes de usá-la:$variable = "valor" | | JOSS-SYM-002 | Símbolos | Redeclaração de uma variável no mesmo escopo lexical. | int $x = 1int $x = 2 | Reatribuir sem redeclarar:$x = 2 | | JOSS-SYM-003 | Símbolos | Função não resolvida: uma função que não existe no projeto ou nos componentes internos é invocada. | calcularTotal() | Defina a função com public func ou verifique a ortografia do nome. | | JOSS-SYM-004 | Símbolos | Classe não resolvida: tentativa de instanciar (new) uma classe não declarada e não registrada. | $p = new Persona() | Declare public class Persona {} ou carregue o plugin que o expõe. | | JOSS-SYM-005 | Símbolos | Herança inválida: a classe especificada em extends não existe. | public class A extends B {} | Certifique-se de que a superclasse B esteja declarada no projeto. || JOSS-SYM-006 | Símbolos | Tente reatribuir uma constante imutável. | const int $MAX = 5$MAX = 10 | Se o valor precisar mudar, declare-o como uma variável mutável: $MAX = 5. | | JOSS-SYM-007 | Símbolos | Interface não resolvida: a interface especificada em implements ou extends não existe. | public class A implements IDesconocida {} | Certifique-se de declarar a interface ou verificar a ortografia. | | JOSS-SYM-008 | Símbolos | Herança cíclica em interfaces: Uma interface se estende direta ou indiretamente. | public interface A extends B {}public interface B extends A {} | Quebre o ciclo de herança entre interfaces. | | JOSS-DECL-001 | Declarações | Conflito de nomes: Duas funções globais possuem exatamente o mesmo identificador. | Dois arquivos com:public func procesar() {} | Renomeie uma das duas funções. No Joss não há namespaces de origem por pasta. | | JOSS-DECL-002 | Declarações | Conflito de classes: Duas classes globais têm o mesmo nome no projeto. | Dois arquivos com:public class Usuario {} | Mantenha uma única declaração canônica da classe durante todo o projeto. | | JOSS-DECL-003 | Declarações | Métodos duplicados: a mesma classe declara dois métodos com o mesmo nome. | public func id() {}public func id(int $x) {} | Joss não oferece suporte à sobrecarga de métodos por assinatura; Use nomes descritivos diferentes. | | JOSS-DECL-004 | Declarações | Conflito de nome entre interface e classe ou interfaces duplicadas. | public class Repo {}public interface Repo {} | Use nomes exclusivos para cada tipo; Convenção sugerida: Prefixo I para interfaces (IRepo). | | JOSS-DECL-005 | Declarações | Quebra de contrato de interface: falta um método ou difere em número/tipo de parâmetros, retorno ou visibilidade. | public class MiClase implements IFigura {} (sem calcularArea()) | Implemente todos os métodos de interface com visibilidade public e tipos compatíveis. | — ## 2. Tipo de sistema, chamadas e acessibilidade | Código | Categoria | Significado e Causa | Exemplo errado | Solução e caso correto | |—|—|—|—|—| | JOSS-TYPE-001 | Tipos | Reatribuição incompatível: Dados de um tipo diferente são atribuídos a uma variável digitada ou inferida. | $edad = 20$edad = "veinte" | Mantenha o tipo homogêneo ou use dinamismo voluntário:mixed $edad = 20$edad = "veinte" | | JOSS-TYPE-002 | Tipos | Valor inicial incompatível com anotação de tipo explícita. | int $x = "texto" | Forneça um valor do tipo esperado ou uma string conversível de acordo com CoerceString. | | JOSS-TYPE-003 | Tipos | Argumento incompatível com o parâmetro digitado de uma função ou método. | public func f(int $n) {}f("hola") | Passe o tipo correto ou lance o argumento antes da chamada. | | JOSS-TYPE-004 | Tipos | Operador aplicado a operandos não suportados (por exemplo, adição de texto com +). | "hola" + " mundo" | Para números de uso aritmético; Para juntar texto use o operador ponto (.): "hola" . " mundo". || JOSS-TYPE-005 | Tipos | Tipo de chave não suportado em um mapa associativo. | {[1, 2]: "valor"} | As chaves de map devem ser do tipo string. | | JOSS-TYPE-006 | Tipos | Tipo de índice incorreto para uma coleção conhecida. | $arr["clave"] (em uma matriz)$map[true] (em um mapa) | Matrizes são indexadas com números inteiros ($arr[0]); mapas com strings ($map["clave"]). | | JOSS-TYPE-007 | Tipos | Tente indexar com [...] um valor que não seja indexável (por exemplo, um número inteiro ou booleano). | $n = 42print($n[0]) | Indexe apenas matrizes, mapas, strings ou instâncias compatíveis. | | JOSS-TYPE-008 | Tipos | O valor retornado por return não corresponde ao tipo prometido na assinatura : Tipo. | public func f(): int {return "no es int"} | Retorne um valor compatível com a assinatura declarada. | | JOSS-TYPE-009 | Tipos | Tipo ou classe de dados inexistente (inclui aliases excluídos, como integer, double, boolean, any, list). | integer $x = 10boolean $flag = true | Use tipos canônicos de Joss:int $x = 10bool $flag = true | | JOSS-TYPE-010 | Tipos | A função com tipo de retorno anotado pode terminar sem executar return ou throw. | public func f(int $n): string {$n > 0 ? { return "si" } : {}} | Certifique-se de que todas as rotas possíveis retornem um valor do tipo prometido. | | JOSS-TYPE-011 | Tipos | Foi declarado um parâmetro sem tipo explícito. | public func f($x) {} | No Joss todos os parâmetros devem declarar seu tipo:public func f(int $x) {} ou public func f(mixed $x) {} | | JOSS-TYPE-012 | Aviso | Uma coleção mutável sem parâmetros é usada como uma coleção tipada. O alias original pode inserir valores incompatíveis. | array $origen = [1]array<int> $numeros = $origen | Mantenha o tipo desde a declaração ou valide e copie no limite: array<int> $origen = [1]. | | JOSS-CALL-001 | Chamadas | Número incorreto de argumentos relativos a parâmetros de assinatura conhecidos. | public func f(int $a, int $b) {}f(1) | Forneça todos os argumentos obrigatórios exigidos pela função. | | JOSS-MEMBER-001 | Membros | É feita uma tentativa de invocar um método que não existe na classe receptora resolvida. | $usuario->metodoInexistente() | Verifique o nome do método na definição de classe ou no catálogo nativo. | | JOSS-ACCESS-001 | Visibilidade | É feita uma tentativa de usar uma classe ou função declarada como private de outro arquivo. | Chame uma função privada de outro arquivo. | Declare a função ou classe como public se ela precisar ser compartilhada no projeto. | | JOSS-ACCESS-002 | Visibilidade | Tentativa de acessar uma propriedade ou método private ou protected fora de seu escopo autorizado. | $cuenta->saldo (sendo privado) | Acesso através de métodos públicos autorizados (getters/setters). | — ## 3. Referências temporárias (ref) | Código | Categoria | Significado e Causa | Solução | |—|—|—|—| | JOSS-REF-001 | Referências | Marcador bilateral ref ausente na chamada ou definição ou cruzamento ilegal para nativo/assíncrono. | Se a função espera ref int $x, a chamada deverá ser f(ref $x). | | JOSS-REF-002 | Referências | Uma expressão, literal, campo de objeto ou índice de matriz é passado como referência. | Passe apenas variáveis locais mutáveis diretas (ref $miVariable). || JOSS-REF-003 | Referências | A variável passada como referência é uma constante imutável (const). | Uma referência altera o valor original; você não pode passar constantes para um parâmetro ref. | | JOSS-REF-004 | Referências | Incompatibilidade de tipo na referência (o tipo da variável não corresponde exatamente ao parâmetro). | As referências são estritamente invariantes: um ref float requer exatamente uma variável float. | | JOSS-REF-005 | Referências | Tentativa de armazenar, capturar em fechamento, devolver ou escapar de uma referência. | Uma referência só vive durante a ligação; para retornar dados, use return. | | JOSS-REF-006 | Referências | Parâmetro ref declarado com valor padrão. | Os parâmetros por referência não permitem valores padrão; remova o = valor. | — ## 4. Controle de fluxo, linter e templates | Código | Gravidade | Significado e Causa | Solução | |—|—|—|—| | JOSS-FLOW-001 | Aviso | Código inacessível (código morto): instruções escritas após um return incondicional. | Mova as instruções antes de return ou exclua-as. | | JOSS-FLOW-002 | Aviso | Match não exaustivo em enum: uma expressão match sobre um enum não cobre todos os casos possíveis nem declara um braço default. | Adicionar os casos de enum ausentes ou incluir um ramo default => .... | | JOSS-FLOW-003 | Aviso | Acesso a membro em um valor cujo tipo ainda inclui null. | Verifique o valor contra null ou use o operador seguro ?->. | | JOSS-LINT-001 | Aviso | Variável local declarada, mas nunca lida no corpo. | Use a variável ou remova-a para manter o código limpo. | | JOSS-SYNTAX-001 | Erro | Erro de sintaxe capturado durante a fase de análise do linter. | Corrija a pontuação ou estrutura indicada pelo analisador. | | JOSS-LINT-002 | Erro | Parâmetro sem tipo explícito informado pelo linter. | Adicione a anotação de tipo correspondente (int, string, mixed). | | JOSS-LINT-007 | Aviso | Desvio das convenções de nomenclatura de projetos (classes em PascalCase, funções em camelCase). | Ajuste o nome ao padrão canônico. | | JOSS-SEC-001 | Aviso | Detecção heurística de um possível segredo confidencial escrito em texto simples (chaves de API, tokens). | Mova o segredo para o arquivo de configuração do ambiente (env.joss). | | JOSS-VIEW-001 | Erro | Falha crítica ao compilar ou analisar um modelo de visualização HTML. | Verifique as diretivas de fechamento (@foreach, @endforeach) e os arquivos incluídos. | | JOSS-VIEW-SYNTAX | Erro | Expressão Joss malformada dentro de uma tag de visualização {{ ... }}. | Corrija a sintaxe da expressão incorporada. | | JOSS-VIEW-UNDEF | Aviso | Visualize a variável acessada sem proteção contra valores indefinidos ou nulos. | Proteja com o operador de coalescência nula: {{ $variable ?? 'default' }}. | — ## 5. Erros aritméticos e indexação em tempo de execução | Código | Categoria | Operação inválida em Runtime | Como evitá-lo | |—|—|—|—| | JOSS-ARITH-001 | Tempo de execução | Estouro de inteiro assinado de 64 bits (−2⁶³ a 2⁶³−1). | Valide os limites antes de operar ou utilize o tipo decimal para cálculos em larga escala. | | JOSS-ARITH-002 | Tempo de execução | Divisão ou módulo por zero ($x / 0 ou $x % 0). | Verifique se o divisor é diferente de zero antes de executar a divisão: ($divisor != 0) ? ($x / $divisor) : 0.0. || JOSS-INDEX-001 | Tempo de execução | Índice fora da faixa: acesso à posição negativa ou maior/igual ao comprimento. | Verifique count($arr) antes de indexar ou verificar a existência com array_key_exists. | | JOSS-INDEX-002 | Tempo de execução | Tipo de índice não suportado pela estrutura de dados. | Matrizes de índice com inteiros e mapas com strings de texto. | — ## 6. Casos de teste verificados completos As operações de canal também têm defesas runtime estáveis. JOSS-CHANNEL-001 ocorre ao fechar duas vezes um canal ou enviar após o fechamento; o vizinho válido é enviar enquanto estiver aberto e fechá-lo apenas uma vez. JOSS-CHANNEL-002 ocorre com make_chan(-1); make_chan(0) é uma capacidade válida para um canal sem buffer. Esses estados podem depender de outra tarefa concorrente, então o analyzer não pode substituir a defesa runtime. Abaixo estão exemplos executáveis que validam formalmente a emissão dos diagnósticos e sua contraparte correta: ### Tipo inexistente ou alias excluído (JOSS-TYPE-009)
integer $edad = 20
Caso corrigido com tipo canônico int:
int $edad = 20
print($edad)
— ### Parâmetro sem tipo explícito (JOSS-TYPE-011)
public func duplicar($valor) { return $valor * 2 }
Caso corrigido digitando o parâmetro e o retorno:
public func duplicar(int $valor): int { return $valor * 2 }
print(duplicar(3))
— ### Remapear com tipo incompatível (JOSS-TYPE-001)
$edad = 20
$edad = "veinte"
Caso corrigido usando dinamismo voluntário (mixed):
mixed $dato = 20
$dato = "veinte"
print($dato)
— ### Estreitamento inseguro de coleção mutável (JOSS-TYPE-012)
Compatibilidade legada permite a operação, mas o analisador avisa porque os dois nomes podem compartilhar a mesma coleção mutável.
array $origen = [1]
array<int> $numeros = $origen
Caso seguro que mantém o tipo desde a origem:
array<int> $origen = [1]
array<int> $numeros = $origen
print($numeros[0])
— ### Retorno ausente nos caminhos de fluxo (JOSS-TYPE-010)
public func signo(int $n): string {
$n > 0 ? { return "positivo" } : {}
}
Caso corrigido garantindo retorno em todas as rotas possíveis:
public func signo(int $n): string {
return $n > 0 ? "positivo" : "no positivo"
}
print(signo(0))
Match não exaustivo em enum (JOSS-FLOW-002)
public enum Estado {
case Activo;
case Inactivo;
}
public func describir(Estado $e): string {
return match ($e) {
Estado::Activo => "activo",
}
}
Caso corrigido cobrindo exaustivamente todos os casos do enum:
public enum Estado {
case Activo;
case Inactivo;
}
public func describir(Estado $e): string {
return match ($e) {
Estado::Activo => "activo",
Estado::Inactivo => "inactivo",
}
}
print(describir(Estado::Activo))
— ## Próxima etapa Agora que você conhece todos os diagnósticos e como resolvê-los, você pode se aprofundar em como o analisador semântico examina a árvore de sintaxe abstrata para gerar esses códigos: Continue com: AST Static Analyzer.
Acesso potencialmente nulo (JOSS-FLOW-003)
public class Usuario { public string $nombre = "Ada" }
public func nombre(Usuario|null $usuario): string {
return $usuario->nombre
}
Caso corrigido com acesso seguro:
public class Usuario { public string $nombre = "Ada" }
public func nombre(Usuario|null $usuario): string {
return $usuario == null ? "sin usuario" : $usuario->nombre
}
print(nombre(null))