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