diff --git a/fontes/analisador-semantico/analisador-semantico.ts b/fontes/analisador-semantico/analisador-semantico.ts index 1a0bfe8a..ba874f13 100644 --- a/fontes/analisador-semantico/analisador-semantico.ts +++ b/fontes/analisador-semantico/analisador-semantico.ts @@ -283,6 +283,10 @@ export class AnalisadorSemantico implements AnalisadorSemanticoInterface { if (valor.imutavel) { this.erro(expressao.simbolo, `Constante ${expressao.simbolo.lexema} não pode ser modificada.`); return Promise.resolve(); + } else { + if (this.variaveis[expressao.simbolo.lexema]) { + this.variaveis[expressao.simbolo.lexema].valor = expressao.valor; + } } } @@ -475,6 +479,9 @@ export class AnalisadorSemantico implements AnalisadorSemanticoInterface { if (!this.variaveis[variavel.simbolo.lexema]) { this.erro(variavel.simbolo, `Variável '${variavel.simbolo.lexema}' não existe.`) } + if (this.variaveis[variavel.simbolo.lexema]?.valor === undefined) { + this.aviso(variavel.simbolo, `Variável '${variavel.simbolo.lexema}' não foi inicializada.`) + } } return Promise.resolve(); @@ -509,7 +516,6 @@ export class AnalisadorSemantico implements AnalisadorSemanticoInterface { } virificarTipoDeclaracaoConst(declaracao: Const): Promise { - if (declaracao.inicializador instanceof Binario) { // verificar tipos iguais no lado esquerdo e direito const binario = declaracao.inicializador as Binario; diff --git a/testes/analisador-semantico.test.ts b/testes/analisador-semantico.test.ts index 3dcf4ba6..fce6bf18 100644 --- a/testes/analisador-semantico.test.ts +++ b/testes/analisador-semantico.test.ts @@ -792,5 +792,86 @@ describe('Analisador semântico', () => { }); }); }); + + describe('Cenários variáveis não inicializada', () => { + describe('Cenários de sucesso', () => { + it('Sucesso - variável de classe inicializada na declaração', () => { + const retornoLexador = lexador.mapear([ + "classe Teste {}", + "var teste: Teste = Teste();", + "escreva(teste); ", + ], -1); + const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); + const retornoAnalisadorSemantico = analisadorSemantico.analisar(retornoAvaliadorSintatico.declaracoes); + expect(retornoAnalisadorSemantico).toBeTruthy(); + expect(retornoAnalisadorSemantico.diagnosticos).toHaveLength(0); + }); + + it('Sucesso - variável de classe inicializada após declaração', () => { + const retornoLexador = lexador.mapear([ + "classe Teste {}", + "var teste: Teste;", + "teste = Teste();", + "escreva(teste); ", + ], -1); + const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); + const retornoAnalisadorSemantico = analisadorSemantico.analisar(retornoAvaliadorSintatico.declaracoes); + expect(retornoAnalisadorSemantico).toBeTruthy(); + expect(retornoAnalisadorSemantico.diagnosticos).toHaveLength(0); + }); + + it('Sucesso - variável tipo texto inicializada na declaração', () => { + const retornoLexador = lexador.mapear([ + "classe Teste {}", + "var teste: Texto = 'abc';", + "escreva(teste); ", + ], -1); + const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); + const retornoAnalisadorSemantico = analisadorSemantico.analisar(retornoAvaliadorSintatico.declaracoes); + expect(retornoAnalisadorSemantico).toBeTruthy(); + expect(retornoAnalisadorSemantico.diagnosticos).toHaveLength(0); + }); + + it('Sucesso - variável tipo texto inicializada após declaração', () => { + const retornoLexador = lexador.mapear([ + "classe Teste {}", + "var teste: Texto;", + "teste = 'abc';", + "escreva(teste); ", + ], -1); + const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); + const retornoAnalisadorSemantico = analisadorSemantico.analisar(retornoAvaliadorSintatico.declaracoes); + expect(retornoAnalisadorSemantico).toBeTruthy(); + expect(retornoAnalisadorSemantico.diagnosticos).toHaveLength(0); + }); + }); + describe('Cenários de falha', () => { + it('Aviso - variável de classe não inicializada', () => { + const retornoLexador = lexador.mapear([ + "classe Teste {}", + "var teste: Teste;", + "escreva(teste); ", + ], -1); + const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); + const retornoAnalisadorSemantico = analisadorSemantico.analisar(retornoAvaliadorSintatico.declaracoes); + expect(retornoAnalisadorSemantico).toBeTruthy(); + expect(retornoAnalisadorSemantico.diagnosticos).toHaveLength(1); + expect(retornoAnalisadorSemantico.diagnosticos.filter(item => item.severidade === DiagnosticoSeveridade.AVISO)).toHaveLength(1); + }); + + it('Sucesso - variável tipo texto não inicializada', () => { + const retornoLexador = lexador.mapear([ + "classe Teste {}", + "var teste: Texto;", + "escreva(teste); ", + ], -1); + const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1); + const retornoAnalisadorSemantico = analisadorSemantico.analisar(retornoAvaliadorSintatico.declaracoes); + expect(retornoAnalisadorSemantico).toBeTruthy(); + expect(retornoAnalisadorSemantico.diagnosticos).toHaveLength(1); + expect(retornoAnalisadorSemantico.diagnosticos.filter(item => item.severidade === DiagnosticoSeveridade.AVISO)).toHaveLength(1); + }); + }); + }); }); });