@designliquido/delegua 1.15.5 → 1.16.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 (67) hide show
  1. package/analisador-semantico/analisador-semantico-base.d.ts +6 -2
  2. package/analisador-semantico/analisador-semantico-base.d.ts.map +1 -1
  3. package/analisador-semantico/analisador-semantico-base.js +30 -7
  4. package/analisador-semantico/analisador-semantico-base.js.map +1 -1
  5. package/analisador-semantico/analisador-semantico.d.ts +15 -5
  6. package/analisador-semantico/analisador-semantico.d.ts.map +1 -1
  7. package/analisador-semantico/analisador-semantico.js +153 -67
  8. package/analisador-semantico/analisador-semantico.js.map +1 -1
  9. package/analisador-semantico/dialetos/analisador-semantico-pitugues.d.ts +6 -1
  10. package/analisador-semantico/dialetos/analisador-semantico-pitugues.d.ts.map +1 -1
  11. package/analisador-semantico/dialetos/analisador-semantico-pitugues.js +31 -35
  12. package/analisador-semantico/dialetos/analisador-semantico-pitugues.js.map +1 -1
  13. package/avaliador-sintatico/avaliador-sintatico-base.d.ts.map +1 -1
  14. package/avaliador-sintatico/avaliador-sintatico-base.js +10 -1
  15. package/avaliador-sintatico/avaliador-sintatico-base.js.map +1 -1
  16. package/avaliador-sintatico/avaliador-sintatico.d.ts.map +1 -1
  17. package/avaliador-sintatico/avaliador-sintatico.js +19 -6
  18. package/avaliador-sintatico/avaliador-sintatico.js.map +1 -1
  19. package/bin/package.json +1 -1
  20. package/declaracoes/classe.d.ts +2 -1
  21. package/declaracoes/classe.d.ts.map +1 -1
  22. package/declaracoes/classe.js +2 -1
  23. package/declaracoes/classe.js.map +1 -1
  24. package/declaracoes/extensao.d.ts +3 -0
  25. package/declaracoes/extensao.d.ts.map +1 -1
  26. package/declaracoes/extensao.js +3 -0
  27. package/declaracoes/extensao.js.map +1 -1
  28. package/formatadores/formatador-delegua.d.ts +18 -9
  29. package/formatadores/formatador-delegua.d.ts.map +1 -1
  30. package/formatadores/formatador-delegua.js +176 -4
  31. package/formatadores/formatador-delegua.js.map +1 -1
  32. package/interfaces/analisador-semantico-interface.d.ts +1 -0
  33. package/interfaces/analisador-semantico-interface.d.ts.map +1 -1
  34. package/interfaces/formatador/index.d.ts +2 -0
  35. package/interfaces/formatador/index.d.ts.map +1 -0
  36. package/interfaces/formatador/index.js +18 -0
  37. package/interfaces/formatador/index.js.map +1 -0
  38. package/interfaces/formatador/opcoes-formatador-delegua-interface.d.ts +5 -0
  39. package/interfaces/formatador/opcoes-formatador-delegua-interface.d.ts.map +1 -0
  40. package/interfaces/formatador/opcoes-formatador-delegua-interface.js +3 -0
  41. package/interfaces/formatador/opcoes-formatador-delegua-interface.js.map +1 -0
  42. package/interpretador/estruturas/descritor-tipo-classe.d.ts +4 -3
  43. package/interpretador/estruturas/descritor-tipo-classe.d.ts.map +1 -1
  44. package/interpretador/estruturas/descritor-tipo-classe.js +9 -3
  45. package/interpretador/estruturas/descritor-tipo-classe.js.map +1 -1
  46. package/interpretador/interpretador-base.d.ts.map +1 -1
  47. package/interpretador/interpretador-base.js +3 -2
  48. package/interpretador/interpretador-base.js.map +1 -1
  49. package/lexador/palavras-reservadas.d.ts +1 -0
  50. package/lexador/palavras-reservadas.d.ts.map +1 -1
  51. package/lexador/palavras-reservadas.js +1 -0
  52. package/lexador/palavras-reservadas.js.map +1 -1
  53. package/package.json +1 -1
  54. package/tipos-de-simbolos/delegua.d.ts +1 -0
  55. package/tipos-de-simbolos/delegua.d.ts.map +1 -1
  56. package/tipos-de-simbolos/delegua.js +1 -0
  57. package/tipos-de-simbolos/delegua.js.map +1 -1
  58. package/tipos.d.ts +7 -0
  59. package/tipos.d.ts.map +1 -1
  60. package/tradutores/tradutor-elixir.d.ts +1 -0
  61. package/tradutores/tradutor-elixir.d.ts.map +1 -1
  62. package/tradutores/tradutor-elixir.js +31 -9
  63. package/tradutores/tradutor-elixir.js.map +1 -1
  64. package/tradutores/tradutor-mermaidjs.d.ts.map +1 -1
  65. package/tradutores/tradutor-mermaidjs.js +3 -2
  66. package/tradutores/tradutor-mermaidjs.js.map +1 -1
  67. package/umd/delegua.js +443 -104
package/umd/delegua.js CHANGED
@@ -5,16 +5,25 @@ exports.AnalisadorSemanticoBase = void 0;
5
5
  const construtos_1 = require("../construtos");
6
6
  const declaracoes_1 = require("../declaracoes");
7
7
  const interfaces_1 = require("../interfaces");
8
+ const quebras_1 = require("../quebras");
9
+ const gerenciador_escopos_1 = require("./gerenciador-escopos");
8
10
  /**
9
11
  * Essa classe só existe para eliminar redundância entre todos os analisadores
10
12
  * semânticos. Por padrão, quando um método não é implementado, ao invés de dar erro,
11
13
  * simplesmente passa por ele (`return Promise.resolve()`).
12
14
  */
13
15
  class AnalisadorSemanticoBase {
16
+ constructor() {
17
+ this.gerenciadorEscopos = new gerenciador_escopos_1.GerenciadorEscopos();
18
+ this.diagnosticos = [];
19
+ }
14
20
  diagnosticoJaExiste(simbolo, mensagem) {
15
- return this.diagnosticos.some((d) => d.linha === simbolo.linha &&
16
- d.mensagem === mensagem &&
17
- d.simbolo.lexema === simbolo.lexema);
21
+ return this.diagnosticos.some((d) => {
22
+ var _a;
23
+ return d.linha === simbolo.linha &&
24
+ d.mensagem === mensagem &&
25
+ ((_a = d.simbolo) === null || _a === void 0 ? void 0 : _a.lexema) === simbolo.lexema;
26
+ });
18
27
  }
19
28
  erro(simbolo, mensagem) {
20
29
  if (this.diagnosticoJaExiste(simbolo, mensagem)) {
@@ -156,6 +165,10 @@ class AnalisadorSemanticoBase {
156
165
  * Marca as variáveis usadas em uma expressão.
157
166
  */
158
167
  marcarVariaveisUsadasEmExpressao(expressao) {
168
+ if (expressao instanceof declaracoes_1.Expressao) {
169
+ this.marcarVariaveisUsadasEmExpressao(expressao.expressao);
170
+ return;
171
+ }
159
172
  if (expressao instanceof construtos_1.Variavel) {
160
173
  this.gerenciadorEscopos.marcarComoUsada(expressao.simbolo.lexema);
161
174
  return;
@@ -202,8 +215,18 @@ class AnalisadorSemanticoBase {
202
215
  }
203
216
  return;
204
217
  }
218
+ if (expressao instanceof construtos_1.Literal && typeof expressao.valor === 'string') {
219
+ this.verificarInterpolacaoTexto(expressao.valor, expressao);
220
+ return;
221
+ }
205
222
  // TODO: Adicionar outros tipos de expressões conforme necessário.
206
223
  }
224
+ /**
225
+ * Stub para ser sobrescrito por subclasses que implementam análise de interpolações.
226
+ */
227
+ verificarInterpolacaoTexto(_texto, _literal) {
228
+ // implementado nas subclasses
229
+ }
207
230
  /**
208
231
  * Analisa se todos os caminhos retornam
209
232
  * @returns true se todos os caminhos retornam, false caso contrário
@@ -390,7 +413,7 @@ class AnalisadorSemanticoBase {
390
413
  return Promise.resolve();
391
414
  }
392
415
  visitarExpressaoContinua(declaracao) {
393
- return null;
416
+ return new quebras_1.ContinuarQuebra();
394
417
  }
395
418
  visitarExpressaoDeChamada(expressao) {
396
419
  return Promise.resolve();
@@ -408,7 +431,7 @@ class AnalisadorSemanticoBase {
408
431
  return Promise.resolve();
409
432
  }
410
433
  visitarExpressaoExpressaoRegular(expressao) {
411
- return;
434
+ return Promise.resolve(new RegExp(''));
412
435
  }
413
436
  visitarDeclaracaoEscrevaMesmaLinha(declaracao) {
414
437
  return Promise.resolve();
@@ -435,13 +458,13 @@ class AnalisadorSemanticoBase {
435
458
  return Promise.resolve();
436
459
  }
437
460
  visitarExpressaoRetornar(declaracao) {
438
- return;
461
+ return Promise.resolve(new quebras_1.RetornoQuebra(null));
439
462
  }
440
463
  visitarExpressaoSuper(expressao) {
441
464
  return Promise.resolve();
442
465
  }
443
466
  visitarExpressaoSustar(declaracao) {
444
- return null;
467
+ return new quebras_1.SustarQuebra();
445
468
  }
446
469
  visitarExpressaoTupla(expressao) {
447
470
  return Promise.resolve();
@@ -458,7 +481,7 @@ class AnalisadorSemanticoBase {
458
481
  }
459
482
  exports.AnalisadorSemanticoBase = AnalisadorSemanticoBase;
460
483
 
461
- },{"../construtos":62,"../declaracoes":110,"../interfaces":149}],2:[function(require,module,exports){
484
+ },{"../construtos":62,"../declaracoes":110,"../interfaces":149,"../quebras":216,"./gerenciador-escopos":5}],2:[function(require,module,exports){
462
485
  "use strict";
463
486
  Object.defineProperty(exports, "__esModule", { value: true });
464
487
  exports.AnalisadorSemantico = void 0;
@@ -466,6 +489,8 @@ const construtos_1 = require("../construtos");
466
489
  const declaracoes_1 = require("../declaracoes");
467
490
  const erros_1 = require("../interfaces/erros");
468
491
  const comum_1 = require("../avaliador-sintatico/comum");
492
+ const micro_avaliador_sintatico_1 = require("../avaliador-sintatico/micro-avaliador-sintatico");
493
+ const micro_lexador_1 = require("../lexador/micro-lexador");
469
494
  const analisador_semantico_base_1 = require("./analisador-semantico-base");
470
495
  const gerenciador_escopos_1 = require("./gerenciador-escopos");
471
496
  const pilha_variaveis_1 = require("./pilha-variaveis");
@@ -475,15 +500,21 @@ const pilha_variaveis_1 = require("./pilha-variaveis");
475
500
  class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemanticoBase {
476
501
  constructor() {
477
502
  super();
503
+ this.microLexador = new micro_lexador_1.MicroLexador();
504
+ this.microAvaliadorSintatico = new micro_avaliador_sintatico_1.MicroAvaliadorSintatico();
478
505
  this.pilhaVariaveis = new pilha_variaveis_1.PilhaVariaveis();
479
506
  this.gerenciadorEscopos = new gerenciador_escopos_1.GerenciadorEscopos();
480
507
  this.funcoes = {};
481
- this.classesDeclararadas = new Set();
508
+ this.classesDeclaradas = new Set();
482
509
  this.classesRegistradas = new Map();
510
+ this.classesExternasConhecidas = new Set();
483
511
  this.classeAtualEmAnalise = null;
484
512
  this.atual = 0;
485
513
  this.diagnosticos = [];
486
514
  }
515
+ definirClassesExternasConhecidas(classesExternasConhecidas) {
516
+ this.classesExternasConhecidas = new Set(classesExternasConhecidas);
517
+ }
487
518
  verificarTipoAtribuido(declaracao) {
488
519
  if (declaracao.tipo) {
489
520
  if (['vetor', 'qualquer[]', 'inteiro[]', 'texto[]'].includes(declaracao.tipo)) {
@@ -668,6 +699,8 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
668
699
  }
669
700
  // Marca como inicializada após atribuição
670
701
  this.gerenciadorEscopos.marcarComoInicializada(simboloAlvo.lexema, expressao.valor);
702
+ // Marca variáveis usadas no valor atribuído (ex: idade = ano - inteiro(leia(...))).
703
+ this.marcarVariaveisUsadasEmExpressao(expressao.valor);
671
704
  // Atualiza tipo se a variável não foi tipada explicitamente
672
705
  if (variavel.tipo === 'qualquer') {
673
706
  const tipoInferido = this.obterTipoExpressao(expressao.valor);
@@ -742,10 +775,34 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
742
775
  this.variaveis[simboloAlvo.lexema].valor = expressao.valor;
743
776
  }
744
777
  } */
778
+ return Promise.resolve();
745
779
  }
746
780
  async visitarDeclaracaoDeExpressao(declaracao) {
747
781
  return await declaracao.expressao.aceitar(this);
748
782
  }
783
+ async visitarExpressaoBloco(declaracao) {
784
+ this.gerenciadorEscopos.empilharEscopo();
785
+ try {
786
+ for (const declaracaoBloco of declaracao.declaracoes) {
787
+ await declaracaoBloco.aceitar(this);
788
+ }
789
+ }
790
+ finally {
791
+ this.gerenciadorEscopos.desempilharEscopo();
792
+ }
793
+ return Promise.resolve();
794
+ }
795
+ visitarExpressaoAcessoIndiceVariavel(expressao) {
796
+ this.marcarVariaveisUsadasEmExpressao(expressao.entidadeChamada);
797
+ this.marcarVariaveisUsadasEmExpressao(expressao.indice);
798
+ return Promise.resolve();
799
+ }
800
+ visitarExpressaoAtribuicaoPorIndice(expressao) {
801
+ this.marcarVariaveisUsadasEmExpressao(expressao.objeto);
802
+ this.marcarVariaveisUsadasEmExpressao(expressao.indice);
803
+ this.marcarVariaveisUsadasEmExpressao(expressao.valor);
804
+ return Promise.resolve();
805
+ }
749
806
  visitarDeclaracaoAjuda(declaracao) {
750
807
  if (declaracao.elemento) {
751
808
  this.marcarVariaveisUsadasEmExpressao(declaracao.elemento);
@@ -760,7 +817,7 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
760
817
  }
761
818
  visitarDeclaracaoEscolha(declaracao) {
762
819
  const identificadorOuLiteral = declaracao.identificadorOuLiteral;
763
- const tipo = identificadorOuLiteral.tipo;
820
+ const tipo = identificadorOuLiteral.tipo || 'qualquer';
764
821
  for (let caminho of declaracao.caminhos) {
765
822
  for (let condicao of caminho.condicoes) {
766
823
  switch (condicao.constructor) {
@@ -791,8 +848,16 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
791
848
  }
792
849
  return Promise.resolve();
793
850
  }
794
- visitarDeclaracaoEnquanto(declaracao) {
795
- return this.verificarCondicao(declaracao.condicao);
851
+ async visitarDeclaracaoEnquanto(declaracao) {
852
+ // Marca variáveis usadas na condição.
853
+ this.marcarVariaveisUsadasEmExpressao(declaracao.condicao);
854
+ // Verifica a condição (incluindo validações de tipo para operadores lógicos).
855
+ await this.verificarCondicao(declaracao.condicao);
856
+ // Visita corpo para que usos/atribuições dentro do laço sejam analisados.
857
+ for (const declaracaoCorpo of declaracao.corpo.declaracoes) {
858
+ await declaracaoCorpo.aceitar(this);
859
+ }
860
+ return Promise.resolve();
796
861
  }
797
862
  visitarDeclaracaoFazer(declaracao) {
798
863
  // Marca variáveis usadas na condição
@@ -801,25 +866,31 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
801
866
  return this.verificarCondicao(declaracao.condicaoEnquanto);
802
867
  }
803
868
  async visitarDeclaracaoPara(declaracao) {
804
- if (Array.isArray(declaracao.inicializador)) {
805
- for (const inicializador of declaracao.inicializador) {
806
- await inicializador.aceitar(this);
869
+ this.gerenciadorEscopos.empilharEscopo();
870
+ try {
871
+ if (Array.isArray(declaracao.inicializador)) {
872
+ for (const inicializador of declaracao.inicializador) {
873
+ await inicializador.aceitar(this);
874
+ }
875
+ }
876
+ else if (declaracao.inicializador) {
877
+ await declaracao.inicializador.aceitar(this);
878
+ }
879
+ // O laço precisa visitar condição/incremento/corpo para registrar usos de variáveis.
880
+ if (declaracao.condicao) {
881
+ this.marcarVariaveisUsadasEmExpressao(declaracao.condicao);
882
+ await this.verificarCondicao(declaracao.condicao);
883
+ }
884
+ if (declaracao.incrementar) {
885
+ this.marcarVariaveisUsadasEmExpressao(declaracao.incrementar);
886
+ this.verificarExpressao(declaracao.incrementar);
887
+ }
888
+ for (const declaracaoCorpo of declaracao.corpo.declaracoes) {
889
+ await declaracaoCorpo.aceitar(this);
807
890
  }
808
891
  }
809
- else if (declaracao.inicializador) {
810
- await declaracao.inicializador.aceitar(this);
811
- }
812
- // O laço precisa visitar condição/incremento/corpo para registrar usos de variáveis.
813
- if (declaracao.condicao) {
814
- this.marcarVariaveisUsadasEmExpressao(declaracao.condicao);
815
- await this.verificarCondicao(declaracao.condicao);
816
- }
817
- if (declaracao.incrementar) {
818
- this.marcarVariaveisUsadasEmExpressao(declaracao.incrementar);
819
- this.verificarExpressao(declaracao.incrementar);
820
- }
821
- for (const declaracaoCorpo of declaracao.corpo.declaracoes) {
822
- await declaracaoCorpo.aceitar(this);
892
+ finally {
893
+ this.gerenciadorEscopos.desempilharEscopo();
823
894
  }
824
895
  return Promise.resolve();
825
896
  }
@@ -828,11 +899,25 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
828
899
  this.marcarVariaveisUsadasEmExpressao(declaracao.vetorOuDicionario);
829
900
  return Promise.resolve();
830
901
  }
831
- visitarDeclaracaoSe(declaracao) {
902
+ async visitarDeclaracaoSe(declaracao) {
832
903
  // Marca variáveis usadas na condição
833
904
  this.marcarVariaveisUsadasEmExpressao(declaracao.condicao);
834
905
  // Verifica a condição (incluindo validação de tipos para operadores lógicos)
835
- return this.verificarCondicao(declaracao.condicao);
906
+ await this.verificarCondicao(declaracao.condicao);
907
+ if (declaracao.caminhoEntao) {
908
+ await declaracao.caminhoEntao.aceitar(this);
909
+ }
910
+ if (declaracao.caminhosSeSenao && declaracao.caminhosSeSenao.length > 0) {
911
+ for (const caminhoSeSenao of declaracao.caminhosSeSenao) {
912
+ this.marcarVariaveisUsadasEmExpressao(caminhoSeSenao.condicao);
913
+ await this.verificarCondicao(caminhoSeSenao.condicao);
914
+ await caminhoSeSenao.caminho.aceitar(this);
915
+ }
916
+ }
917
+ if (declaracao.caminhoSenao) {
918
+ await declaracao.caminhoSenao.aceitar(this);
919
+ }
920
+ return Promise.resolve();
836
921
  }
837
922
  /**
838
923
  * Verifica uma expressão recursivamente, incluindo operações binárias
@@ -979,6 +1064,9 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
979
1064
  const tipoEsquerda = this.obterTipoExpressao(binario.esquerda);
980
1065
  const tipoDireita = this.obterTipoExpressao(binario.direita);
981
1066
  const tiposNumericos = ['inteiro', 'número', 'real'];
1067
+ if (!tipoEsquerda || !tipoDireita) {
1068
+ return;
1069
+ }
982
1070
  if ((tipoEsquerda === 'texto' && tiposNumericos.includes(tipoDireita)) ||
983
1071
  (tiposNumericos.includes(tipoEsquerda) && tipoDireita === 'texto')) {
984
1072
  this.aviso(binario.operador, `Esta comparação ocorre entre tipos ${tipoEsquerda} e ${tipoDireita}, e o resultado pode não ser o desejado.`);
@@ -1133,40 +1221,24 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
1133
1221
  }
1134
1222
  }
1135
1223
  /**
1136
- * Verifica interpolações de texto e marca variáveis como usadas
1224
+ * Verifica interpolações de texto e marca variáveis como usadas,
1225
+ * compreendendo cada expressão interpolada com MicroLexador e MicroAvaliadorSintatico.
1137
1226
  */
1138
1227
  verificarInterpolacaoTexto(texto, literal) {
1139
- // Regex para encontrar ${identificador}
1140
- const regexInterpolacao = /\$\{([a-zA-Z_][a-zA-Z0-9_]*)\}/g;
1228
+ const regexInterpolacao = /\$\{(.*?)\}/g;
1141
1229
  let match;
1142
1230
  while ((match = regexInterpolacao.exec(texto)) !== null) {
1143
- const nomeVariavel = match[1];
1144
- // Verifica se a variável existe
1145
- const variavel = this.gerenciadorEscopos.buscar(nomeVariavel);
1146
- const funcao = this.funcoes[nomeVariavel];
1147
- if (!variavel && !funcao) {
1148
- this.erro({
1149
- lexema: nomeVariavel,
1150
- tipo: 'IDENTIFICADOR',
1151
- linha: literal.linha,
1152
- hashArquivo: literal.hashArquivo,
1153
- literal: null,
1154
- }, `Variável ou função '${nomeVariavel}' usada em interpolação não existe.`);
1155
- }
1156
- else if (variavel) {
1157
- // Marca como usada
1158
- this.gerenciadorEscopos.marcarComoUsada(nomeVariavel);
1159
- // Verifica se foi inicializada
1160
- if (!variavel.inicializada) {
1161
- this.aviso({
1162
- lexema: nomeVariavel,
1163
- tipo: 'IDENTIFICADOR',
1164
- linha: literal.linha,
1165
- hashArquivo: literal.hashArquivo,
1166
- literal: null,
1167
- }, `Variável '${nomeVariavel}' usada em interpolação pode não ter sido inicializada.`);
1231
+ const expressaoInterpolacao = match[1].trim();
1232
+ try {
1233
+ const retornoMicroLexador = this.microLexador.mapear(expressaoInterpolacao);
1234
+ const retornoMicro = this.microAvaliadorSintatico.analisar(retornoMicroLexador, literal.linha);
1235
+ for (const construto of retornoMicro.declaracoes) {
1236
+ this.marcarVariaveisUsadasEmExpressao(construto);
1168
1237
  }
1169
1238
  }
1239
+ catch (_) {
1240
+ // Erros de sintaxe na interpolação são tratados em tempo de execução
1241
+ }
1170
1242
  }
1171
1243
  }
1172
1244
  async visitarDeclaracaoEscreva(declaracao) {
@@ -1281,7 +1353,10 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
1281
1353
  // Inferir tipo do inicializador se não foi especificado explicitamente
1282
1354
  let tipoInferido = declaracao.tipo;
1283
1355
  if (!tipoInferido && declaracao.inicializador) {
1284
- tipoInferido = this.obterTipoExpressao(declaracao.inicializador);
1356
+ const tipoInicializador = this.obterTipoExpressao(declaracao.inicializador);
1357
+ if (tipoInicializador) {
1358
+ tipoInferido = tipoInicializador;
1359
+ }
1285
1360
  }
1286
1361
  // Sugestão de tipo melhor quando 'qualquer' é usado explicitamente
1287
1362
  if (declaracao.tipoExplicito &&
@@ -1295,8 +1370,8 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
1295
1370
  textoOriginal: 'qualquer',
1296
1371
  textoSubstituto: tipoMelhor,
1297
1372
  linha: declaracao.simbolo.linha,
1298
- colunaInicio: declaracao.simbolo.colunaInicio,
1299
- colunaFim: declaracao.simbolo.colunaFim,
1373
+ colunaInicio: declaracao.simbolo.colunaInicio || 0,
1374
+ colunaFim: declaracao.simbolo.colunaFim || 0,
1300
1375
  },
1301
1376
  ]);
1302
1377
  }
@@ -1331,7 +1406,7 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
1331
1406
  return Promise.resolve();
1332
1407
  }
1333
1408
  visitarExpressaoRetornar(declaracao) {
1334
- return Promise.resolve(null);
1409
+ return Promise.resolve(undefined);
1335
1410
  }
1336
1411
  visitarExpressaoDeVariavel(expressao) {
1337
1412
  if (expressao instanceof construtos_1.Variavel) {
@@ -1415,23 +1490,29 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
1415
1490
  if (nomeSuperclasse === declaracao.simbolo.lexema) {
1416
1491
  this.erro(superClasseVariavel.simbolo, `A classe '${declaracao.simbolo.lexema}' não pode herdar de si mesma.`);
1417
1492
  }
1418
- else if (!this.classesDeclararadas.has(nomeSuperclasse)) {
1493
+ else if (!this.classesDeclaradas.has(nomeSuperclasse) && !this.classesExternasConhecidas.has(nomeSuperclasse)) {
1419
1494
  this.erro(superClasseVariavel.simbolo, `Superclasse '${nomeSuperclasse}' não foi declarada.`);
1420
1495
  }
1421
1496
  }
1422
- this.classesDeclararadas.add(declaracao.simbolo.lexema);
1497
+ this.classesDeclaradas.add(declaracao.simbolo.lexema);
1423
1498
  this.classesRegistradas.set(declaracao.simbolo.lexema, declaracao);
1424
- // Visita corpos dos métodos com contexto de classe ativo
1499
+ // Visita corpos dos métodos com contexto de classe ativo.
1500
+ // Métodos abstratos implícitos e métodos de classes estrangeiras têm corpo vazio —
1501
+ // não há declarações para visitar.
1425
1502
  const classeAnterior = this.classeAtualEmAnalise;
1426
1503
  this.classeAtualEmAnalise = declaracao;
1427
- for (const metodo of declaracao.metodos) {
1428
- for (const stmt of metodo.funcao.corpo) {
1429
- await stmt.aceitar(this);
1504
+ if (!declaracao.estrangeira) {
1505
+ for (const metodo of declaracao.metodos) {
1506
+ if (metodo.abstrato)
1507
+ continue;
1508
+ for (const stmt of metodo.funcao.corpo) {
1509
+ await stmt.aceitar(this);
1510
+ }
1430
1511
  }
1431
1512
  }
1432
1513
  this.classeAtualEmAnalise = classeAnterior;
1433
1514
  }
1434
- visitarDeclaracaoDefinicaoFuncao(declaracao) {
1515
+ async visitarDeclaracaoDefinicaoFuncao(declaracao) {
1435
1516
  var _a;
1436
1517
  if (declaracao.funcao.tipo === undefined) {
1437
1518
  this.erro(declaracao.simbolo, `Declaração de retorno da função é inválido.`);
@@ -1447,7 +1528,10 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
1447
1528
  this.erro(declaracao.simbolo, `Função '${declaracao.simbolo.lexema}' deve retornar '${tipoRetornoFuncao}' em todos os caminhos de execução.`);
1448
1529
  }
1449
1530
  }
1450
- const retornos = declaracao.funcao.corpo.flatMap((c) => (0, comum_1.buscarRetornos)(c));
1531
+ let retornos = [];
1532
+ for (const declaracaoCorpo of declaracao.funcao.corpo) {
1533
+ retornos = retornos.concat((0, comum_1.buscarRetornos)(declaracaoCorpo));
1534
+ }
1451
1535
  // Filtra retornos com tipo 'qualquer' (não determinado em tempo de análise sintática)
1452
1536
  const retornosComTipoIndeterminado = retornos.filter((retorno) => retorno.valor !== null &&
1453
1537
  retorno.valor !== undefined &&
@@ -1458,7 +1542,8 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
1458
1542
  declaracao.funcao.tipoExplicito &&
1459
1543
  retornosComTipoIndeterminado.length > 0) {
1460
1544
  const retornoComValor = retornosComTipoIndeterminado[0];
1461
- const tipoInferido = this.obterTipoExpressao(retornoComValor.valor);
1545
+ const valorRetorno = retornoComValor.valor;
1546
+ const tipoInferido = this.obterTipoExpressao(valorRetorno);
1462
1547
  if (tipoInferido && tipoInferido !== 'qualquer') {
1463
1548
  this.erro(declaracao.simbolo, `A função não pode ter nenhum tipo de retorno. Tipo inferido do retorno: '${tipoInferido}'.`);
1464
1549
  }
@@ -1486,14 +1571,38 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
1486
1571
  this.funcoes[declaracao.simbolo.lexema] = {
1487
1572
  valor: declaracao.funcao,
1488
1573
  };
1574
+ this.gerenciadorEscopos.empilharEscopo();
1575
+ try {
1576
+ for (const parametro of declaracao.funcao.parametros) {
1577
+ this.gerenciadorEscopos.declarar(parametro.nome.lexema, {
1578
+ nome: parametro.nome.lexema,
1579
+ tipo: parametro.tipoDado || 'qualquer',
1580
+ imutavel: false,
1581
+ valor: undefined,
1582
+ inicializada: true,
1583
+ usada: false,
1584
+ hashArquivo: parametro.nome.hashArquivo,
1585
+ linha: parametro.nome.linha,
1586
+ });
1587
+ }
1588
+ for (const declaracaoCorpo of declaracao.funcao.corpo) {
1589
+ await declaracaoCorpo.aceitar(this);
1590
+ }
1591
+ }
1592
+ finally {
1593
+ this.gerenciadorEscopos.desempilharEscopo();
1594
+ }
1489
1595
  return Promise.resolve();
1490
1596
  }
1491
1597
  verificarVariaveisNaoUsadas() {
1492
1598
  const naoUsadas = this.gerenciadorEscopos.obterVariaveisNaoUsadas();
1493
1599
  for (let variavel of naoUsadas) {
1494
1600
  // Verifica se já existe um erro associado à variável.
1495
- const temErro = this.diagnosticos.some((d) => d.severidade === erros_1.DiagnosticoSeveridade.ERRO &&
1496
- d.simbolo.lexema === variavel.nome);
1601
+ const temErro = this.diagnosticos.some((d) => {
1602
+ var _a;
1603
+ return d.severidade === erros_1.DiagnosticoSeveridade.ERRO &&
1604
+ ((_a = d.simbolo) === null || _a === void 0 ? void 0 : _a.lexema) === variavel.nome;
1605
+ });
1497
1606
  // Se a variável já tem um erro associado, não emitir aviso de não usada.
1498
1607
  if (temErro) {
1499
1608
  continue;
@@ -1508,7 +1617,7 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
1508
1617
  }
1509
1618
  async analisar(declaracoes) {
1510
1619
  this.gerenciadorEscopos = new gerenciador_escopos_1.GerenciadorEscopos();
1511
- this.classesDeclararadas = new Set();
1620
+ this.classesDeclaradas = new Set();
1512
1621
  this.classesRegistradas = new Map();
1513
1622
  this.classeAtualEmAnalise = null;
1514
1623
  this.atual = 0;
@@ -1531,7 +1640,7 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
1531
1640
  }
1532
1641
  exports.AnalisadorSemantico = AnalisadorSemantico;
1533
1642
 
1534
- },{"../avaliador-sintatico/comum":11,"../construtos":62,"../declaracoes":110,"../interfaces/erros":146,"./analisador-semantico-base":1,"./gerenciador-escopos":5,"./pilha-variaveis":7}],3:[function(require,module,exports){
1643
+ },{"../avaliador-sintatico/comum":11,"../avaliador-sintatico/micro-avaliador-sintatico":24,"../construtos":62,"../declaracoes":110,"../interfaces/erros":146,"../lexador/micro-lexador":213,"./analisador-semantico-base":1,"./gerenciador-escopos":5,"./pilha-variaveis":7}],3:[function(require,module,exports){
1535
1644
  "use strict";
1536
1645
  Object.defineProperty(exports, "__esModule", { value: true });
1537
1646
 
@@ -1690,6 +1799,13 @@ const comum_1 = __importDefault(require("../tipos-de-simbolos/comum"));
1690
1799
  * de tipos de símbolos comuns entre todos os dialetos.
1691
1800
  */
1692
1801
  class AvaliadorSintaticoBase {
1802
+ constructor() {
1803
+ this.simbolos = [];
1804
+ this.erros = [];
1805
+ this.hashArquivo = -1;
1806
+ this.atual = 0;
1807
+ this.blocos = 0;
1808
+ }
1693
1809
  erro(simbolo, mensagemDeErro) {
1694
1810
  const excecao = new erro_avaliador_sintatico_1.ErroAvaliadorSintatico(simbolo, mensagemDeErro);
1695
1811
  return excecao;
@@ -1721,6 +1837,8 @@ class AvaliadorSintaticoBase {
1721
1837
  return this.simbolos[this.atual].tipo === tipo;
1722
1838
  }
1723
1839
  verificarTipoProximoSimbolo(tipo) {
1840
+ if (this.atual + 1 >= this.simbolos.length)
1841
+ return false;
1724
1842
  return this.simbolos[this.atual + 1].tipo === tipo;
1725
1843
  }
1726
1844
  estaNoFinal() {
@@ -1880,7 +1998,7 @@ class AvaliadorSintaticoBase {
1880
1998
  }
1881
1999
  const parametro = {};
1882
2000
  if (this.simbolos[this.atual].tipo === comum_1.default.MULTIPLICACAO) {
1883
- this.consumir(comum_1.default.MULTIPLICACAO, null);
2001
+ this.avancarEDevolverAnterior();
1884
2002
  parametro.abrangencia = 'multiplo';
1885
2003
  }
1886
2004
  else {
@@ -3957,12 +4075,15 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
3957
4075
  }
3958
4076
  async declaracaoDeClasse() {
3959
4077
  var _a;
3960
- // Modificadores opcionais no nível da classe: `abstrata` e/ou `estática`.
3961
- // Sintaxe: `classe abstrata NomeDaClasse` ou `classe estática NomeDaClasse`.
4078
+ // Modificadores opcionais no nível da classe: `abstrata`, `estrangeira` e/ou `estática`.
4079
+ // Sintaxe: `classe abstrata NomeDaClasse`, `classe estrangeira NomeDaClasse`, etc.
3962
4080
  let ehAbstrata = false;
4081
+ let ehEstrangeira = false;
3963
4082
  let ehEstatica = false;
3964
4083
  if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.ABSTRATO))
3965
4084
  ehAbstrata = true;
4085
+ if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.ESTRANGEIRA))
4086
+ ehEstrangeira = true;
3966
4087
  if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.ESTATICO))
3967
4088
  ehEstatica = true;
3968
4089
  // Também permite a ordem invertida: `classe estática abstrata`
@@ -4105,7 +4226,6 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
4105
4226
  params = await this.logicaComumParametros();
4106
4227
  }
4107
4228
  this.consumir(delegua_2.default.PARENTESE_DIREITO, "Esperado ')' após parâmetros do método.");
4108
- const ehAbstrato = ehAbstratoPadrao;
4109
4229
  // Tipo de retorno opcional (igual a corpoDaFuncao())
4110
4230
  let tipoRetorno = 'qualquer';
4111
4231
  let definicaoExplicitaDeTipo = false;
@@ -4114,10 +4234,21 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
4114
4234
  this.avancarEDevolverAnterior();
4115
4235
  definicaoExplicitaDeTipo = true;
4116
4236
  }
4237
+ // Método de classe estrangeira não pode ter corpo.
4238
+ if (ehEstrangeira &&
4239
+ this.verificarTipoSimboloAtual(delegua_2.default.CHAVE_ESQUERDA)) {
4240
+ throw this.erro(this.simbolos[this.atual], "Métodos de classe estrangeira não podem ter corpo.");
4241
+ }
4242
+ // Método é abstrato quando: (a) está dentro de um bloco `abstrato {}`,
4243
+ // ou (b) a classe é abstrata/estrangeira e o próximo token não é `{`.
4244
+ const ehAbstrato = ehAbstratoPadrao ||
4245
+ ehEstrangeira ||
4246
+ (ehAbstrata &&
4247
+ !this.verificarTipoSimboloAtual(delegua_2.default.CHAVE_ESQUERDA));
4117
4248
  if (ehAbstrato) {
4118
- // Método abstrato: sem corpo
4249
+ // Método abstrato/estrangeiro: sem corpo
4119
4250
  this.verificarSeSimboloAtualEIgualA(delegua_2.default.PONTO_E_VIRGULA);
4120
- const corpoVazio = new construtos_1.FuncaoConstruto(this.hashArquivo, nomeMetodo.linha, params, [], tipoRetorno);
4251
+ const corpoVazio = new construtos_1.FuncaoConstruto(this.hashArquivo, nomeMetodo.linha, params, [], tipoRetorno, definicaoExplicitaDeTipo);
4121
4252
  const metodoAbstrato = new declaracoes_1.FuncaoDeclaracao(nomeMetodo, corpoVazio, tipoRetorno);
4122
4253
  metodoAbstrato.estatico = ehEstatico;
4123
4254
  metodoAbstrato.abstrato = true;
@@ -4315,7 +4446,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
4315
4446
  }
4316
4447
  }
4317
4448
  }
4318
- const definicaoClasse = new declaracoes_1.Classe(simbolo, superClasses, metodos, propriedades, pilhaDecoradoresClasse, ehAbstrata, ehEstatica, implementaInterfaces, mesclas);
4449
+ const definicaoClasse = new declaracoes_1.Classe(simbolo, superClasses, metodos, propriedades, pilhaDecoradoresClasse, ehAbstrata, ehEstrangeira, ehEstatica, implementaInterfaces, mesclas);
4319
4450
  this.tiposDefinidosEmCodigo[definicaoClasse.simbolo.lexema] = definicaoClasse;
4320
4451
  this.superclasseAtual = undefined;
4321
4452
  return definicaoClasse;
@@ -14234,7 +14365,7 @@ class Classe extends declaracao_1.Declaracao {
14234
14365
  var _a;
14235
14366
  return (_a = this.superClasses[0]) !== null && _a !== void 0 ? _a : null;
14236
14367
  }
14237
- constructor(simbolo, superClasses = [], metodos, propriedades = [], decoradores = [], abstrata = false, classeEstatica = false, implementa = [], mesclas = []) {
14368
+ constructor(simbolo, superClasses = [], metodos, propriedades = [], decoradores = [], abstrata = false, estrangeira = false, classeEstatica = false, implementa = [], mesclas = []) {
14238
14369
  super(Number(simbolo.linha), simbolo.hashArquivo);
14239
14370
  this.simbolo = simbolo;
14240
14371
  this.superClasses = superClasses;
@@ -14243,6 +14374,7 @@ class Classe extends declaracao_1.Declaracao {
14243
14374
  this.propriedades = propriedades;
14244
14375
  this.decoradores = decoradores;
14245
14376
  this.abstrata = abstrata;
14377
+ this.estrangeira = estrangeira;
14246
14378
  this.classeEstatica = classeEstatica;
14247
14379
  this.implementa = implementa;
14248
14380
  }
@@ -14499,6 +14631,9 @@ exports.Expressao = Expressao;
14499
14631
  Object.defineProperty(exports, "__esModule", { value: true });
14500
14632
  exports.Extensao = void 0;
14501
14633
  const declaracao_1 = require("./declaracao");
14634
+ /**
14635
+ * Declaração de Extensão de Classe.
14636
+ */
14502
14637
  class Extensao extends declaracao_1.Declaracao {
14503
14638
  constructor(simboloTipo, metodos, ehGlobal, hashArquivo) {
14504
14639
  super(Number(simboloTipo.linha), hashArquivo);
@@ -15692,6 +15827,135 @@ class FormatadorDelegua {
15692
15827
  this.deveIndentar = true;
15693
15828
  this.delimitadorTexto = opcoes.delimitadorTexto || 'aspas-simples';
15694
15829
  }
15830
+ visitarDeclaracaoAjuda(declaracao) {
15831
+ this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}ajuda(`;
15832
+ if (declaracao.elemento) {
15833
+ this.formatarDeclaracaoOuConstruto(declaracao.elemento);
15834
+ }
15835
+ this.codigoFormatado += `)${this.quebraLinha}`;
15836
+ }
15837
+ visitarDeclaracaoExtensao(declaracao) {
15838
+ const global = declaracao.ehGlobal ? 'global ' : '';
15839
+ this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}extensão ${global}de ${declaracao.simboloTipo.lexema} {${this.quebraLinha}`;
15840
+ this.indentacaoAtual += this.tamanhoIndentacao;
15841
+ for (let metodo of declaracao.metodos) {
15842
+ this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}${metodo.simbolo.lexema}`;
15843
+ this.visitarExpressaoFuncaoConstruto(metodo.funcao);
15844
+ }
15845
+ this.indentacaoAtual -= this.tamanhoIndentacao;
15846
+ this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}}${this.quebraLinha}`;
15847
+ }
15848
+ visitarDeclaracaoInterface(declaracao) {
15849
+ this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}interface ${declaracao.simbolo.lexema} {${this.quebraLinha}`;
15850
+ this.indentacaoAtual += this.tamanhoIndentacao;
15851
+ for (let propriedade of declaracao.propriedades) {
15852
+ this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}${propriedade.nome.lexema}: ${propriedade.tipo || 'qualquer'}${this.quebraLinha}`;
15853
+ }
15854
+ for (let metodo of declaracao.metodos) {
15855
+ this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}${metodo.nome.lexema}(`;
15856
+ for (let parametro of metodo.parametros) {
15857
+ this.codigoFormatado += `${parametro.nome.lexema}: ${parametro.tipoDado || 'qualquer'}, `;
15858
+ }
15859
+ if (metodo.parametros.length > 0) {
15860
+ this.codigoFormatado = this.codigoFormatado.slice(0, -2);
15861
+ }
15862
+ this.codigoFormatado += `)`;
15863
+ if (metodo.tipoRetorno) {
15864
+ this.codigoFormatado += `: ${metodo.tipoRetorno}`;
15865
+ }
15866
+ this.codigoFormatado += this.quebraLinha;
15867
+ }
15868
+ this.indentacaoAtual -= this.tamanhoIndentacao;
15869
+ this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}}${this.quebraLinha}`;
15870
+ }
15871
+ visitarExpressaoAjuda(expressao) {
15872
+ this.codigoFormatado += `ajuda(`;
15873
+ if (expressao.valor) {
15874
+ this.formatarDeclaracaoOuConstruto(expressao.valor);
15875
+ }
15876
+ this.codigoFormatado += `)`;
15877
+ }
15878
+ visitarExpressaoEnquanto(expressao) {
15879
+ this.codigoFormatado += `enquanto `;
15880
+ this.formatarDeclaracaoOuConstruto(expressao.condicao);
15881
+ this.codigoFormatado += ` {${this.quebraLinha}`;
15882
+ this.indentacaoAtual += this.tamanhoIndentacao;
15883
+ for (let declaracao of expressao.corpo.declaracoes) {
15884
+ this.formatarDeclaracaoOuConstruto(declaracao);
15885
+ }
15886
+ this.indentacaoAtual -= this.tamanhoIndentacao;
15887
+ this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}}`;
15888
+ }
15889
+ visitarExpressaoElvis(expressao) {
15890
+ this.formatarDeclaracaoOuConstruto(expressao.esquerda);
15891
+ this.codigoFormatado += ` ?? `;
15892
+ this.formatarDeclaracaoOuConstruto(expressao.direita);
15893
+ }
15894
+ visitarExpressaoFazer(expressao) {
15895
+ this.codigoFormatado += `fazer {${this.quebraLinha}`;
15896
+ this.indentacaoAtual += this.tamanhoIndentacao;
15897
+ for (let declaracao of expressao.caminhoFazer.declaracoes) {
15898
+ this.formatarDeclaracaoOuConstruto(declaracao);
15899
+ }
15900
+ this.indentacaoAtual -= this.tamanhoIndentacao;
15901
+ this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}} enquanto `;
15902
+ this.formatarDeclaracaoOuConstruto(expressao.condicaoEnquanto);
15903
+ }
15904
+ visitarExpressaoListaCompreensao(listaCompreensao) {
15905
+ this.codigoFormatado += `[`;
15906
+ this.formatarDeclaracaoOuConstruto(listaCompreensao.expressaoRetorno);
15907
+ this.codigoFormatado += ` para cada `;
15908
+ this.formatarDeclaracaoOuConstruto(listaCompreensao.referenciaVariavelIteracao);
15909
+ this.codigoFormatado += ` de `;
15910
+ this.formatarDeclaracaoOuConstruto(listaCompreensao.paraCada.vetorOuDicionario);
15911
+ this.codigoFormatado += `]`;
15912
+ }
15913
+ visitarExpressaoPara(expressao) {
15914
+ this.codigoFormatado += `para `;
15915
+ this.devePularLinha = false;
15916
+ if (expressao.inicializador) {
15917
+ if (Array.isArray(expressao.inicializador)) {
15918
+ this.deveIndentar = false;
15919
+ for (let declaracaoInicializador of expressao.inicializador) {
15920
+ this.formatarDeclaracaoOuConstruto(declaracaoInicializador);
15921
+ }
15922
+ this.deveIndentar = true;
15923
+ }
15924
+ else {
15925
+ this.formatarDeclaracaoOuConstruto(expressao.inicializador);
15926
+ }
15927
+ }
15928
+ this.codigoFormatado += `; `;
15929
+ this.formatarDeclaracaoOuConstruto(expressao.condicao);
15930
+ this.codigoFormatado += `; `;
15931
+ this.formatarDeclaracaoOuConstruto(expressao.incrementar);
15932
+ this.devePularLinha = true;
15933
+ this.codigoFormatado += ` {${this.quebraLinha}`;
15934
+ this.indentacaoAtual += this.tamanhoIndentacao;
15935
+ for (let declaracao of expressao.corpo.declaracoes) {
15936
+ this.formatarDeclaracaoOuConstruto(declaracao);
15937
+ }
15938
+ this.indentacaoAtual -= this.tamanhoIndentacao;
15939
+ this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}}`;
15940
+ }
15941
+ visitarExpressaoParaCada(expressao) {
15942
+ this.codigoFormatado += `para cada ${expressao.variavelIteracao} de `;
15943
+ this.formatarDeclaracaoOuConstruto(expressao.vetorOuDicionario);
15944
+ this.codigoFormatado += ` {${this.quebraLinha}`;
15945
+ this.indentacaoAtual += this.tamanhoIndentacao;
15946
+ for (let declaracao of expressao.corpo.declaracoes) {
15947
+ this.formatarDeclaracaoOuConstruto(declaracao);
15948
+ }
15949
+ this.indentacaoAtual -= this.tamanhoIndentacao;
15950
+ this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}}`;
15951
+ }
15952
+ visitarExpressaoSeTernario(expressao) {
15953
+ this.formatarDeclaracaoOuConstruto(expressao.condicao);
15954
+ this.codigoFormatado += ` ? `;
15955
+ this.formatarDeclaracaoOuConstruto(expressao.expressaoSe);
15956
+ this.codigoFormatado += ` : `;
15957
+ this.formatarDeclaracaoOuConstruto(expressao.expressaoSenao);
15958
+ }
15695
15959
  obterDelimitadorTexto(expressao) {
15696
15960
  if (this.delimitadorTexto === 'aspas-duplas') {
15697
15961
  return '"';
@@ -15769,7 +16033,12 @@ class FormatadorDelegua {
15769
16033
  return '';
15770
16034
  }
15771
16035
  visitarDeclaracaoClasse(declaracao) {
15772
- this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}classe ${declaracao.simbolo.lexema} {${this.quebraLinha}`;
16036
+ const modificador = declaracao.estrangeira
16037
+ ? 'estrangeira '
16038
+ : declaracao.abstrata
16039
+ ? 'abstrata '
16040
+ : '';
16041
+ this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}classe ${modificador}${declaracao.simbolo.lexema} {${this.quebraLinha}`;
15773
16042
  this.indentacaoAtual += this.tamanhoIndentacao;
15774
16043
  for (let propriedade of declaracao.propriedades) {
15775
16044
  this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}${propriedade.nome.lexema}: ${propriedade.tipo || 'qualquer'}${this.quebraLinha}`;
@@ -15777,7 +16046,24 @@ class FormatadorDelegua {
15777
16046
  this.codigoFormatado += `${this.quebraLinha}`;
15778
16047
  for (let metodo of declaracao.metodos) {
15779
16048
  this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}${metodo.simbolo.lexema}`;
15780
- this.visitarExpressaoFuncaoConstruto(metodo.funcao);
16049
+ if (declaracao.estrangeira) {
16050
+ // Métodos estrangeiros: emitir apenas a assinatura, sem corpo.
16051
+ this.codigoFormatado += `(`;
16052
+ for (let argumento of metodo.funcao.parametros) {
16053
+ this.codigoFormatado += `${argumento.nome.lexema}: ${argumento.tipoDado || 'qualquer'}, `;
16054
+ }
16055
+ if (metodo.funcao.parametros.length > 0) {
16056
+ this.codigoFormatado = this.codigoFormatado.slice(0, -2);
16057
+ }
16058
+ this.codigoFormatado += `)`;
16059
+ if (metodo.funcao.tipoExplicito && metodo.funcao.tipo) {
16060
+ this.codigoFormatado += `: ${metodo.funcao.tipo}`;
16061
+ }
16062
+ this.codigoFormatado += this.quebraLinha;
16063
+ }
16064
+ else {
16065
+ this.visitarExpressaoFuncaoConstruto(metodo.funcao);
16066
+ }
15781
16067
  }
15782
16068
  this.indentacaoAtual -= this.tamanhoIndentacao;
15783
16069
  this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}}${this.quebraLinha}`;
@@ -15822,6 +16108,9 @@ class FormatadorDelegua {
15822
16108
  visitarDeclaracaoDeExpressao(declaracao) {
15823
16109
  this.codigoFormatado += ' '.repeat(this.indentacaoAtual);
15824
16110
  this.formatarDeclaracaoOuConstruto(declaracao.expressao);
16111
+ if (!this.codigoFormatado.endsWith(this.quebraLinha)) {
16112
+ this.codigoFormatado += this.quebraLinha;
16113
+ }
15825
16114
  }
15826
16115
  visitarDeclaracaoDefinicaoFuncao(declaracao) {
15827
16116
  this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}função `;
@@ -15833,7 +16122,13 @@ class FormatadorDelegua {
15833
16122
  visitarDeclaracaoEnquanto(declaracao) {
15834
16123
  this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}enquanto `;
15835
16124
  this.formatarDeclaracaoOuConstruto(declaracao.condicao);
15836
- this.formatarDeclaracaoOuConstruto(declaracao.corpo);
16125
+ this.codigoFormatado += ` {${this.quebraLinha}`;
16126
+ this.indentacaoAtual += this.tamanhoIndentacao;
16127
+ for (let declaracaoBloco of declaracao.corpo.declaracoes) {
16128
+ this.formatarDeclaracaoOuConstruto(declaracaoBloco);
16129
+ }
16130
+ this.indentacaoAtual -= this.tamanhoIndentacao;
16131
+ this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}}${this.quebraLinha}`;
15837
16132
  }
15838
16133
  visitarDeclaracaoEscolha(declaracao) {
15839
16134
  this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}escolha `;
@@ -16256,7 +16551,7 @@ class FormatadorDelegua {
16256
16551
  this.formatarDeclaracaoOuConstruto(expressao.valor);
16257
16552
  }
16258
16553
  visitarExpressaoUnaria(expressao) {
16259
- let operador;
16554
+ let operador = '';
16260
16555
  switch (expressao.operador.tipo) {
16261
16556
  case delegua_1.default.INCREMENTAR:
16262
16557
  operador = `++`;
@@ -16301,6 +16596,12 @@ class FormatadorDelegua {
16301
16596
  case construtos_1.AcessoIndiceVariavel:
16302
16597
  this.visitarExpressaoAcessoIndiceVariavel(declaracaoOuConstruto);
16303
16598
  break;
16599
+ case construtos_1.AcessoMetodo:
16600
+ this.visitarExpressaoAcessoMetodo(declaracaoOuConstruto);
16601
+ break;
16602
+ case construtos_1.AcessoPropriedade:
16603
+ this.visitarExpressaoAcessoPropriedade(declaracaoOuConstruto);
16604
+ break;
16304
16605
  case construtos_1.AcessoMetodoOuPropriedade:
16305
16606
  this.visitarExpressaoAcessoMetodoOuPropriedade(declaracaoOuConstruto);
16306
16607
  break;
@@ -16346,6 +16647,9 @@ class FormatadorDelegua {
16346
16647
  case declaracoes_1.Enquanto:
16347
16648
  this.visitarDeclaracaoEnquanto(declaracaoOuConstruto);
16348
16649
  break;
16650
+ case declaracoes_1.Extensao:
16651
+ this.visitarDeclaracaoExtensao(declaracaoOuConstruto);
16652
+ break;
16349
16653
  case declaracoes_1.Escreva:
16350
16654
  this.visitarDeclaracaoEscreva(declaracaoOuConstruto);
16351
16655
  break;
@@ -16370,6 +16674,9 @@ class FormatadorDelegua {
16370
16674
  case declaracoes_1.Importar:
16371
16675
  this.visitarDeclaracaoImportar(declaracaoOuConstruto);
16372
16676
  break;
16677
+ case declaracoes_1.InterfaceDeclaracao:
16678
+ this.visitarDeclaracaoInterface(declaracaoOuConstruto);
16679
+ break;
16373
16680
  case construtos_1.ImportarComoConstruto:
16374
16681
  this.visitarExpressaoImportar(declaracaoOuConstruto);
16375
16682
  break;
@@ -18229,6 +18536,7 @@ class DescritorTipoClasse extends chamavel_1.Chamavel {
18229
18536
  }
18230
18537
  constructor(simboloOriginal, superClasses, metodos, propriedades) {
18231
18538
  super();
18539
+ this.dialetoRequerExpansaoPropriedadesEspacoMemoria = false;
18232
18540
  this.simboloOriginal = simboloOriginal;
18233
18541
  if (Array.isArray(superClasses)) {
18234
18542
  this.superClasses = superClasses;
@@ -18250,6 +18558,7 @@ class DescritorTipoClasse extends chamavel_1.Chamavel {
18250
18558
  this.propriedades = propriedades || [];
18251
18559
  this.dialetoRequerDeclaracaoPropriedades = false;
18252
18560
  this.abstrata = false;
18561
+ this.estrangeira = false;
18253
18562
  this.classeEstatica = false;
18254
18563
  this.metodosAbstratos = [];
18255
18564
  this.acessoMetodos = {};
@@ -18272,7 +18581,7 @@ class DescritorTipoClasse extends chamavel_1.Chamavel {
18272
18581
  }
18273
18582
  }
18274
18583
  if (candidato === null) {
18275
- throw new excecoes_1.ErroEmTempoDeExecucao(null, 'Hierarquia de classes inconsistente: não foi possível calcular o OReM (C3).');
18584
+ throw new excecoes_1.ErroEmTempoDeExecucao(undefined, 'Hierarquia de classes inconsistente: não foi possível calcular o OReM (C3).');
18276
18585
  }
18277
18586
  resultado.push(candidato);
18278
18587
  for (const lista of listas) {
@@ -18420,6 +18729,7 @@ class DescritorTipoClasse extends chamavel_1.Chamavel {
18420
18729
  return new metodo_polimorfico_1.MetodoPolimorfico(nome, todasSobrecargas);
18421
18730
  }
18422
18731
  encontrarPropriedade(nome) {
18732
+ var _a;
18423
18733
  if (nome in this.propriedades) {
18424
18734
  return this.propriedades[nome];
18425
18735
  }
@@ -18429,7 +18739,7 @@ class DescritorTipoClasse extends chamavel_1.Chamavel {
18429
18739
  }
18430
18740
  }
18431
18741
  if (this.dialetoRequerDeclaracaoPropriedades) {
18432
- throw new excecoes_1.ErroEmTempoDeExecucao(this.simboloOriginal, `Propriedade "${nome}" não declarada na classe ${this.simboloOriginal.lexema}.`);
18742
+ throw new excecoes_1.ErroEmTempoDeExecucao(this.simboloOriginal, `Propriedade "${nome}" não declarada na classe ${(_a = this.simboloOriginal) === null || _a === void 0 ? void 0 : _a.lexema}.`);
18433
18743
  }
18434
18744
  return undefined;
18435
18745
  }
@@ -18460,13 +18770,16 @@ class DescritorTipoClasse extends chamavel_1.Chamavel {
18460
18770
  return inicializador ? inicializador.aridade() : 0;
18461
18771
  }
18462
18772
  async chamar(visitante, argumentos) {
18463
- var _a, _b;
18773
+ var _a, _b, _c;
18464
18774
  if (this.classeEstatica) {
18465
18775
  throw new excecoes_1.ErroEmTempoDeExecucao(this.simboloOriginal, `Não é possível instanciar a classe estática '${(_a = this.simboloOriginal) === null || _a === void 0 ? void 0 : _a.lexema}'.`);
18466
18776
  }
18467
18777
  if (this.abstrata) {
18468
18778
  throw new excecoes_1.ErroEmTempoDeExecucao(this.simboloOriginal, `Não é possível instanciar a classe abstrata '${(_b = this.simboloOriginal) === null || _b === void 0 ? void 0 : _b.lexema}'.`);
18469
18779
  }
18780
+ if (this.estrangeira) {
18781
+ throw new excecoes_1.ErroEmTempoDeExecucao(this.simboloOriginal, `Não é possível instanciar a classe estrangeira '${(_c = this.simboloOriginal) === null || _c === void 0 ? void 0 : _c.lexema}' diretamente.`);
18782
+ }
18470
18783
  const instancia = new objeto_delegua_classe_1.ObjetoDeleguaClasse(this);
18471
18784
  const inicializador = this.encontrarMetodo('construtor');
18472
18785
  if (inicializador) {
@@ -20847,6 +21160,7 @@ class InterpretadorBase {
20847
21160
  descritorTipoClasse.obtenedoresEstaticos = obtenedoresEstaticos;
20848
21161
  descritorTipoClasse.definidoresEstaticos = definidoresEstaticos;
20849
21162
  descritorTipoClasse.abstrata = declaracao.abstrata;
21163
+ descritorTipoClasse.estrangeira = declaracao.estrangeira;
20850
21164
  descritorTipoClasse.classeEstatica = declaracao.classeEstatica;
20851
21165
  descritorTipoClasse.metodosAbstratos = metodosAbstratos;
20852
21166
  descritorTipoClasse.acessoMetodos = acessoMetodos;
@@ -20887,9 +21201,9 @@ class InterpretadorBase {
20887
21201
  }
20888
21202
  // Verifica se a subclasse concreta implementa todos os métodos abstratos
20889
21203
  // da(s) superclasse(s) abstrata(s).
20890
- if (!declaracao.abstrata) {
21204
+ if (!declaracao.abstrata && !declaracao.estrangeira) {
20891
21205
  for (const superClasse of superClassesResolvidas) {
20892
- if (superClasse.abstrata) {
21206
+ if (superClasse.abstrata || superClasse.estrangeira) {
20893
21207
  superClasse.verificarImplementacaoAbstrata(descritorTipoClasse);
20894
21208
  }
20895
21209
  }
@@ -27325,6 +27639,7 @@ exports.palavrasReservadasDelegua = {
27325
27639
  enquanto: delegua_1.default.ENQUANTO,
27326
27640
  extensao: delegua_1.default.EXTENSAO,
27327
27641
  extensão: delegua_1.default.EXTENSAO,
27642
+ estrangeira: delegua_1.default.ESTRANGEIRA,
27328
27643
  estatica: delegua_1.default.ESTATICO,
27329
27644
  estática: delegua_1.default.ESTATICO,
27330
27645
  estatico: delegua_1.default.ESTATICO,
@@ -27658,6 +27973,7 @@ exports.default = {
27658
27973
  DOIS_PONTOS: 'DOIS_PONTOS',
27659
27974
  E: 'E',
27660
27975
  ELVIS: 'ELVIS',
27976
+ ESTRANGEIRA: 'ESTRANGEIRA',
27661
27977
  EXTENSAO: 'EXTENSAO',
27662
27978
  EM: 'EM',
27663
27979
  ENQUANTO: 'ENQUANTO',
@@ -44366,6 +44682,17 @@ class TradutorElixir {
44366
44682
  converterNomeModulo(nome) {
44367
44683
  return nome.charAt(0).toUpperCase() + nome.slice(1);
44368
44684
  }
44685
+ mapearTipoParaTypespec(tipo) {
44686
+ switch (tipo) {
44687
+ case 'texto': return 'String.t()';
44688
+ case 'numero':
44689
+ case 'inteiro': return 'integer()';
44690
+ case 'real': return 'float()';
44691
+ case 'logico': return 'boolean()';
44692
+ case 'vazio': return 'no_return()';
44693
+ default: return 'term()';
44694
+ }
44695
+ }
44369
44696
  /**
44370
44697
  * Gera nome único para variável temporária
44371
44698
  */
@@ -44450,16 +44777,27 @@ class TradutorElixir {
44450
44777
  this.aumentarIndentacao();
44451
44778
  const moduloAnterior = this.moduloAtual;
44452
44779
  this.moduloAtual = nomeModulo;
44453
- // Extrair campos do struct do construtor
44454
- const camposStruct = await this.extrairCamposStruct(declaracao);
44455
- if (camposStruct.length > 0) {
44456
- resultado += this.adicionarIndentacao();
44457
- resultado += `defstruct [${camposStruct.join(', ')}]\n\n`;
44780
+ if (declaracao.estrangeira) {
44781
+ // Classe estrangeira: emitir @callback para cada método, definindo a interface esperada do módulo.
44782
+ resultado += this.adicionarIndentacao() + `@moduledoc "Classe estrangeira — implementação externa."\n`;
44783
+ for (const metodo of declaracao.metodos) {
44784
+ const params = metodo.funcao.parametros.map(() => 'term()').join(', ');
44785
+ const retorno = this.mapearTipoParaTypespec(metodo.funcao.tipo);
44786
+ resultado += this.adicionarIndentacao() + `@callback ${metodo.simbolo.lexema}(${params}) :: ${retorno}\n`;
44787
+ }
44458
44788
  }
44459
- // Traduzir métodos
44460
- for (const metodo of declaracao.metodos) {
44461
- const traducaoMetodo = await this.traduzirMetodoClasse(metodo, nomeModulo);
44462
- resultado += traducaoMetodo + '\n\n';
44789
+ else {
44790
+ // Extrair campos do struct do construtor
44791
+ const camposStruct = await this.extrairCamposStruct(declaracao);
44792
+ if (camposStruct.length > 0) {
44793
+ resultado += this.adicionarIndentacao();
44794
+ resultado += `defstruct [${camposStruct.join(', ')}]\n\n`;
44795
+ }
44796
+ // Traduzir métodos
44797
+ for (const metodo of declaracao.metodos) {
44798
+ const traducaoMetodo = await this.traduzirMetodoClasse(metodo, nomeModulo);
44799
+ resultado += traducaoMetodo + '\n\n';
44800
+ }
44463
44801
  }
44464
44802
  this.diminuirIndentacao();
44465
44803
  resultado += this.adicionarIndentacao() + 'end';
@@ -46061,9 +46399,10 @@ class TradutorMermaidJs {
46061
46399
  : undefined;
46062
46400
  const linha = declaracao.linha;
46063
46401
  // Cria arestas de entrada e saída para a classe
46064
- const textoInicio = `Classe${nomeClasse}Inicio[Início: Classe ${nomeClasse}]`;
46402
+ const rotulo = declaracao.estrangeira ? 'Classe Estrangeira' : 'Classe';
46403
+ const textoInicio = `Classe${nomeClasse}Inicio[Início: ${rotulo} ${nomeClasse}]`;
46065
46404
  const arestaInicial = new mermaid_1.ArestaFluxograma(declaracao, textoInicio);
46066
- const textoFim = `Classe${nomeClasse}Fim[Fim: Classe ${nomeClasse}]`;
46405
+ const textoFim = `Classe${nomeClasse}Fim[Fim: ${rotulo} ${nomeClasse}]`;
46067
46406
  const arestaFinal = new mermaid_1.ArestaFluxograma(declaracao, textoFim);
46068
46407
  // Cria o subgrafo da classe
46069
46408
  const subgrafo = new mermaid_1.SubgrafoClasse(nomeClasse, linha, arestaInicial, arestaFinal, superClasse);