Repository: DesignLiquido/delegua
Pull request #552 (2023-11-09 17:56:23)

[delegua] analisador semântico - aviso variável não inicializada


Patch:
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<any> {
-        
         if (declaracao.inicializador instanceof Binario) {
             // verificar tipos iguais no lado esquerdo e direito
             const binario = declaracao.inicializador as Binario;


Test patch:
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);
+                });
+            });
+        });
     });
 });