@designliquido/delegua 1.9.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/analisador-semantico/analisador-semantico-base.d.ts.map +1 -1
  2. package/analisador-semantico/analisador-semantico-base.js +6 -0
  3. package/analisador-semantico/analisador-semantico-base.js.map +1 -1
  4. package/analisador-semantico/analisador-semantico.d.ts +11 -3
  5. package/analisador-semantico/analisador-semantico.d.ts.map +1 -1
  6. package/analisador-semantico/analisador-semantico.js +96 -4
  7. package/analisador-semantico/analisador-semantico.js.map +1 -1
  8. package/avaliador-sintatico/avaliador-sintatico.d.ts +8 -1
  9. package/avaliador-sintatico/avaliador-sintatico.d.ts.map +1 -1
  10. package/avaliador-sintatico/avaliador-sintatico.js +205 -109
  11. package/avaliador-sintatico/avaliador-sintatico.js.map +1 -1
  12. package/bin/package.json +2 -2
  13. package/construtos/isto.d.ts +1 -0
  14. package/construtos/isto.d.ts.map +1 -1
  15. package/construtos/isto.js +1 -0
  16. package/construtos/isto.js.map +1 -1
  17. package/declaracoes/extensao.d.ts +13 -0
  18. package/declaracoes/extensao.d.ts.map +1 -0
  19. package/declaracoes/extensao.js +26 -0
  20. package/declaracoes/extensao.js.map +1 -0
  21. package/declaracoes/index.d.ts +1 -0
  22. package/declaracoes/index.d.ts.map +1 -1
  23. package/declaracoes/index.js +1 -0
  24. package/declaracoes/index.js.map +1 -1
  25. package/interfaces/visitante-delegua-interface.d.ts +2 -1
  26. package/interfaces/visitante-delegua-interface.d.ts.map +1 -1
  27. package/interpretador/estruturas/delegua-funcao.d.ts +3 -2
  28. package/interpretador/estruturas/delegua-funcao.d.ts.map +1 -1
  29. package/interpretador/estruturas/delegua-funcao.js +26 -2
  30. package/interpretador/estruturas/delegua-funcao.js.map +1 -1
  31. package/interpretador/interpretador-base.d.ts +13 -1
  32. package/interpretador/interpretador-base.d.ts.map +1 -1
  33. package/interpretador/interpretador-base.js +90 -15
  34. package/interpretador/interpretador-base.js.map +1 -1
  35. package/interpretador/interpretador.d.ts.map +1 -1
  36. package/interpretador/interpretador.js +76 -14
  37. package/interpretador/interpretador.js.map +1 -1
  38. package/lexador/palavras-reservadas.d.ts +2 -0
  39. package/lexador/palavras-reservadas.d.ts.map +1 -1
  40. package/lexador/palavras-reservadas.js +2 -0
  41. package/lexador/palavras-reservadas.js.map +1 -1
  42. package/package.json +2 -2
  43. package/tipos-de-simbolos/delegua.d.ts +1 -0
  44. package/tipos-de-simbolos/delegua.d.ts.map +1 -1
  45. package/tipos-de-simbolos/delegua.js +1 -0
  46. package/tipos-de-simbolos/delegua.js.map +1 -1
  47. package/umd/delegua.js +910 -523
@@ -436,55 +436,61 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
436
436
  }
437
437
  if (construto.constructor === construtos_1.AcessoMetodoOuPropriedade) {
438
438
  const construtoTipado = construto;
439
- switch (construtoTipado.tipo) {
440
- case delegua_1.default.DICIONARIO:
441
- case delegua_1.default.DICIONÁRIO:
442
- if (!(construtoTipado.simbolo.lexema in primitivas_dicionario_1.default)) {
443
- throw this.erro(construtoTipado.simbolo, `${construtoTipado.simbolo.lexema} não é uma primitiva de dicionário.`);
444
- }
445
- const primitivaDicionarioSelecionada = primitivas_dicionario_1.default[construtoTipado.simbolo.lexema];
446
- construto = new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaDicionarioSelecionada.tipoRetorno);
447
- break;
448
- case delegua_1.default.INTEIRO:
449
- case delegua_1.default.NUMERO:
450
- case delegua_1.default.NÚMERO:
451
- if (!(construtoTipado.simbolo.lexema in primitivas_numero_1.default)) {
452
- throw this.erro(construtoTipado.simbolo, `${construtoTipado.simbolo.lexema} não é uma primitiva de número.`);
453
- }
454
- const primitivaNumeroSelecionada = primitivas_numero_1.default[construtoTipado.simbolo.lexema];
455
- construto = new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaNumeroSelecionada.tipoRetorno);
456
- break;
457
- case delegua_1.default.TEXTO:
458
- if (!(construtoTipado.simbolo.lexema in primitivas_texto_1.default)) {
459
- throw this.erro(construtoTipado.simbolo, `${construtoTipado.simbolo.lexema} não é uma primitiva de texto.`);
460
- }
461
- const primitivaTextoSelecionada = primitivas_texto_1.default[construtoTipado.simbolo.lexema];
462
- construto = new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaTextoSelecionada.tipoRetorno);
463
- break;
464
- case delegua_1.default.VETOR:
465
- case delegua_1.default.VETOR_NUMERO:
466
- case delegua_1.default.VETOR_NÚMERO:
467
- case delegua_1.default.VETOR_TEXTO:
468
- if (!(construtoTipado.simbolo.lexema in primitivas_vetor_1.default)) {
469
- throw this.erro(construtoTipado.simbolo, `${construtoTipado.simbolo.lexema} não é uma primitiva de vetor.`);
470
- }
471
- const primitivaVetorSelecionada = primitivas_vetor_1.default[construtoTipado.simbolo.lexema];
472
- construto = new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaVetorSelecionada.tipoRetorno);
473
- break;
474
- default:
475
- if (construtoTipado.tipo in this.tiposDefinidosEmCodigo) {
476
- const tipoCorrespondente = this.tiposDefinidosEmCodigo[construtoTipado.tipo];
477
- const possivelMetodo = tipoCorrespondente.metodos.filter((m) => m.simbolo.lexema === construtoTipado.simbolo.lexema);
478
- if (possivelMetodo.length > 0) {
479
- construto = new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, possivelMetodo[0].tipo);
480
- break;
439
+ const acessoMetodoConhecido = this.resolverAcessoMetodoConhecido(construtoTipado);
440
+ if (acessoMetodoConhecido) {
441
+ construto = acessoMetodoConhecido;
442
+ }
443
+ else {
444
+ switch (construtoTipado.tipo) {
445
+ case delegua_1.default.DICIONARIO:
446
+ case delegua_1.default.DICIONÁRIO:
447
+ if (!(construtoTipado.simbolo.lexema in primitivas_dicionario_1.default)) {
448
+ throw this.erro(construtoTipado.simbolo, `${construtoTipado.simbolo.lexema} não é uma primitiva de dicionário.`);
481
449
  }
482
- const possivelPropriedade = tipoCorrespondente.propriedades.filter((p) => p.nome.lexema === construtoTipado.simbolo.lexema);
483
- if (possivelPropriedade.length > 0) {
484
- construto = new construtos_1.AcessoPropriedade(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, possivelPropriedade[0].tipo);
485
- break;
450
+ const primitivaDicionarioSelecionada = primitivas_dicionario_1.default[construtoTipado.simbolo.lexema];
451
+ construto = new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaDicionarioSelecionada.tipoRetorno);
452
+ break;
453
+ case delegua_1.default.INTEIRO:
454
+ case delegua_1.default.NUMERO:
455
+ case delegua_1.default.NÚMERO:
456
+ if (!(construtoTipado.simbolo.lexema in primitivas_numero_1.default)) {
457
+ throw this.erro(construtoTipado.simbolo, `${construtoTipado.simbolo.lexema} não é uma primitiva de número.`);
486
458
  }
487
- }
459
+ const primitivaNumeroSelecionada = primitivas_numero_1.default[construtoTipado.simbolo.lexema];
460
+ construto = new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaNumeroSelecionada.tipoRetorno);
461
+ break;
462
+ case delegua_1.default.TEXTO:
463
+ if (!(construtoTipado.simbolo.lexema in primitivas_texto_1.default)) {
464
+ throw this.erro(construtoTipado.simbolo, `${construtoTipado.simbolo.lexema} não é uma primitiva de texto.`);
465
+ }
466
+ const primitivaTextoSelecionada = primitivas_texto_1.default[construtoTipado.simbolo.lexema];
467
+ construto = new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaTextoSelecionada.tipoRetorno);
468
+ break;
469
+ case delegua_1.default.VETOR:
470
+ case delegua_1.default.VETOR_NUMERO:
471
+ case delegua_1.default.VETOR_NÚMERO:
472
+ case delegua_1.default.VETOR_TEXTO:
473
+ if (!(construtoTipado.simbolo.lexema in primitivas_vetor_1.default)) {
474
+ throw this.erro(construtoTipado.simbolo, `${construtoTipado.simbolo.lexema} não é uma primitiva de vetor.`);
475
+ }
476
+ const primitivaVetorSelecionada = primitivas_vetor_1.default[construtoTipado.simbolo.lexema];
477
+ construto = new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaVetorSelecionada.tipoRetorno);
478
+ break;
479
+ default:
480
+ if (construtoTipado.tipo in this.tiposDefinidosEmCodigo) {
481
+ const tipoCorrespondente = this.tiposDefinidosEmCodigo[construtoTipado.tipo];
482
+ const possivelMetodo = tipoCorrespondente.metodos.filter((m) => m.simbolo.lexema === construtoTipado.simbolo.lexema);
483
+ if (possivelMetodo.length > 0) {
484
+ construto = new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, possivelMetodo[0].tipo);
485
+ break;
486
+ }
487
+ const possivelPropriedade = tipoCorrespondente.propriedades.filter((p) => p.nome.lexema === construtoTipado.simbolo.lexema);
488
+ if (possivelPropriedade.length > 0) {
489
+ construto = new construtos_1.AcessoPropriedade(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, possivelPropriedade[0].tipo);
490
+ break;
491
+ }
492
+ }
493
+ }
488
494
  }
489
495
  }
490
496
  return new construtos_1.TipoDe(this.hashArquivo, simboloAtual, construto);
@@ -620,22 +626,26 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
620
626
  */
621
627
  resolverEntidadeChamadaAcessoMetodoOuPropriedade(entidadeChamadaResolvida) {
622
628
  const construtoTipado = entidadeChamadaResolvida;
629
+ const acessoMetodoConhecido = this.resolverAcessoMetodoConhecido(construtoTipado);
630
+ if (acessoMetodoConhecido) {
631
+ return acessoMetodoConhecido;
632
+ }
623
633
  switch (entidadeChamadaResolvida.tipo) {
624
634
  case delegua_1.default.DICIONARIO:
625
635
  case delegua_1.default.DICIONÁRIO:
626
- if (!(construtoTipado.simbolo.lexema in primitivas_dicionario_1.default)) {
627
- throw this.erro(construtoTipado.simbolo, `${construtoTipado.simbolo.lexema} não é uma primitiva de dicionário.`);
636
+ if (construtoTipado.simbolo.lexema in primitivas_dicionario_1.default) {
637
+ const primitivaDicionarioSelecionada = primitivas_dicionario_1.default[construtoTipado.simbolo.lexema];
638
+ return new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaDicionarioSelecionada.tipoRetorno);
628
639
  }
629
- const primitivaDicionarioSelecionada = primitivas_dicionario_1.default[construtoTipado.simbolo.lexema];
630
- return new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaDicionarioSelecionada.tipoRetorno);
640
+ break;
631
641
  case delegua_1.default.INTEIRO:
632
642
  case delegua_1.default.NUMERO:
633
643
  case delegua_1.default.NÚMERO:
634
- if (!(construtoTipado.simbolo.lexema in primitivas_numero_1.default)) {
635
- throw this.erro(construtoTipado.simbolo, `${construtoTipado.simbolo.lexema} não é uma primitiva de número.`);
644
+ if (construtoTipado.simbolo.lexema in primitivas_numero_1.default) {
645
+ const primitivaNumeroSelecionada = primitivas_numero_1.default[construtoTipado.simbolo.lexema];
646
+ return new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaNumeroSelecionada.tipoRetorno);
636
647
  }
637
- const primitivaNumeroSelecionada = primitivas_numero_1.default[construtoTipado.simbolo.lexema];
638
- return new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaNumeroSelecionada.tipoRetorno);
648
+ break;
639
649
  case delegua_1.default.MODULO:
640
650
  case delegua_1.default.MÓDULO:
641
651
  // Há dois casos para resolução de módulo:
@@ -648,23 +658,62 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
648
658
  }
649
659
  return new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema);
650
660
  case delegua_1.default.TEXTO:
651
- if (!(construtoTipado.simbolo.lexema in primitivas_texto_1.default)) {
652
- throw this.erro(construtoTipado.simbolo, `${construtoTipado.simbolo.lexema} não é uma primitiva de texto.`);
661
+ if (construtoTipado.simbolo.lexema in primitivas_texto_1.default) {
662
+ const primitivaTextoSelecionada = primitivas_texto_1.default[construtoTipado.simbolo.lexema];
663
+ return new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaTextoSelecionada.tipoRetorno);
653
664
  }
654
- const primitivaTextoSelecionada = primitivas_texto_1.default[construtoTipado.simbolo.lexema];
655
- return new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaTextoSelecionada.tipoRetorno);
665
+ break;
656
666
  case delegua_1.default.VETOR:
657
667
  case delegua_1.default.VETOR_NUMERO:
658
668
  case delegua_1.default.VETOR_NÚMERO:
659
669
  case delegua_1.default.VETOR_TEXTO:
660
- if (!(construtoTipado.simbolo.lexema in primitivas_vetor_1.default)) {
661
- throw this.erro(construtoTipado.simbolo, `${construtoTipado.simbolo.lexema} não é uma primitiva de vetor.`);
670
+ if (construtoTipado.simbolo.lexema in primitivas_vetor_1.default) {
671
+ const primitivaVetorSelecionada = primitivas_vetor_1.default[construtoTipado.simbolo.lexema];
672
+ return new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaVetorSelecionada.tipoRetorno);
662
673
  }
663
- const primitivaVetorSelecionada = primitivas_vetor_1.default[construtoTipado.simbolo.lexema];
664
- return new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaVetorSelecionada.tipoRetorno);
674
+ break;
665
675
  }
666
676
  return entidadeChamadaResolvida;
667
677
  }
678
+ obterTiposParaConsultaPrimitiva(tipo) {
679
+ switch (tipo) {
680
+ case delegua_1.default.DICIONARIO:
681
+ case delegua_1.default.DICIONÁRIO:
682
+ return ['dicionário'];
683
+ case delegua_1.default.INTEIRO:
684
+ case delegua_1.default.NUMERO:
685
+ case delegua_1.default.NÚMERO:
686
+ case delegua_1.default.REAL:
687
+ return ['número'];
688
+ case delegua_1.default.TEXTO:
689
+ return ['texto'];
690
+ case delegua_1.default.VETOR:
691
+ case delegua_1.default.VETOR_INTEIRO:
692
+ case delegua_1.default.VETOR_LOGICO:
693
+ case delegua_1.default.VETOR_LÓGICO:
694
+ case delegua_1.default.VETOR_NUMERO:
695
+ case delegua_1.default.VETOR_NÚMERO:
696
+ case delegua_1.default.VETOR_QUALQUER:
697
+ case delegua_1.default.VETOR_TEXTO:
698
+ return ['vetor'];
699
+ default:
700
+ return [tipo];
701
+ }
702
+ }
703
+ resolverAcessoMetodoConhecido(construtoTipado) {
704
+ const tiposParaConsulta = this.obterTiposParaConsultaPrimitiva(construtoTipado.tipo);
705
+ for (const tipoConsulta of tiposParaConsulta) {
706
+ const primitivasPorTipo = this.primitivasConhecidas[tipoConsulta];
707
+ if (!primitivasPorTipo) {
708
+ continue;
709
+ }
710
+ const informacoesPrimitiva = primitivasPorTipo[construtoTipado.simbolo.lexema];
711
+ if (informacoesPrimitiva) {
712
+ return new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, informacoesPrimitiva.tipo);
713
+ }
714
+ }
715
+ return null;
716
+ }
668
717
  validarArgumentosEntidadeChamada(argumentosEntidadeChamada, argumentosUtilizados) {
669
718
  if (argumentosEntidadeChamada.length === 0) {
670
719
  return [];
@@ -1984,10 +2033,10 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
1984
2033
  const propriedades = [];
1985
2034
  /**
1986
2035
  * Analisa membros do corpo da classe com um contexto de acesso e estático padrão.
1987
- * Suporta blocos de contexto aninhados: `estático { }`, `privado { }`, `protegido { }`, `publico { }`.
2036
+ * Suporta blocos de contexto aninhados: `estático { }`, `abstrato { }`, `privado { }`, `protegido { }`, `publico { }`.
1988
2037
  */
1989
- const compreenderMembros = async (acessoPadrao, ehEstaticoPadrao) => {
1990
- var _a, _b;
2038
+ const compreenderMembros = async (acessoPadrao, ehEstaticoPadrao, ehAbstratoPadrao = false) => {
2039
+ var _a;
1991
2040
  while (!this.verificarTipoSimboloAtual(delegua_2.default.CHAVE_DIREITA) && !this.estaNoFinal()) {
1992
2041
  // Pular comentários normais dentro do corpo da classe.
1993
2042
  if (this.simbolos[this.atual].tipo === delegua_2.default.COMENTARIO ||
@@ -2009,57 +2058,36 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
2009
2058
  // Detecção de bloco de contexto: modificador seguido de '{'
2010
2059
  const tipoAtual = this.simbolos[this.atual].tipo;
2011
2060
  const tipoProximo = (_a = this.simbolos[this.atual + 1]) === null || _a === void 0 ? void 0 : _a.tipo;
2012
- const ehBlocoAcesso = [delegua_2.default.PRIVADO, delegua_2.default.PROTEGIDO, delegua_2.default.PUBLICO].includes(tipoAtual)
2061
+ const ehBlocoAcesso = [delegua_2.default.PRIVADO, delegua_2.default.PROTEGIDO].includes(tipoAtual)
2013
2062
  && tipoProximo === delegua_2.default.CHAVE_ESQUERDA;
2014
2063
  const ehBlocoEstatico = tipoAtual === delegua_2.default.ESTATICO
2015
2064
  && tipoProximo === delegua_2.default.CHAVE_ESQUERDA;
2065
+ const ehBlocoAbstrato = tipoAtual === delegua_2.default.ABSTRATO
2066
+ && tipoProximo === delegua_2.default.CHAVE_ESQUERDA;
2016
2067
  if (ehBlocoAcesso) {
2017
- const novoAcesso = tipoAtual === delegua_2.default.PRIVADO ? 'privado' :
2018
- tipoAtual === delegua_2.default.PROTEGIDO ? 'protegido' : 'publico';
2068
+ const novoAcesso = tipoAtual === delegua_2.default.PRIVADO ? 'privado' : 'protegido';
2019
2069
  this.avancarEDevolverAnterior(); // consume modificador de acesso
2020
2070
  this.consumir(delegua_2.default.CHAVE_ESQUERDA, "Esperado '{' após modificador de acesso de bloco.");
2021
- await compreenderMembros(novoAcesso, ehEstaticoPadrao);
2071
+ await compreenderMembros(novoAcesso, ehEstaticoPadrao, ehAbstratoPadrao);
2022
2072
  this.consumir(delegua_2.default.CHAVE_DIREITA, "Esperado '}' para fechar bloco de modificador de acesso.");
2023
2073
  continue;
2024
2074
  }
2025
2075
  if (ehBlocoEstatico) {
2026
2076
  this.avancarEDevolverAnterior(); // consume 'estático'
2027
2077
  this.consumir(delegua_2.default.CHAVE_ESQUERDA, "Esperado '{' após 'estático'.");
2028
- await compreenderMembros(acessoPadrao, true);
2078
+ await compreenderMembros(acessoPadrao, true, ehAbstratoPadrao);
2029
2079
  this.consumir(delegua_2.default.CHAVE_DIREITA, "Esperado '}' para fechar bloco estático.");
2030
2080
  continue;
2031
2081
  }
2032
- // Modificador de acesso por membro (somente quando NÃO seguido de '{')
2033
- let modificadorAcesso = acessoPadrao;
2034
- if (this.simbolos[this.atual].tipo === delegua_2.default.PRIVADO) {
2035
- this.avancarEDevolverAnterior();
2036
- modificadorAcesso = 'privado';
2037
- }
2038
- else if (this.simbolos[this.atual].tipo === delegua_2.default.PROTEGIDO) {
2039
- this.avancarEDevolverAnterior();
2040
- modificadorAcesso = 'protegido';
2041
- }
2042
- else if (this.simbolos[this.atual].tipo === delegua_2.default.PUBLICO) {
2043
- this.avancarEDevolverAnterior();
2044
- modificadorAcesso = 'publico';
2045
- }
2046
- // Modificador estático por membro (somente quando NÃO seguido de '{')
2047
- let ehEstatico = ehEstaticoPadrao;
2048
- if (this.simbolos[this.atual].tipo === delegua_2.default.ESTATICO &&
2049
- ((_b = this.simbolos[this.atual + 1]) === null || _b === void 0 ? void 0 : _b.tipo) !== delegua_2.default.CHAVE_ESQUERDA) {
2050
- this.avancarEDevolverAnterior();
2051
- ehEstatico = true;
2052
- }
2053
- // Palavras-chave de acessor (obter/definir)
2054
- let eObtenedor = false;
2055
- let eDefinidor = false;
2056
- if (this.simbolos[this.atual].tipo === delegua_2.default.IDENTIFICADOR &&
2057
- ['obter', 'definir', 'obtenedor', 'definidor', 'get', 'set'].includes(String(this.simbolos[this.atual].lexema || '').toLowerCase())) {
2058
- const palavraAcessor = String(this.simbolos[this.atual].lexema || '').toLowerCase();
2059
- this.avancarEDevolverAnterior();
2060
- eObtenedor = palavraAcessor === 'obter' || palavraAcessor === 'obtenedor' || palavraAcessor === 'get';
2061
- eDefinidor = palavraAcessor === 'definir' || palavraAcessor === 'definidor' || palavraAcessor === 'set';
2082
+ if (ehBlocoAbstrato) {
2083
+ this.avancarEDevolverAnterior(); // consume 'abstrato'
2084
+ this.consumir(delegua_2.default.CHAVE_ESQUERDA, "Esperado '{' após 'abstrato'.");
2085
+ await compreenderMembros(acessoPadrao, ehEstaticoPadrao, true);
2086
+ this.consumir(delegua_2.default.CHAVE_DIREITA, "Esperado '}' para fechar bloco abstrato.");
2087
+ continue;
2062
2088
  }
2089
+ const modificadorAcesso = acessoPadrao;
2090
+ const ehEstatico = ehEstaticoPadrao;
2063
2091
  // Método operador sobrecarregado: `operador+ (outro) { ... }`
2064
2092
  if (this.simbolos[this.atual].tipo === delegua_2.default.OPERADOR) {
2065
2093
  const simboloOperadorKeyword = this.avancarEDevolverAnterior();
@@ -2103,12 +2131,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
2103
2131
  params = await this.logicaComumParametros();
2104
2132
  }
2105
2133
  this.consumir(delegua_2.default.PARENTESE_DIREITO, "Esperado ')' após parâmetros do método.");
2106
- // O modificador `abstrato` vem APÓS o fechamento dos parâmetros.
2107
- // Sintaxe: `area() abstrato: numero`
2108
- let ehAbstrato = false;
2109
- if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.ABSTRATO)) {
2110
- ehAbstrato = true;
2111
- }
2134
+ const ehAbstrato = ehAbstratoPadrao;
2112
2135
  // Tipo de retorno opcional (igual a corpoDaFuncao())
2113
2136
  let tipoRetorno = 'qualquer';
2114
2137
  let definicaoExplicitaDeTipo = false;
@@ -2152,8 +2175,6 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
2152
2175
  const tipoDaFuncao = `função<${tipoRetorno}>`;
2153
2176
  const metodo = new declaracoes_1.FuncaoDeclaracao(nomeMetodo, corpoFuncao, tipoDaFuncao);
2154
2177
  metodo.estatico = ehEstatico;
2155
- metodo.eObtenedor = eObtenedor;
2156
- metodo.eDefinidor = eDefinidor;
2157
2178
  metodo.acesso = modificadorAcesso;
2158
2179
  metodo.decoradores = Array.from(this.pilhaDecoradores);
2159
2180
  metodo.documentacao = docAtual;
@@ -2280,6 +2301,78 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
2280
2301
  this.superclasseAtual = undefined;
2281
2302
  return definicaoClasse;
2282
2303
  }
2304
+ /**
2305
+ * Analisa uma declaração de extensão:
2306
+ * `extensão [global] de <tipo> { <métodos> }`
2307
+ */
2308
+ async declaracaoDeExtensao() {
2309
+ let ehGlobal = false;
2310
+ if (this.simbolos[this.atual].tipo === delegua_2.default.IDENTIFICADOR &&
2311
+ this.simbolos[this.atual].lexema === 'global') {
2312
+ this.avancarEDevolverAnterior();
2313
+ ehGlobal = true;
2314
+ }
2315
+ this.consumir(delegua_2.default.DE, "Esperado 'de' após 'extensão'.");
2316
+ const simboloTipo = this.consumir(delegua_2.default.IDENTIFICADOR, "Esperado nome do tipo após 'de'.");
2317
+ this.consumir(delegua_2.default.CHAVE_ESQUERDA, "Esperado '{' após o nome do tipo.");
2318
+ const metodos = [];
2319
+ const nomeTipo = simboloTipo.lexema;
2320
+ if (!this.primitivasConhecidas[nomeTipo]) {
2321
+ this.primitivasConhecidas[nomeTipo] = {};
2322
+ }
2323
+ while (!this.verificarTipoSimboloAtual(delegua_2.default.CHAVE_DIREITA) && !this.estaNoFinal()) {
2324
+ // Pular comentários dentro do corpo da extensão.
2325
+ if (this.simbolos[this.atual].tipo === delegua_2.default.COMENTARIO ||
2326
+ this.simbolos[this.atual].tipo === delegua_2.default.LINHA_COMENTARIO) {
2327
+ this.avancarEDevolverAnterior();
2328
+ continue;
2329
+ }
2330
+ // Apenas métodos são suportados em extensões.
2331
+ const proximoSimbolo = this.simbolos[this.atual + 1];
2332
+ if ((proximoSimbolo === null || proximoSimbolo === void 0 ? void 0 : proximoSimbolo.tipo) !== delegua_2.default.PARENTESE_ESQUERDO) {
2333
+ throw this.erro(this.simbolos[this.atual], 'Esperado declaração de método na extensão.');
2334
+ }
2335
+ const nomeMetodo = this.avancarEDevolverAnterior();
2336
+ this.consumir(delegua_2.default.PARENTESE_ESQUERDO, "Esperado '(' após nome do método.");
2337
+ let params = [];
2338
+ if (!this.verificarTipoSimboloAtual(delegua_2.default.PARENTESE_DIREITO)) {
2339
+ params = await this.logicaComumParametros();
2340
+ }
2341
+ this.consumir(delegua_2.default.PARENTESE_DIREITO, "Esperado ')' após parâmetros do método.");
2342
+ let tipoRetorno = 'qualquer';
2343
+ let definicaoExplicitaDeTipo = false;
2344
+ if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.DOIS_PONTOS)) {
2345
+ tipoRetorno = this.verificarDefinicaoTipoAtual();
2346
+ this.avancarEDevolverAnterior();
2347
+ definicaoExplicitaDeTipo = true;
2348
+ }
2349
+ this.consumir(delegua_2.default.CHAVE_ESQUERDA, "Esperado '{' antes do corpo do método.");
2350
+ const corpo = await this.blocoEscopo();
2351
+ let expressoesRetorna = [];
2352
+ for (const declaracao of corpo) {
2353
+ expressoesRetorna = expressoesRetorna.concat((0, comum_1.buscarRetornos)(declaracao));
2354
+ }
2355
+ const tiposRetornos = new Set(expressoesRetorna.filter((e) => e.tipo !== 'qualquer').map((e) => e.tipo));
2356
+ const retornaChamadoExplicitamente = tiposRetornos.size > 0;
2357
+ tiposRetornos.delete('qualquer');
2358
+ if (tipoRetorno === 'qualquer') {
2359
+ if (tiposRetornos.size > 0) {
2360
+ tipoRetorno = tiposRetornos.values().next().value;
2361
+ }
2362
+ else if (!retornaChamadoExplicitamente && !definicaoExplicitaDeTipo) {
2363
+ tipoRetorno = 'vazio';
2364
+ }
2365
+ }
2366
+ const corpoFuncao = new construtos_1.FuncaoConstruto(this.hashArquivo, nomeMetodo.linha, params, corpo, tipoRetorno);
2367
+ const tipoDaFuncao = `função<${tipoRetorno}>`;
2368
+ const metodo = new declaracoes_1.FuncaoDeclaracao(nomeMetodo, corpoFuncao, tipoDaFuncao);
2369
+ metodos.push(metodo);
2370
+ const argumentos = params.map((parametro) => new informacao_elemento_sintatico_1.InformacaoElementoSintatico(parametro.nome.lexema, parametro.tipoDado || 'qualquer', parametro.valorPadrao === undefined));
2371
+ this.primitivasConhecidas[nomeTipo][nomeMetodo.lexema] = new informacao_elemento_sintatico_1.InformacaoElementoSintatico(nomeMetodo.lexema, tipoRetorno, true, argumentos);
2372
+ }
2373
+ this.consumir(delegua_2.default.CHAVE_DIREITA, "Esperado '}' ao final da extensão.");
2374
+ return new declaracoes_1.Extensao(simboloTipo, metodos, ehGlobal, this.hashArquivo);
2375
+ }
2283
2376
  /**
2284
2377
  * Declarações fora de bloco precisam ser verificadas primeiro por
2285
2378
  * uma série de motivos, como, por exemplo:
@@ -2317,6 +2410,9 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
2317
2410
  if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.INTERFACE)) {
2318
2411
  return await this.declaracaoDeInterface();
2319
2412
  }
2413
+ if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.EXTENSAO)) {
2414
+ return await this.declaracaoDeExtensao();
2415
+ }
2320
2416
  return await this.resolverDeclaracao();
2321
2417
  }
2322
2418
  catch (erro) {