@designliquido/delegua 1.8.1 → 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.
- package/analisador-semantico/analisador-semantico-base.d.ts.map +1 -1
- package/analisador-semantico/analisador-semantico-base.js +6 -0
- package/analisador-semantico/analisador-semantico-base.js.map +1 -1
- package/analisador-semantico/analisador-semantico.d.ts +11 -3
- package/analisador-semantico/analisador-semantico.d.ts.map +1 -1
- package/analisador-semantico/analisador-semantico.js +96 -4
- package/analisador-semantico/analisador-semantico.js.map +1 -1
- package/avaliador-sintatico/avaliador-sintatico.d.ts +18 -1
- package/avaliador-sintatico/avaliador-sintatico.d.ts.map +1 -1
- package/avaliador-sintatico/avaliador-sintatico.js +582 -123
- package/avaliador-sintatico/avaliador-sintatico.js.map +1 -1
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.d.ts +9 -2
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.d.ts.map +1 -1
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js +83 -12
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js.map +1 -1
- package/bin/package.json +2 -2
- package/construtos/comentario-como-construto.js +1 -1
- package/construtos/comentario-como-construto.js.map +1 -1
- package/construtos/isto.d.ts +1 -0
- package/construtos/isto.d.ts.map +1 -1
- package/construtos/isto.js +1 -0
- package/construtos/isto.js.map +1 -1
- package/declaracoes/classe.d.ts +4 -1
- package/declaracoes/classe.d.ts.map +1 -1
- package/declaracoes/classe.js +4 -1
- package/declaracoes/classe.js.map +1 -1
- package/declaracoes/extensao.d.ts +13 -0
- package/declaracoes/extensao.d.ts.map +1 -0
- package/declaracoes/extensao.js +26 -0
- package/declaracoes/extensao.js.map +1 -0
- package/declaracoes/funcao.d.ts +8 -2
- package/declaracoes/funcao.d.ts.map +1 -1
- package/declaracoes/funcao.js +6 -1
- package/declaracoes/funcao.js.map +1 -1
- package/declaracoes/index.d.ts +2 -0
- package/declaracoes/index.d.ts.map +1 -1
- package/declaracoes/index.js +2 -0
- package/declaracoes/index.js.map +1 -1
- package/declaracoes/interface.d.ts +27 -0
- package/declaracoes/interface.d.ts.map +1 -0
- package/declaracoes/interface.js +45 -0
- package/declaracoes/interface.js.map +1 -0
- package/declaracoes/propriedade-classe.d.ts +7 -2
- package/declaracoes/propriedade-classe.d.ts.map +1 -1
- package/declaracoes/propriedade-classe.js +5 -1
- package/declaracoes/propriedade-classe.js.map +1 -1
- package/interfaces/interpretador-interface.d.ts +2 -0
- package/interfaces/interpretador-interface.d.ts.map +1 -1
- package/interfaces/visitante-delegua-interface.d.ts +3 -1
- package/interfaces/visitante-delegua-interface.d.ts.map +1 -1
- package/interpretador/comum.d.ts.map +1 -1
- package/interpretador/comum.js +45 -0
- package/interpretador/comum.js.map +1 -1
- package/interpretador/dialetos/egua-classico/interpretador-egua-classico.d.ts +1 -0
- package/interpretador/dialetos/egua-classico/interpretador-egua-classico.d.ts.map +1 -1
- package/interpretador/dialetos/egua-classico/interpretador-egua-classico.js +3 -2
- package/interpretador/dialetos/egua-classico/interpretador-egua-classico.js.map +1 -1
- package/interpretador/dialetos/egua-classico/resolvedor/resolvedor.d.ts +1 -0
- package/interpretador/dialetos/egua-classico/resolvedor/resolvedor.d.ts.map +1 -1
- package/interpretador/dialetos/egua-classico/resolvedor/resolvedor.js +1 -0
- package/interpretador/dialetos/egua-classico/resolvedor/resolvedor.js.map +1 -1
- package/interpretador/dialetos/pitugues/comum.js +1 -1
- package/interpretador/dialetos/pitugues/comum.js.map +1 -1
- package/interpretador/dialetos/portugol-ipt/interpretador-portugol-ipt.d.ts +1 -0
- package/interpretador/dialetos/portugol-ipt/interpretador-portugol-ipt.d.ts.map +1 -1
- package/interpretador/dialetos/portugol-ipt/interpretador-portugol-ipt.js +1 -0
- package/interpretador/dialetos/portugol-ipt/interpretador-portugol-ipt.js.map +1 -1
- package/interpretador/estruturas/delegua-funcao-nativa.d.ts +18 -0
- package/interpretador/estruturas/delegua-funcao-nativa.d.ts.map +1 -0
- package/interpretador/estruturas/delegua-funcao-nativa.js +43 -0
- package/interpretador/estruturas/delegua-funcao-nativa.js.map +1 -0
- package/interpretador/estruturas/delegua-funcao.d.ts +5 -3
- package/interpretador/estruturas/delegua-funcao.d.ts.map +1 -1
- package/interpretador/estruturas/delegua-funcao.js +40 -3
- package/interpretador/estruturas/delegua-funcao.js.map +1 -1
- package/interpretador/estruturas/descritor-tipo-classe.d.ts +36 -0
- package/interpretador/estruturas/descritor-tipo-classe.d.ts.map +1 -1
- package/interpretador/estruturas/descritor-tipo-classe.js +85 -10
- package/interpretador/estruturas/descritor-tipo-classe.js.map +1 -1
- package/interpretador/estruturas/index.d.ts +2 -0
- package/interpretador/estruturas/index.d.ts.map +1 -1
- package/interpretador/estruturas/index.js +2 -0
- package/interpretador/estruturas/index.js.map +1 -1
- package/interpretador/estruturas/objeto-base.d.ts +3 -0
- package/interpretador/estruturas/objeto-base.d.ts.map +1 -0
- package/interpretador/estruturas/objeto-base.js +71 -0
- package/interpretador/estruturas/objeto-base.js.map +1 -0
- package/interpretador/estruturas/objeto-delegua-classe.d.ts +4 -3
- package/interpretador/estruturas/objeto-delegua-classe.d.ts.map +1 -1
- package/interpretador/estruturas/objeto-delegua-classe.js +98 -6
- package/interpretador/estruturas/objeto-delegua-classe.js.map +1 -1
- package/interpretador/interpretador-base.d.ts +20 -1
- package/interpretador/interpretador-base.d.ts.map +1 -1
- package/interpretador/interpretador-base.js +205 -25
- package/interpretador/interpretador-base.js.map +1 -1
- package/interpretador/interpretador.d.ts +2 -1
- package/interpretador/interpretador.d.ts.map +1 -1
- package/interpretador/interpretador.js +139 -17
- package/interpretador/interpretador.js.map +1 -1
- package/interpretador/pilha-escopos-execucao.d.ts.map +1 -1
- package/interpretador/pilha-escopos-execucao.js +5 -0
- package/interpretador/pilha-escopos-execucao.js.map +1 -1
- package/lexador/lexador.d.ts +6 -0
- package/lexador/lexador.d.ts.map +1 -1
- package/lexador/lexador.js +36 -1
- package/lexador/lexador.js.map +1 -1
- package/lexador/palavras-reservadas.d.ts +15 -0
- package/lexador/palavras-reservadas.d.ts.map +1 -1
- package/lexador/palavras-reservadas.js +15 -0
- package/lexador/palavras-reservadas.js.map +1 -1
- package/package.json +2 -2
- package/tipos-de-simbolos/delegua.d.ts +10 -0
- package/tipos-de-simbolos/delegua.d.ts.map +1 -1
- package/tipos-de-simbolos/delegua.js +10 -0
- package/tipos-de-simbolos/delegua.js.map +1 -1
- package/umd/delegua.js +2041 -591
|
@@ -51,6 +51,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
|
|
|
51
51
|
this.erros = [];
|
|
52
52
|
this.performance = performance;
|
|
53
53
|
this.tiposDefinidosEmCodigo = {};
|
|
54
|
+
this.interfacesDeclaradas = {};
|
|
54
55
|
this.tiposDeFerramentasExternas = {};
|
|
55
56
|
this.primitivasConhecidas = {};
|
|
56
57
|
this.pilhaEscopos = new pilha_escopos_1.PilhaEscopos();
|
|
@@ -435,55 +436,61 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
|
|
|
435
436
|
}
|
|
436
437
|
if (construto.constructor === construtos_1.AcessoMetodoOuPropriedade) {
|
|
437
438
|
const construtoTipado = construto;
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
case delegua_1.default.NUMERO:
|
|
449
|
-
case delegua_1.default.NÚMERO:
|
|
450
|
-
if (!(construtoTipado.simbolo.lexema in primitivas_numero_1.default)) {
|
|
451
|
-
throw this.erro(construtoTipado.simbolo, `${construtoTipado.simbolo.lexema} não é uma primitiva de número.`);
|
|
452
|
-
}
|
|
453
|
-
const primitivaNumeroSelecionada = primitivas_numero_1.default[construtoTipado.simbolo.lexema];
|
|
454
|
-
construto = new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaNumeroSelecionada.tipoRetorno);
|
|
455
|
-
break;
|
|
456
|
-
case delegua_1.default.TEXTO:
|
|
457
|
-
if (!(construtoTipado.simbolo.lexema in primitivas_texto_1.default)) {
|
|
458
|
-
throw this.erro(construtoTipado.simbolo, `${construtoTipado.simbolo.lexema} não é uma primitiva de texto.`);
|
|
459
|
-
}
|
|
460
|
-
const primitivaTextoSelecionada = primitivas_texto_1.default[construtoTipado.simbolo.lexema];
|
|
461
|
-
construto = new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaTextoSelecionada.tipoRetorno);
|
|
462
|
-
break;
|
|
463
|
-
case delegua_1.default.VETOR:
|
|
464
|
-
case delegua_1.default.VETOR_NUMERO:
|
|
465
|
-
case delegua_1.default.VETOR_NÚMERO:
|
|
466
|
-
case delegua_1.default.VETOR_TEXTO:
|
|
467
|
-
if (!(construtoTipado.simbolo.lexema in primitivas_vetor_1.default)) {
|
|
468
|
-
throw this.erro(construtoTipado.simbolo, `${construtoTipado.simbolo.lexema} não é uma primitiva de vetor.`);
|
|
469
|
-
}
|
|
470
|
-
const primitivaVetorSelecionada = primitivas_vetor_1.default[construtoTipado.simbolo.lexema];
|
|
471
|
-
construto = new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaVetorSelecionada.tipoRetorno);
|
|
472
|
-
break;
|
|
473
|
-
default:
|
|
474
|
-
if (construtoTipado.tipo in this.tiposDefinidosEmCodigo) {
|
|
475
|
-
const tipoCorrespondente = this.tiposDefinidosEmCodigo[construtoTipado.tipo];
|
|
476
|
-
const possivelMetodo = tipoCorrespondente.metodos.filter((m) => m.simbolo.lexema === construtoTipado.simbolo.lexema);
|
|
477
|
-
if (possivelMetodo.length > 0) {
|
|
478
|
-
construto = new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, possivelMetodo[0].tipo);
|
|
479
|
-
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.`);
|
|
480
449
|
}
|
|
481
|
-
const
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
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.`);
|
|
485
458
|
}
|
|
486
|
-
|
|
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
|
+
}
|
|
487
494
|
}
|
|
488
495
|
}
|
|
489
496
|
return new construtos_1.TipoDe(this.hashArquivo, simboloAtual, construto);
|
|
@@ -619,22 +626,26 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
|
|
|
619
626
|
*/
|
|
620
627
|
resolverEntidadeChamadaAcessoMetodoOuPropriedade(entidadeChamadaResolvida) {
|
|
621
628
|
const construtoTipado = entidadeChamadaResolvida;
|
|
629
|
+
const acessoMetodoConhecido = this.resolverAcessoMetodoConhecido(construtoTipado);
|
|
630
|
+
if (acessoMetodoConhecido) {
|
|
631
|
+
return acessoMetodoConhecido;
|
|
632
|
+
}
|
|
622
633
|
switch (entidadeChamadaResolvida.tipo) {
|
|
623
634
|
case delegua_1.default.DICIONARIO:
|
|
624
635
|
case delegua_1.default.DICIONÁRIO:
|
|
625
|
-
if (
|
|
626
|
-
|
|
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);
|
|
627
639
|
}
|
|
628
|
-
|
|
629
|
-
return new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaDicionarioSelecionada.tipoRetorno);
|
|
640
|
+
break;
|
|
630
641
|
case delegua_1.default.INTEIRO:
|
|
631
642
|
case delegua_1.default.NUMERO:
|
|
632
643
|
case delegua_1.default.NÚMERO:
|
|
633
|
-
if (
|
|
634
|
-
|
|
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);
|
|
635
647
|
}
|
|
636
|
-
|
|
637
|
-
return new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaNumeroSelecionada.tipoRetorno);
|
|
648
|
+
break;
|
|
638
649
|
case delegua_1.default.MODULO:
|
|
639
650
|
case delegua_1.default.MÓDULO:
|
|
640
651
|
// Há dois casos para resolução de módulo:
|
|
@@ -647,23 +658,62 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
|
|
|
647
658
|
}
|
|
648
659
|
return new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema);
|
|
649
660
|
case delegua_1.default.TEXTO:
|
|
650
|
-
if (
|
|
651
|
-
|
|
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);
|
|
652
664
|
}
|
|
653
|
-
|
|
654
|
-
return new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaTextoSelecionada.tipoRetorno);
|
|
665
|
+
break;
|
|
655
666
|
case delegua_1.default.VETOR:
|
|
656
667
|
case delegua_1.default.VETOR_NUMERO:
|
|
657
668
|
case delegua_1.default.VETOR_NÚMERO:
|
|
658
669
|
case delegua_1.default.VETOR_TEXTO:
|
|
659
|
-
if (
|
|
660
|
-
|
|
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);
|
|
661
673
|
}
|
|
662
|
-
|
|
663
|
-
return new construtos_1.AcessoMetodo(construtoTipado.hashArquivo, construtoTipado.objeto, construtoTipado.simbolo.lexema, primitivaVetorSelecionada.tipoRetorno);
|
|
674
|
+
break;
|
|
664
675
|
}
|
|
665
676
|
return entidadeChamadaResolvida;
|
|
666
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
|
+
}
|
|
667
717
|
validarArgumentosEntidadeChamada(argumentosEntidadeChamada, argumentosUtilizados) {
|
|
668
718
|
if (argumentosEntidadeChamada.length === 0) {
|
|
669
719
|
return [];
|
|
@@ -1540,6 +1590,41 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
|
|
|
1540
1590
|
this.pilhaDecoradores = [];
|
|
1541
1591
|
return retornos;
|
|
1542
1592
|
}
|
|
1593
|
+
logicaComumInferenciaTiposAcessoMetodoOuPropriedade(entidadeChamada) {
|
|
1594
|
+
// Algumas coisas podem acontecer aqui.
|
|
1595
|
+
// Uma delas é a variável/constante ser uma classe padrão.
|
|
1596
|
+
// Isso ocorre quando a importação é feita de uma biblioteca Node.js.
|
|
1597
|
+
// Nesse caso, o tipo de `entidadeChamada.objeto` começa com uma letra maiúscula.
|
|
1598
|
+
if (entidadeChamada.objeto.tipo &&
|
|
1599
|
+
entidadeChamada.objeto.tipo.match(/^[A-Z]/)) {
|
|
1600
|
+
const tipoCorrespondente = this.tiposDefinidosPorBibliotecas[entidadeChamada.objeto.tipo];
|
|
1601
|
+
if (!tipoCorrespondente) {
|
|
1602
|
+
throw new erro_avaliador_sintatico_1.ErroAvaliadorSintatico(entidadeChamada.simbolo, `Tipo '${entidadeChamada.objeto.tipo}' não foi encontrado entre os tipos definidos por bibliotecas.`);
|
|
1603
|
+
}
|
|
1604
|
+
if (!(entidadeChamada.simbolo.lexema in
|
|
1605
|
+
tipoCorrespondente.metodos) &&
|
|
1606
|
+
!(entidadeChamada.simbolo.lexema in
|
|
1607
|
+
tipoCorrespondente.propriedades)) {
|
|
1608
|
+
throw new erro_avaliador_sintatico_1.ErroAvaliadorSintatico(entidadeChamada.simbolo, `Membro '${entidadeChamada.simbolo.lexema}' não existe no tipo '${entidadeChamada.objeto.tipo}'.`);
|
|
1609
|
+
}
|
|
1610
|
+
if (entidadeChamada.simbolo.lexema in
|
|
1611
|
+
tipoCorrespondente.metodos) {
|
|
1612
|
+
const metodoCorrespondente = tipoCorrespondente.metodos[entidadeChamada.simbolo.lexema];
|
|
1613
|
+
return metodoCorrespondente.tipoRetorno || 'qualquer';
|
|
1614
|
+
}
|
|
1615
|
+
const propriedadeCorrespondente = tipoCorrespondente.propriedades[entidadeChamada.simbolo.lexema];
|
|
1616
|
+
return propriedadeCorrespondente.tipo;
|
|
1617
|
+
}
|
|
1618
|
+
// Este caso ocorre quando a variável/constante é do tipo 'qualquer',
|
|
1619
|
+
// e a chamada normalmente é feita para uma primitiva.
|
|
1620
|
+
// A inferência, portanto, ocorre pelo uso da primitiva.
|
|
1621
|
+
for (const primitiva in this.primitivasConhecidas) {
|
|
1622
|
+
if (this.primitivasConhecidas[primitiva].hasOwnProperty(entidadeChamada.simbolo.lexema)) {
|
|
1623
|
+
return this.primitivasConhecidas[primitiva][entidadeChamada.simbolo.lexema].tipo;
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
throw new erro_avaliador_sintatico_1.ErroAvaliadorSintatico(entidadeChamada.simbolo, `Primitiva '${entidadeChamada.simbolo.lexema}' não existe.`);
|
|
1627
|
+
}
|
|
1543
1628
|
logicaComumInferenciaTiposVariaveisEConstantes(inicializador, tipo) {
|
|
1544
1629
|
if (tipo !== 'qualquer') {
|
|
1545
1630
|
return tipo;
|
|
@@ -1565,40 +1650,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
|
|
|
1565
1650
|
const tipoRetornoAcessoMetodoResolvido = entidadeChamadaAcessoMetodo.tipoRetornoMetodo.replace('<T>', entidadeChamadaAcessoMetodo.objeto.tipo);
|
|
1566
1651
|
return tipoRetornoAcessoMetodoResolvido;
|
|
1567
1652
|
case construtos_1.AcessoMetodoOuPropriedade:
|
|
1568
|
-
|
|
1569
|
-
// Algumas coisas podem acontecer aqui.
|
|
1570
|
-
// Uma delas é a variável/constante ser uma classe padrão.
|
|
1571
|
-
// Isso ocorre quando a importação é feita de uma biblioteca Node.js.
|
|
1572
|
-
// Nesse caso, o tipo de `entidadeChamadaAcessoMetodoOuPropriedade.objeto` começa com uma letra maiúscula.
|
|
1573
|
-
if (entidadeChamadaAcessoMetodoOuPropriedade.objeto.tipo &&
|
|
1574
|
-
entidadeChamadaAcessoMetodoOuPropriedade.objeto.tipo.match(/^[A-Z]/)) {
|
|
1575
|
-
const tipoCorrespondente = this.tiposDefinidosPorBibliotecas[entidadeChamadaAcessoMetodoOuPropriedade.objeto.tipo];
|
|
1576
|
-
if (!tipoCorrespondente) {
|
|
1577
|
-
throw new erro_avaliador_sintatico_1.ErroAvaliadorSintatico(entidadeChamadaAcessoMetodoOuPropriedade.simbolo, `Tipo '${entidadeChamadaAcessoMetodoOuPropriedade.objeto.tipo}' não foi encontrado entre os tipos definidos por bibliotecas.`);
|
|
1578
|
-
}
|
|
1579
|
-
if (!(entidadeChamadaAcessoMetodoOuPropriedade.simbolo.lexema in
|
|
1580
|
-
tipoCorrespondente.metodos) &&
|
|
1581
|
-
!(entidadeChamadaAcessoMetodoOuPropriedade.simbolo.lexema in
|
|
1582
|
-
tipoCorrespondente.propriedades)) {
|
|
1583
|
-
throw new erro_avaliador_sintatico_1.ErroAvaliadorSintatico(entidadeChamadaAcessoMetodoOuPropriedade.simbolo, `Membro '${entidadeChamadaAcessoMetodoOuPropriedade.simbolo.lexema}' não existe no tipo '${entidadeChamadaAcessoMetodoOuPropriedade.objeto.tipo}'.`);
|
|
1584
|
-
}
|
|
1585
|
-
if (entidadeChamadaAcessoMetodoOuPropriedade.simbolo.lexema in
|
|
1586
|
-
tipoCorrespondente.metodos) {
|
|
1587
|
-
const metodoCorrespondente = tipoCorrespondente.metodos[entidadeChamadaAcessoMetodoOuPropriedade.simbolo.lexema];
|
|
1588
|
-
return metodoCorrespondente.tipoRetorno || 'qualquer';
|
|
1589
|
-
}
|
|
1590
|
-
const propriedadeCorrespondente = tipoCorrespondente.propriedades[entidadeChamadaAcessoMetodoOuPropriedade.simbolo.lexema];
|
|
1591
|
-
return propriedadeCorrespondente.tipo;
|
|
1592
|
-
}
|
|
1593
|
-
// Este caso ocorre quando a variável/constante é do tipo 'qualquer',
|
|
1594
|
-
// e a chamada normalmente é feita para uma primitiva.
|
|
1595
|
-
// A inferência, portanto, ocorre pelo uso da primitiva.
|
|
1596
|
-
for (const primitiva in this.primitivasConhecidas) {
|
|
1597
|
-
if (this.primitivasConhecidas[primitiva].hasOwnProperty(entidadeChamadaAcessoMetodoOuPropriedade.simbolo.lexema)) {
|
|
1598
|
-
return this.primitivasConhecidas[primitiva][entidadeChamadaAcessoMetodoOuPropriedade.simbolo.lexema].tipo;
|
|
1599
|
-
}
|
|
1600
|
-
}
|
|
1601
|
-
throw new erro_avaliador_sintatico_1.ErroAvaliadorSintatico(entidadeChamadaAcessoMetodoOuPropriedade.simbolo, `Primitiva '${entidadeChamadaAcessoMetodoOuPropriedade.simbolo.lexema}' não existe.`);
|
|
1653
|
+
return this.logicaComumInferenciaTiposAcessoMetodoOuPropriedade(entidadeChamadaChamada);
|
|
1602
1654
|
case construtos_1.AcessoPropriedade:
|
|
1603
1655
|
const entidadeChamadaAcessoPropriedade = entidadeChamadaChamada;
|
|
1604
1656
|
return entidadeChamadaAcessoPropriedade.tipoRetornoPropriedade;
|
|
@@ -1899,8 +1951,68 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
|
|
|
1899
1951
|
}
|
|
1900
1952
|
return new construtos_1.FuncaoConstruto(this.hashArquivo, Number(parenteseEsquerdo.linha), parametros, corpo, tipoRetorno, definicaoExplicitaDeTipo);
|
|
1901
1953
|
}
|
|
1954
|
+
/**
|
|
1955
|
+
* Analisa uma declaração de interface.
|
|
1956
|
+
* Interfaces definem contratos de métodos e propriedades que as classes devem implementar.
|
|
1957
|
+
* A verificação é feita em tempo de análise (parse-time).
|
|
1958
|
+
*/
|
|
1959
|
+
async declaracaoDeInterface() {
|
|
1960
|
+
const simbolo = this.consumir(delegua_2.default.IDENTIFICADOR, 'Esperado nome da interface.');
|
|
1961
|
+
this.consumir(delegua_2.default.CHAVE_ESQUERDA, "Esperado '{' antes do corpo da interface.");
|
|
1962
|
+
const metodos = [];
|
|
1963
|
+
const propriedades = [];
|
|
1964
|
+
while (!this.verificarTipoSimboloAtual(delegua_2.default.CHAVE_DIREITA) && !this.estaNoFinal()) {
|
|
1965
|
+
this.verificarSeSimboloAtualEIgualA(delegua_2.default.PONTO_E_VIRGULA);
|
|
1966
|
+
if (this.verificarTipoSimboloAtual(delegua_2.default.CHAVE_DIREITA))
|
|
1967
|
+
break;
|
|
1968
|
+
const nomeMembro = this.consumir(delegua_2.default.IDENTIFICADOR, 'Esperado nome de método ou propriedade na interface.');
|
|
1969
|
+
if (this.verificarTipoSimboloAtual(delegua_2.default.PARENTESE_ESQUERDO)) {
|
|
1970
|
+
// Assinatura de método: nome(params): tipoRetorno
|
|
1971
|
+
this.consumir(delegua_2.default.PARENTESE_ESQUERDO, "Esperado '(' após nome do método.");
|
|
1972
|
+
let params = [];
|
|
1973
|
+
if (!this.verificarTipoSimboloAtual(delegua_2.default.PARENTESE_DIREITO)) {
|
|
1974
|
+
params = await this.logicaComumParametros();
|
|
1975
|
+
}
|
|
1976
|
+
this.consumir(delegua_2.default.PARENTESE_DIREITO, "Esperado ')' após parâmetros.");
|
|
1977
|
+
let tipoRetorno = 'qualquer';
|
|
1978
|
+
if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.DOIS_PONTOS)) {
|
|
1979
|
+
tipoRetorno = this.verificarDefinicaoTipoAtual();
|
|
1980
|
+
this.avancarEDevolverAnterior();
|
|
1981
|
+
}
|
|
1982
|
+
this.verificarSeSimboloAtualEIgualA(delegua_2.default.PONTO_E_VIRGULA);
|
|
1983
|
+
metodos.push(new declaracoes_1.AssinaturaMetodo(nomeMembro, params, tipoRetorno));
|
|
1984
|
+
}
|
|
1985
|
+
else {
|
|
1986
|
+
// Assinatura de propriedade: nome: tipo
|
|
1987
|
+
this.consumir(delegua_2.default.DOIS_PONTOS, "Esperado ':' após nome de propriedade na interface.");
|
|
1988
|
+
const tipo = this.verificarDefinicaoTipoAtual();
|
|
1989
|
+
this.avancarEDevolverAnterior();
|
|
1990
|
+
this.verificarSeSimboloAtualEIgualA(delegua_2.default.PONTO_E_VIRGULA);
|
|
1991
|
+
propriedades.push(new declaracoes_1.PropriedadeClasse(nomeMembro, tipo));
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
this.consumir(delegua_2.default.CHAVE_DIREITA, "Esperado '}' após o corpo da interface.");
|
|
1995
|
+
const declaracao = new declaracoes_1.InterfaceDeclaracao(simbolo, metodos, propriedades);
|
|
1996
|
+
this.interfacesDeclaradas[simbolo.lexema] = declaracao;
|
|
1997
|
+
return declaracao;
|
|
1998
|
+
}
|
|
1902
1999
|
async declaracaoDeClasse() {
|
|
2000
|
+
var _a;
|
|
2001
|
+
// Modificadores opcionais no nível da classe: `abstrata` e/ou `estática`.
|
|
2002
|
+
// Sintaxe: `classe abstrata NomeDaClasse` ou `classe estática NomeDaClasse`.
|
|
2003
|
+
let ehAbstrata = false;
|
|
2004
|
+
let ehEstatica = false;
|
|
2005
|
+
if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.ABSTRATO))
|
|
2006
|
+
ehAbstrata = true;
|
|
2007
|
+
if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.ESTATICO))
|
|
2008
|
+
ehEstatica = true;
|
|
2009
|
+
// Também permite a ordem invertida: `classe estática abstrata`
|
|
2010
|
+
if (!ehAbstrata && this.verificarSeSimboloAtualEIgualA(delegua_2.default.ABSTRATO))
|
|
2011
|
+
ehAbstrata = true;
|
|
1903
2012
|
const simbolo = this.consumir(delegua_2.default.IDENTIFICADOR, 'Esperado nome da classe.');
|
|
2013
|
+
// Pré-registro para permitir auto-referência no corpo da própria classe,
|
|
2014
|
+
// como em `MinhaClasse.propriedadeEstatica` dentro de métodos.
|
|
2015
|
+
this.tiposDefinidosEmCodigo[simbolo.lexema] = (_a = this.tiposDefinidosEmCodigo[simbolo.lexema]) !== null && _a !== void 0 ? _a : {};
|
|
1904
2016
|
const pilhaDecoradoresClasse = Array.from(this.pilhaDecoradores);
|
|
1905
2017
|
let superClasse = null;
|
|
1906
2018
|
if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.HERDA)) {
|
|
@@ -1908,43 +2020,359 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
|
|
|
1908
2020
|
this.superclasseAtual = simboloSuperclasse.lexema;
|
|
1909
2021
|
superClasse = new construtos_1.Variavel(this.hashArquivo, this.simbolos[this.atual - 1], simboloSuperclasse.lexema);
|
|
1910
2022
|
}
|
|
2023
|
+
// Verificar `implementa InterfaceA, InterfaceB`
|
|
2024
|
+
const implementaInterfaces = [];
|
|
2025
|
+
if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.IMPLEMENTA)) {
|
|
2026
|
+
do {
|
|
2027
|
+
implementaInterfaces.push(this.consumir(delegua_2.default.IDENTIFICADOR, 'Esperado nome de interface após "implementa".'));
|
|
2028
|
+
} while (this.verificarSeSimboloAtualEIgualA(delegua_2.default.VIRGULA));
|
|
2029
|
+
}
|
|
1911
2030
|
this.consumir(delegua_2.default.CHAVE_ESQUERDA, "Esperado '{' antes do escopo da classe.");
|
|
1912
2031
|
this.pilhaDecoradores = [];
|
|
1913
2032
|
const metodos = [];
|
|
1914
2033
|
const propriedades = [];
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
2034
|
+
/**
|
|
2035
|
+
* Analisa membros do corpo da classe com um contexto de acesso e estático padrão.
|
|
2036
|
+
* Suporta blocos de contexto aninhados: `estático { }`, `abstrato { }`, `privado { }`, `protegido { }`, `publico { }`.
|
|
2037
|
+
*/
|
|
2038
|
+
const compreenderMembros = async (acessoPadrao, ehEstaticoPadrao, ehAbstratoPadrao = false) => {
|
|
2039
|
+
var _a;
|
|
2040
|
+
while (!this.verificarTipoSimboloAtual(delegua_2.default.CHAVE_DIREITA) && !this.estaNoFinal()) {
|
|
2041
|
+
// Pular comentários normais dentro do corpo da classe.
|
|
2042
|
+
if (this.simbolos[this.atual].tipo === delegua_2.default.COMENTARIO ||
|
|
2043
|
+
this.simbolos[this.atual].tipo === delegua_2.default.LINHA_COMENTARIO) {
|
|
2044
|
+
this.avancarEDevolverAnterior();
|
|
2045
|
+
continue;
|
|
2046
|
+
}
|
|
2047
|
+
// Documentário (/** ... */)
|
|
2048
|
+
let docAtual = null;
|
|
2049
|
+
if (this.simbolos[this.atual].tipo === delegua_2.default.DOCUMENTARIO) {
|
|
2050
|
+
const simboloDoc = this.avancarEDevolverAnterior();
|
|
2051
|
+
docAtual = new construtos_1.ComentarioComoConstruto(simboloDoc);
|
|
2052
|
+
}
|
|
2053
|
+
// Decorador
|
|
2054
|
+
if (this.simbolos[this.atual].tipo === delegua_2.default.ARROBA) {
|
|
2055
|
+
await this.resolverDecoradores();
|
|
2056
|
+
continue;
|
|
2057
|
+
}
|
|
2058
|
+
// Detecção de bloco de contexto: modificador seguido de '{'
|
|
2059
|
+
const tipoAtual = this.simbolos[this.atual].tipo;
|
|
2060
|
+
const tipoProximo = (_a = this.simbolos[this.atual + 1]) === null || _a === void 0 ? void 0 : _a.tipo;
|
|
2061
|
+
const ehBlocoAcesso = [delegua_2.default.PRIVADO, delegua_2.default.PROTEGIDO].includes(tipoAtual)
|
|
2062
|
+
&& tipoProximo === delegua_2.default.CHAVE_ESQUERDA;
|
|
2063
|
+
const ehBlocoEstatico = tipoAtual === delegua_2.default.ESTATICO
|
|
2064
|
+
&& tipoProximo === delegua_2.default.CHAVE_ESQUERDA;
|
|
2065
|
+
const ehBlocoAbstrato = tipoAtual === delegua_2.default.ABSTRATO
|
|
2066
|
+
&& tipoProximo === delegua_2.default.CHAVE_ESQUERDA;
|
|
2067
|
+
if (ehBlocoAcesso) {
|
|
2068
|
+
const novoAcesso = tipoAtual === delegua_2.default.PRIVADO ? 'privado' : 'protegido';
|
|
2069
|
+
this.avancarEDevolverAnterior(); // consume modificador de acesso
|
|
2070
|
+
this.consumir(delegua_2.default.CHAVE_ESQUERDA, "Esperado '{' após modificador de acesso de bloco.");
|
|
2071
|
+
await compreenderMembros(novoAcesso, ehEstaticoPadrao, ehAbstratoPadrao);
|
|
2072
|
+
this.consumir(delegua_2.default.CHAVE_DIREITA, "Esperado '}' para fechar bloco de modificador de acesso.");
|
|
2073
|
+
continue;
|
|
2074
|
+
}
|
|
2075
|
+
if (ehBlocoEstatico) {
|
|
2076
|
+
this.avancarEDevolverAnterior(); // consume 'estático'
|
|
2077
|
+
this.consumir(delegua_2.default.CHAVE_ESQUERDA, "Esperado '{' após 'estático'.");
|
|
2078
|
+
await compreenderMembros(acessoPadrao, true, ehAbstratoPadrao);
|
|
2079
|
+
this.consumir(delegua_2.default.CHAVE_DIREITA, "Esperado '}' para fechar bloco estático.");
|
|
2080
|
+
continue;
|
|
2081
|
+
}
|
|
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;
|
|
2088
|
+
}
|
|
2089
|
+
const modificadorAcesso = acessoPadrao;
|
|
2090
|
+
const ehEstatico = ehEstaticoPadrao;
|
|
2091
|
+
// Método operador sobrecarregado: `operador+ (outro) { ... }`
|
|
2092
|
+
if (this.simbolos[this.atual].tipo === delegua_2.default.OPERADOR) {
|
|
2093
|
+
const simboloOperadorKeyword = this.avancarEDevolverAnterior();
|
|
2094
|
+
const simboloDoOperador = this.avancarEDevolverAnterior();
|
|
2095
|
+
const nomeMetodoOp = 'operador' + simboloDoOperador.lexema;
|
|
2096
|
+
const simboloNomeMetodo = {
|
|
2097
|
+
tipo: delegua_2.default.IDENTIFICADOR,
|
|
2098
|
+
lexema: nomeMetodoOp,
|
|
2099
|
+
literal: null,
|
|
2100
|
+
linha: simboloOperadorKeyword.linha,
|
|
2101
|
+
hashArquivo: this.hashArquivo,
|
|
2102
|
+
};
|
|
2103
|
+
this.consumir(delegua_2.default.PARENTESE_ESQUERDO, "Esperado '(' após operador sobrecarregado.");
|
|
2104
|
+
let paramsOp = [];
|
|
2105
|
+
if (!this.verificarTipoSimboloAtual(delegua_2.default.PARENTESE_DIREITO)) {
|
|
2106
|
+
paramsOp = await this.logicaComumParametros();
|
|
2107
|
+
}
|
|
2108
|
+
this.consumir(delegua_2.default.PARENTESE_DIREITO, "Esperado ')' após parâmetros do operador.");
|
|
2109
|
+
this.consumir(delegua_2.default.CHAVE_ESQUERDA, "Esperado '{' antes do corpo do operador.");
|
|
2110
|
+
const corpoOp = await this.blocoEscopo();
|
|
2111
|
+
const corpoFuncaoOp = new construtos_1.FuncaoConstruto(this.hashArquivo, simboloNomeMetodo.linha, paramsOp, corpoOp);
|
|
2112
|
+
const metodoOp = new declaracoes_1.FuncaoDeclaracao(simboloNomeMetodo, corpoFuncaoOp);
|
|
2113
|
+
metodoOp.estatico = ehEstatico;
|
|
2114
|
+
metodoOp.acesso = modificadorAcesso;
|
|
2115
|
+
metodoOp.documentacao = docAtual;
|
|
2116
|
+
metodos.push(metodoOp);
|
|
2117
|
+
this.pilhaDecoradores = [];
|
|
2118
|
+
continue;
|
|
2119
|
+
}
|
|
2120
|
+
// Método ou propriedade, determinado pelo token seguinte ao nome
|
|
2121
|
+
const proximoSimbolo = this.simbolos[this.atual + 1];
|
|
2122
|
+
switch (proximoSimbolo === null || proximoSimbolo === void 0 ? void 0 : proximoSimbolo.tipo) {
|
|
2123
|
+
case delegua_2.default.PARENTESE_ESQUERDO: {
|
|
2124
|
+
// Analisa: nome ( params ) [abstrato] [: tipoRetorno] { corpo }
|
|
2125
|
+
const nomeMetodo = this.avancarEDevolverAnterior();
|
|
2126
|
+
// Pré-registrar para suportar chamadas recursivas (igual a funcao()).
|
|
2127
|
+
this.pilhaEscopos.definirInformacoesVariavel(nomeMetodo.lexema, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(nomeMetodo.lexema, 'qualquer'));
|
|
2128
|
+
this.consumir(delegua_2.default.PARENTESE_ESQUERDO, "Esperado '(' após nome do método.");
|
|
2129
|
+
let params = [];
|
|
2130
|
+
if (!this.verificarTipoSimboloAtual(delegua_2.default.PARENTESE_DIREITO)) {
|
|
2131
|
+
params = await this.logicaComumParametros();
|
|
2132
|
+
}
|
|
2133
|
+
this.consumir(delegua_2.default.PARENTESE_DIREITO, "Esperado ')' após parâmetros do método.");
|
|
2134
|
+
const ehAbstrato = ehAbstratoPadrao;
|
|
2135
|
+
// Tipo de retorno opcional (igual a corpoDaFuncao())
|
|
2136
|
+
let tipoRetorno = 'qualquer';
|
|
2137
|
+
let definicaoExplicitaDeTipo = false;
|
|
2138
|
+
if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.DOIS_PONTOS)) {
|
|
2139
|
+
tipoRetorno = this.verificarDefinicaoTipoAtual();
|
|
2140
|
+
this.avancarEDevolverAnterior();
|
|
2141
|
+
definicaoExplicitaDeTipo = true;
|
|
2142
|
+
}
|
|
2143
|
+
if (ehAbstrato) {
|
|
2144
|
+
// Método abstrato: sem corpo
|
|
2145
|
+
this.verificarSeSimboloAtualEIgualA(delegua_2.default.PONTO_E_VIRGULA);
|
|
2146
|
+
const corpoVazio = new construtos_1.FuncaoConstruto(this.hashArquivo, nomeMetodo.linha, params, [], tipoRetorno);
|
|
2147
|
+
const metodoAbstrato = new declaracoes_1.FuncaoDeclaracao(nomeMetodo, corpoVazio, tipoRetorno);
|
|
2148
|
+
metodoAbstrato.estatico = ehEstatico;
|
|
2149
|
+
metodoAbstrato.abstrato = true;
|
|
2150
|
+
metodoAbstrato.acesso = modificadorAcesso;
|
|
2151
|
+
metodoAbstrato.documentacao = docAtual;
|
|
2152
|
+
metodos.push(metodoAbstrato);
|
|
2153
|
+
}
|
|
2154
|
+
else {
|
|
2155
|
+
// Método concreto: com corpo.
|
|
2156
|
+
// Inferência de tipo de retorno igual a corpoDaFuncao().
|
|
2157
|
+
this.consumir(delegua_2.default.CHAVE_ESQUERDA, "Esperado '{' antes do corpo do método.");
|
|
2158
|
+
const corpo = await this.blocoEscopo();
|
|
2159
|
+
let expressoesRetorna = [];
|
|
2160
|
+
for (const declaracao of corpo) {
|
|
2161
|
+
expressoesRetorna = expressoesRetorna.concat((0, comum_1.buscarRetornos)(declaracao));
|
|
2162
|
+
}
|
|
2163
|
+
const tiposRetornos = new Set(expressoesRetorna.filter((e) => e.tipo !== 'qualquer').map((e) => e.tipo));
|
|
2164
|
+
const retornaChamadoExplicitamente = tiposRetornos.size > 0;
|
|
2165
|
+
tiposRetornos.delete('qualquer');
|
|
2166
|
+
if (tipoRetorno === 'qualquer') {
|
|
2167
|
+
if (tiposRetornos.size > 0) {
|
|
2168
|
+
tipoRetorno = tiposRetornos.values().next().value;
|
|
2169
|
+
}
|
|
2170
|
+
else if (!retornaChamadoExplicitamente && !definicaoExplicitaDeTipo) {
|
|
2171
|
+
tipoRetorno = 'vazio';
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
const corpoFuncao = new construtos_1.FuncaoConstruto(this.hashArquivo, nomeMetodo.linha, params, corpo, tipoRetorno);
|
|
2175
|
+
const tipoDaFuncao = `função<${tipoRetorno}>`;
|
|
2176
|
+
const metodo = new declaracoes_1.FuncaoDeclaracao(nomeMetodo, corpoFuncao, tipoDaFuncao);
|
|
2177
|
+
metodo.estatico = ehEstatico;
|
|
2178
|
+
metodo.acesso = modificadorAcesso;
|
|
2179
|
+
metodo.decoradores = Array.from(this.pilhaDecoradores);
|
|
2180
|
+
metodo.documentacao = docAtual;
|
|
2181
|
+
metodos.push(metodo);
|
|
2182
|
+
this.pilhaEscopos.definirInformacoesVariavel(nomeMetodo.lexema, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(nomeMetodo.lexema, tipoDaFuncao));
|
|
2183
|
+
this.pilhaEscopos.registrarReferenciaFuncao(nomeMetodo.lexema, metodo);
|
|
2184
|
+
}
|
|
2185
|
+
this.pilhaDecoradores = [];
|
|
2186
|
+
break;
|
|
2187
|
+
}
|
|
2188
|
+
case delegua_2.default.DOIS_PONTOS: {
|
|
2189
|
+
const nomePropriedade = this.consumir(delegua_2.default.IDENTIFICADOR, 'Esperado identificador para nome de propriedade.');
|
|
2190
|
+
this.consumir(delegua_2.default.DOIS_PONTOS, 'Esperado dois-pontos após nome de propriedade.');
|
|
2191
|
+
const tipoPropriedade = this.avancarEDevolverAnterior();
|
|
2192
|
+
const prop = new declaracoes_1.PropriedadeClasse(nomePropriedade, tipoPropriedade.lexema, Array.from(this.pilhaDecoradores), modificadorAcesso, ehEstatico);
|
|
2193
|
+
prop.documentacao = docAtual;
|
|
2194
|
+
// Auto-propriedade: `nome: tipo { obter; definir; }`
|
|
2195
|
+
// Ou corpo personalizado: `nome: tipo { obter() { ... } definir(valor) { ... } }`
|
|
2196
|
+
if (this.verificarTipoSimboloAtual(delegua_2.default.CHAVE_ESQUERDA)) {
|
|
2197
|
+
this.avancarEDevolverAnterior(); // consume '{'
|
|
2198
|
+
let temCorpoPersonalizado = false;
|
|
2199
|
+
while (!this.verificarTipoSimboloAtual(delegua_2.default.CHAVE_DIREITA) &&
|
|
2200
|
+
!this.estaNoFinal()) {
|
|
2201
|
+
const lexema = String(this.simbolos[this.atual].lexema || '').toLowerCase();
|
|
2202
|
+
if (lexema === 'obter' || lexema === 'definir') {
|
|
2203
|
+
const ehObter = lexema === 'obter';
|
|
2204
|
+
this.avancarEDevolverAnterior(); // consume 'obter' / 'definir'
|
|
2205
|
+
if (this.verificarTipoSimboloAtual(delegua_2.default.PARENTESE_ESQUERDO)) {
|
|
2206
|
+
// Corpo personalizado: obter() { ... } / definir(valor) { ... }
|
|
2207
|
+
temCorpoPersonalizado = true;
|
|
2208
|
+
this.consumir(delegua_2.default.PARENTESE_ESQUERDO, "Esperado '(' após acessor.");
|
|
2209
|
+
let paramsAcessor = [];
|
|
2210
|
+
if (!this.verificarTipoSimboloAtual(delegua_2.default.PARENTESE_DIREITO)) {
|
|
2211
|
+
paramsAcessor = await this.logicaComumParametros();
|
|
2212
|
+
}
|
|
2213
|
+
this.consumir(delegua_2.default.PARENTESE_DIREITO, "Esperado ')' após parâmetros do acessor.");
|
|
2214
|
+
this.consumir(delegua_2.default.CHAVE_ESQUERDA, "Esperado '{' antes do corpo do acessor.");
|
|
2215
|
+
const corpoAcessor = await this.blocoEscopo();
|
|
2216
|
+
// Inferência de tipo de retorno
|
|
2217
|
+
let tipoAcessor = 'qualquer';
|
|
2218
|
+
let expressoesRetornaAcessor = [];
|
|
2219
|
+
for (const declaracao of corpoAcessor) {
|
|
2220
|
+
expressoesRetornaAcessor = expressoesRetornaAcessor.concat((0, comum_1.buscarRetornos)(declaracao));
|
|
2221
|
+
}
|
|
2222
|
+
const tiposRetornosAcessor = new Set(expressoesRetornaAcessor.filter((e) => e.tipo !== 'qualquer').map((e) => e.tipo));
|
|
2223
|
+
const retornaExplicitamenteAcessor = tiposRetornosAcessor.size > 0;
|
|
2224
|
+
tiposRetornosAcessor.delete('qualquer');
|
|
2225
|
+
if (tiposRetornosAcessor.size > 0) {
|
|
2226
|
+
tipoAcessor = tiposRetornosAcessor.values().next().value;
|
|
2227
|
+
}
|
|
2228
|
+
else if (!retornaExplicitamenteAcessor) {
|
|
2229
|
+
tipoAcessor = 'vazio';
|
|
2230
|
+
}
|
|
2231
|
+
const corpoFuncaoAcessor = new construtos_1.FuncaoConstruto(this.hashArquivo, nomePropriedade.linha, paramsAcessor, corpoAcessor, tipoAcessor);
|
|
2232
|
+
const tipoDaFuncaoAcessor = `função<${tipoAcessor}>`;
|
|
2233
|
+
const metodoAcessor = new declaracoes_1.FuncaoDeclaracao(nomePropriedade, corpoFuncaoAcessor, tipoDaFuncaoAcessor);
|
|
2234
|
+
metodoAcessor.estatico = ehEstatico;
|
|
2235
|
+
metodoAcessor.acesso = modificadorAcesso;
|
|
2236
|
+
metodoAcessor.eObtenedor = ehObter;
|
|
2237
|
+
metodoAcessor.eDefinidor = !ehObter;
|
|
2238
|
+
metodos.push(metodoAcessor);
|
|
2239
|
+
}
|
|
2240
|
+
else {
|
|
2241
|
+
// Forma trivial: obter; / definir;
|
|
2242
|
+
if (ehObter) {
|
|
2243
|
+
prop.autoObter = true;
|
|
2244
|
+
}
|
|
2245
|
+
else {
|
|
2246
|
+
prop.autoDefinir = true;
|
|
2247
|
+
}
|
|
2248
|
+
this.verificarSeSimboloAtualEIgualA(delegua_2.default.PONTO_E_VIRGULA);
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
else {
|
|
2252
|
+
break;
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
this.consumir(delegua_2.default.CHAVE_DIREITA, "Esperado '}' após acessores da propriedade.");
|
|
2256
|
+
// Corpo personalizado: obtenedor/definidor são métodos — não há campos base a declarar.
|
|
2257
|
+
// Para auto-propriedades, o campo base iniciado por '_' é criado em tempo de execução com base
|
|
2258
|
+
// nos indicadores autoObter/autoDefinir. O avaliador sintático usa o nome original ('nome').
|
|
2259
|
+
if (!temCorpoPersonalizado) {
|
|
2260
|
+
propriedades.push(prop);
|
|
2261
|
+
}
|
|
2262
|
+
}
|
|
2263
|
+
else {
|
|
2264
|
+
this.verificarSeSimboloAtualEIgualA(delegua_2.default.PONTO_E_VIRGULA);
|
|
2265
|
+
propriedades.push(prop);
|
|
2266
|
+
}
|
|
2267
|
+
this.pilhaDecoradores = [];
|
|
2268
|
+
break;
|
|
2269
|
+
}
|
|
2270
|
+
default:
|
|
2271
|
+
throw this.erro(this.simbolos[this.atual], 'Esperado definição de método ou propriedade.');
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
};
|
|
2275
|
+
await compreenderMembros('publico', false);
|
|
2276
|
+
this.consumir(delegua_2.default.CHAVE_DIREITA, "Esperado '}' após o escopo da classe.");
|
|
2277
|
+
// Verificação em tempo de análise: classe deve implementar todos os contratos das interfaces.
|
|
2278
|
+
for (const nomeInterface of implementaInterfaces) {
|
|
2279
|
+
const interfaceDecl = this.interfacesDeclaradas[nomeInterface.lexema];
|
|
2280
|
+
if (!interfaceDecl) {
|
|
2281
|
+
this.erros.push(this.erro(nomeInterface, `Interface '${nomeInterface.lexema}' não foi declarada antes da classe '${simbolo.lexema}'.`));
|
|
1921
2282
|
continue;
|
|
1922
2283
|
}
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
this.
|
|
1935
|
-
|
|
1936
|
-
this.pilhaDecoradores = [];
|
|
1937
|
-
break;
|
|
1938
|
-
default:
|
|
1939
|
-
throw this.erro(this.simbolos[this.atual], 'Esperado definição de método ou propriedade.');
|
|
2284
|
+
for (const assinatura of interfaceDecl.metodos) {
|
|
2285
|
+
const nomeMetodo = assinatura.nome.lexema;
|
|
2286
|
+
const implementado = metodos.some((m) => m.simbolo.lexema === nomeMetodo);
|
|
2287
|
+
if (!implementado) {
|
|
2288
|
+
this.erros.push(this.erro(simbolo, `Classe '${simbolo.lexema}' não implementa o método '${nomeMetodo}' exigido pela interface '${nomeInterface.lexema}'.`));
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2291
|
+
for (const prop of interfaceDecl.propriedades) {
|
|
2292
|
+
const nomeProp = prop.nome.lexema;
|
|
2293
|
+
const implementada = propriedades.some((p) => p.nome.lexema === nomeProp);
|
|
2294
|
+
if (!implementada) {
|
|
2295
|
+
this.erros.push(this.erro(simbolo, `Classe '${simbolo.lexema}' não declara a propriedade '${nomeProp}' exigida pela interface '${nomeInterface.lexema}'.`));
|
|
2296
|
+
}
|
|
1940
2297
|
}
|
|
1941
2298
|
}
|
|
1942
|
-
|
|
1943
|
-
const definicaoClasse = new declaracoes_1.Classe(simbolo, superClasse, metodos, propriedades, pilhaDecoradoresClasse);
|
|
2299
|
+
const definicaoClasse = new declaracoes_1.Classe(simbolo, superClasse, metodos, propriedades, pilhaDecoradoresClasse, ehAbstrata, ehEstatica, implementaInterfaces);
|
|
1944
2300
|
this.tiposDefinidosEmCodigo[definicaoClasse.simbolo.lexema] = definicaoClasse;
|
|
1945
2301
|
this.superclasseAtual = undefined;
|
|
1946
2302
|
return definicaoClasse;
|
|
1947
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
|
+
}
|
|
1948
2376
|
/**
|
|
1949
2377
|
* Declarações fora de bloco precisam ser verificadas primeiro por
|
|
1950
2378
|
* uma série de motivos, como, por exemplo:
|
|
@@ -1962,15 +2390,29 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
|
|
|
1962
2390
|
while (this.verificarTipoSimboloAtual(delegua_2.default.ARROBA)) {
|
|
1963
2391
|
await this.resolverDecoradores();
|
|
1964
2392
|
}
|
|
2393
|
+
// Documentário (/** ... */) antes de uma declaração de função.
|
|
2394
|
+
let docTopLevel = null;
|
|
2395
|
+
if (this.verificarTipoSimboloAtual(delegua_2.default.DOCUMENTARIO)) {
|
|
2396
|
+
const simboloDoc = this.avancarEDevolverAnterior();
|
|
2397
|
+
docTopLevel = new construtos_1.ComentarioComoConstruto(simboloDoc);
|
|
2398
|
+
}
|
|
1965
2399
|
if ((this.verificarTipoSimboloAtual(delegua_2.default.FUNCAO) ||
|
|
1966
2400
|
this.verificarTipoSimboloAtual(delegua_2.default.FUNÇÃO)) &&
|
|
1967
2401
|
this.verificarTipoProximoSimbolo(delegua_2.default.IDENTIFICADOR)) {
|
|
1968
2402
|
this.avancarEDevolverAnterior();
|
|
1969
|
-
|
|
2403
|
+
const declaracaoFuncao = await this.funcao('funcao');
|
|
2404
|
+
declaracaoFuncao.documentacao = docTopLevel;
|
|
2405
|
+
return declaracaoFuncao;
|
|
1970
2406
|
}
|
|
1971
2407
|
if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.CLASSE)) {
|
|
1972
2408
|
return await this.declaracaoDeClasse();
|
|
1973
2409
|
}
|
|
2410
|
+
if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.INTERFACE)) {
|
|
2411
|
+
return await this.declaracaoDeInterface();
|
|
2412
|
+
}
|
|
2413
|
+
if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.EXTENSAO)) {
|
|
2414
|
+
return await this.declaracaoDeExtensao();
|
|
2415
|
+
}
|
|
1974
2416
|
return await this.resolverDeclaracao();
|
|
1975
2417
|
}
|
|
1976
2418
|
catch (erro) {
|
|
@@ -2024,6 +2466,20 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
|
|
|
2024
2466
|
return await this.declaracaoBloco();
|
|
2025
2467
|
case delegua_2.default.COMENTARIO:
|
|
2026
2468
|
return this.declaracaoComentarioUmaLinha();
|
|
2469
|
+
case delegua_2.default.DOCUMENTARIO: {
|
|
2470
|
+
const simboloDoc = this.avancarEDevolverAnterior();
|
|
2471
|
+
// Se o próximo token for uma declaração de função com identificador,
|
|
2472
|
+
// anexa o documentário como documentação da função.
|
|
2473
|
+
if ((this.verificarTipoSimboloAtual(delegua_2.default.FUNCAO) ||
|
|
2474
|
+
this.verificarTipoSimboloAtual(delegua_2.default.FUNÇÃO)) &&
|
|
2475
|
+
this.verificarTipoProximoSimbolo(delegua_2.default.IDENTIFICADOR)) {
|
|
2476
|
+
this.avancarEDevolverAnterior();
|
|
2477
|
+
const declaracaoFuncao = await this.funcao('funcao');
|
|
2478
|
+
declaracaoFuncao.documentacao = new construtos_1.ComentarioComoConstruto(simboloDoc);
|
|
2479
|
+
return declaracaoFuncao;
|
|
2480
|
+
}
|
|
2481
|
+
return new declaracoes_1.Comentario(simboloDoc.hashArquivo, simboloDoc.linha, simboloDoc.literal, false);
|
|
2482
|
+
}
|
|
2027
2483
|
case delegua_2.default.CONSTANTE:
|
|
2028
2484
|
this.avancarEDevolverAnterior();
|
|
2029
2485
|
return await this.declaracaoDeConstantes();
|
|
@@ -2202,6 +2658,8 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
|
|
|
2202
2658
|
this.pilhaEscopos.definirInformacoesVariavel('tupla', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('tupla', 'tupla', true, [
|
|
2203
2659
|
new informacao_elemento_sintatico_1.InformacaoElementoSintatico('vetor', 'qualquer[]'),
|
|
2204
2660
|
]));
|
|
2661
|
+
// Classe base global `Objeto`, registrada pelo interpretador em tempo de execução.
|
|
2662
|
+
this.pilhaEscopos.definirInformacoesVariavel('Objeto', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('Objeto', 'qualquer'));
|
|
2205
2663
|
// TODO: Escrever algum tipo de validação aqui.
|
|
2206
2664
|
for (const tipos of Object.values(this.tiposDeFerramentasExternas)) {
|
|
2207
2665
|
for (const [nomeTipo, tipo] of Object.entries(tipos)) {
|
|
@@ -2218,6 +2676,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
|
|
|
2218
2676
|
this.simbolos = (retornoLexador === null || retornoLexador === void 0 ? void 0 : retornoLexador.simbolos) || [];
|
|
2219
2677
|
this.pilhaDecoradores = [];
|
|
2220
2678
|
this.tiposDefinidosEmCodigo = {};
|
|
2679
|
+
this.interfacesDeclaradas = {};
|
|
2221
2680
|
this.montaoTipos = new montao_tipos_1.MontaoTipos();
|
|
2222
2681
|
this.inicializarPilhaEscopos();
|
|
2223
2682
|
let declaracoes = [];
|