Repository: DesignLiquido/delegua
Pull request #516 (2023-09-26 21:19:49)

#484 Se escolha usa variável com certo tipo, verificar se opções resolve
Resolve: https://github.com/DesignLiquido/delegua/issues/484


Patch:
diff --git a/fontes/analisador-semantico/analisador-semantico.ts b/fontes/analisador-semantico/analisador-semantico.ts
index 7fd4342c..93d07771 100644
--- a/fontes/analisador-semantico/analisador-semantico.ts
+++ b/fontes/analisador-semantico/analisador-semantico.ts
@@ -37,6 +37,7 @@ interface VariavelHipoteticaInterface {
     tipo: TiposDadosInterface;
     subtipo?: 'texto' | 'número' | 'inteiro' | 'longo' | 'lógico';
     imutavel: boolean;
+    valor?: any
 }
 
 export class AnalisadorSemantico implements AnalisadorSemanticoInterface {
@@ -238,6 +239,17 @@ export class AnalisadorSemantico implements AnalisadorSemanticoInterface {
     }
 
     visitarDeclaracaoEscolha(declaracao: Escolha) {
+        const identificadorOuLiteral = declaracao.identificadorOuLiteral as any;
+        const valor = this.variaveis[identificadorOuLiteral.simbolo?.lexema]?.valor;
+        const tipo = typeof valor;
+        for (let caminho of declaracao.caminhos) {
+            for (let condicao of caminho.condicoes) {
+                if(typeof condicao?.valor !== tipo) {
+                    this.erro(condicao, `'caso ${condicao.valor}:' não é do mesmo tipo esperado em 'escolha'`);
+                }
+            }
+        }
+
         return Promise.resolve();
     }
 
@@ -280,6 +292,7 @@ export class AnalisadorSemantico implements AnalisadorSemanticoInterface {
             this.variaveis[declaracao.simbolo.lexema] = {
                 imutavel: true,
                 tipo: declaracao.tipo,
+                valor: declaracao.inicializador.valor
             };
         }
 
@@ -297,6 +310,7 @@ export class AnalisadorSemantico implements AnalisadorSemanticoInterface {
         this.variaveis[declaracao.simbolo.lexema] = {
             imutavel: false,
             tipo: declaracao.tipo,
+            valor: declaracao.inicializador.valor
         };
 
         return Promise.resolve();


Test patch:
diff --git a/testes/analisador-semantico.test.ts b/testes/analisador-semantico.test.ts
index 86e04f05..a894b77d 100644
--- a/testes/analisador-semantico.test.ts
+++ b/testes/analisador-semantico.test.ts
@@ -242,6 +242,25 @@ describe('Analisador semântico', () => {
                 expect(retornoAnalisadorSemantico).toBeTruthy();
                 expect(retornoAnalisadorSemantico.erros[0].mensagem).toBe('Declaração de retorno da função é inválido.');
             });
+
+            it('Escolha com tipos diferentes em \'caso\'', () => {
+                const retornoLexador = lexador.mapear([
+                    'var opcao: texto = \'1\'',
+                    'escolha opcao {',
+                        'caso 0:',
+                        'caso 1: // Avisar aqui que tipo de `opcao` não é o mesmo tipo do literal 1',
+                            'facaAlgumaCoisa()',
+                        'caso \'1\': // Aqui o tipo está correto, então não precisa avisar.',
+                            'facaAlgumaCoisa()',
+                    '}',
+                ], -1);
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+                const retornoAnalisadorSemantico = analisadorSemantico.analisar(retornoAvaliadorSintatico.declaracoes);
+    
+                expect(retornoAnalisadorSemantico).toBeTruthy();
+                expect(retornoAnalisadorSemantico.erros[0].mensagem).toBe('\'caso 0:\' não é do mesmo tipo esperado em \'escolha\'');
+                expect(retornoAnalisadorSemantico.erros[1].mensagem).toBe('\'caso 1:\' não é do mesmo tipo esperado em \'escolha\'');
+            });
         });
     });
 });