@designliquido/delegua-node 1.3.15 → 1.3.17

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 (60) hide show
  1. package/bin/package.json +11 -11
  2. package/delegua.d.ts +21 -21
  3. package/delegua.js +74 -74
  4. package/delegua.js.map +1 -1
  5. package/depuracao/index.d.ts +1 -1
  6. package/depuracao/index.js +17 -17
  7. package/depuracao/servidor-depuracao.d.ts +41 -42
  8. package/depuracao/servidor-depuracao.d.ts.map +1 -1
  9. package/depuracao/servidor-depuracao.js +297 -297
  10. package/depuracao/servidor-depuracao.js.map +1 -1
  11. package/execucao.d.ts +1 -1
  12. package/execucao.js +48 -48
  13. package/execucao.js.map +1 -1
  14. package/formatadores/index.d.ts +6 -6
  15. package/formatadores/index.js +57 -57
  16. package/formatadores/index.js.map +1 -1
  17. package/importador/importador-javascript.d.ts +15 -15
  18. package/importador/importador-javascript.js +62 -62
  19. package/importador/importador-javascript.js.map +1 -1
  20. package/importador/importador.d.ts +28 -28
  21. package/importador/importador.js +81 -81
  22. package/importador/importador.js.map +1 -1
  23. package/importador/index.d.ts +2 -2
  24. package/importador/index.js +18 -18
  25. package/importador/retorno-importador.d.ts +9 -9
  26. package/importador/retorno-importador.js +2 -2
  27. package/index.d.ts +3 -3
  28. package/index.js +19 -19
  29. package/interfaces/delegua-interface.d.ts +6 -6
  30. package/interfaces/delegua-interface.js +2 -2
  31. package/interfaces/importador-interface.d.ts +8 -8
  32. package/interfaces/importador-interface.js +2 -2
  33. package/interfaces/index.d.ts +2 -2
  34. package/interfaces/index.js +18 -18
  35. package/interfaces/nucleo-execucao-interface.d.ts +12 -12
  36. package/interfaces/nucleo-execucao-interface.js +2 -2
  37. package/interpretador/index.d.ts +1 -1
  38. package/interpretador/index.js +17 -17
  39. package/interpretador/interpretador-com-depuracao-importacao.d.ts +15 -15
  40. package/interpretador/interpretador-com-depuracao-importacao.js +76 -76
  41. package/interpretador/interpretador-com-depuracao-importacao.js.map +1 -1
  42. package/interpretador/interpretador.d.ts +19 -19
  43. package/interpretador/interpretador.js +80 -80
  44. package/interpretador/interpretador.js.map +1 -1
  45. package/interpretador/mecanismo-importacao-bibliotecas.d.ts +2 -2
  46. package/interpretador/mecanismo-importacao-bibliotecas.js +131 -132
  47. package/interpretador/mecanismo-importacao-bibliotecas.js.map +1 -1
  48. package/lexador/lexador-json.d.ts +20 -20
  49. package/lexador/lexador-json.js +64 -64
  50. package/lexador/lexador-json.js.map +1 -1
  51. package/nucleo-comum.d.ts +12 -12
  52. package/nucleo-comum.js +48 -48
  53. package/nucleo-comum.js.map +1 -1
  54. package/nucleo-execucao.d.ts +72 -72
  55. package/nucleo-execucao.js +358 -358
  56. package/nucleo-execucao.js.map +1 -1
  57. package/nucleo-traducao.d.ts +36 -36
  58. package/nucleo-traducao.js +127 -127
  59. package/nucleo-traducao.js.map +1 -1
  60. package/package.json +11 -11
@@ -1,298 +1,298 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.ServidorDepuracao = void 0;
27
- const net = __importStar(require("net"));
28
- const depuracao_1 = require("@designliquido/delegua/depuracao");
29
- /**
30
- * Esta foi a primeira implementacão do mecanismo de depuração, usando comunicação por _sockets_.
31
- * Inicialmente uma integração foi implementada na extensão do VSCode, mas o protocolo de
32
- * comunicação nunca foi exatamente maturado, em favor de uma implementação na extensão
33
- * usando a linguagem diretamente.
34
- *
35
- * Mecanismo poderá ser maturado num futuro próximo. Para mais detalhes, ler `README.md`.
36
- */
37
- class ServidorDepuracao {
38
- constructor(instanciaNucleoExecucao) {
39
- this.validarPontoParada = (caminhoArquivo, linha, conexao) => {
40
- const hashArquivo = (0, depuracao_1.cyrb53)(caminhoArquivo.toLowerCase());
41
- if (!this.instanciaNucleoExecucao.arquivosAbertos.hasOwnProperty(hashArquivo)) {
42
- conexao.write(`[adicionar-ponto-parada]: Arquivo '${caminhoArquivo}' não encontrado\n`);
43
- return { sucesso: false };
44
- }
45
- if (this.instanciaNucleoExecucao.conteudoArquivosAbertos[hashArquivo].length < linha) {
46
- conexao.write(`[adicionar-ponto-parada]: Linha ${linha} não existente em arquivo '${caminhoArquivo}'\n`);
47
- return { sucesso: false };
48
- }
49
- return { sucesso: true, hashArquivo, linha };
50
- };
51
- this.comandoAdentrarEscopo = async (conexao) => {
52
- let linhasResposta = '';
53
- linhasResposta += "Recebido comando 'adentrar-escopo'\n";
54
- linhasResposta += '--- adentrar-escopo-resposta ---\n';
55
- this.interpretador.comando = 'adentrarEscopo';
56
- this.interpretador.pontoDeParadaAtivo = false;
57
- await this.interpretador.instrucaoPasso();
58
- conexao.write(linhasResposta);
59
- };
60
- this.comandoAdicionarPontoParada = (comando, conexao) => {
61
- conexao.write("Recebido comando 'adicionar-ponto-parada'\n");
62
- if (comando.length < 3) {
63
- conexao.write(`[adicionar-ponto-parada]: Formato: adicionar-ponto-parada /caminho/do/arquivo.egua 1\n`);
64
- return;
65
- }
66
- const validacaoPontoParada = this.validarPontoParada(comando[1], parseInt(comando[2]), conexao);
67
- if (validacaoPontoParada.sucesso) {
68
- this.interpretador.pontosParada.push({
69
- hashArquivo: validacaoPontoParada.hashArquivo,
70
- linha: validacaoPontoParada.linha,
71
- });
72
- }
73
- };
74
- this.comandoAvaliar = async (comando, conexao) => {
75
- let linhasResposta = '';
76
- comando.shift();
77
- const expressaoAvaliar = comando.join(' ');
78
- let retornoInterpretacao;
79
- let resultadoInterpretacao;
80
- try {
81
- retornoInterpretacao = await this.instanciaNucleoExecucao.executarUmaLinha(expressaoAvaliar);
82
- resultadoInterpretacao = retornoInterpretacao.resultado;
83
- }
84
- catch (erro) {
85
- resultadoInterpretacao = [String(erro)];
86
- }
87
- linhasResposta += "Recebido comando 'avaliar'\n";
88
- linhasResposta += '--- avaliar-resposta ---\n';
89
- linhasResposta += JSON.stringify(resultadoInterpretacao[0]) + '\n';
90
- linhasResposta += '--- fim-avaliar-resposta ---\n';
91
- conexao.write(linhasResposta);
92
- };
93
- this.comandoAvaliarVariavel = async (comando, conexao) => {
94
- let linhasResposta = '';
95
- comando.shift();
96
- const nomeVariavel = comando.join(' ');
97
- linhasResposta += "Recebido comando 'avaliar-variavel'\n";
98
- linhasResposta += '--- avaliar-variavel-resposta ---\n';
99
- try {
100
- linhasResposta += JSON.stringify(this.interpretador.obterVariavel(nomeVariavel)) + '\n';
101
- }
102
- catch (erro) {
103
- linhasResposta += String(erro) + '\n';
104
- }
105
- linhasResposta += '--- fim-avaliar-variavel-resposta ---\n';
106
- conexao.write(linhasResposta);
107
- };
108
- this.comandoContinuar = async (conexao) => {
109
- let linhasResposta = '';
110
- linhasResposta += "Recebido comando 'continuar'\n";
111
- this.interpretador.pontoDeParadaAtivo = false;
112
- await this.interpretador.instrucaoContinuarInterpretacao();
113
- linhasResposta += '--- continuar-resposta ---\n';
114
- conexao.write(linhasResposta);
115
- };
116
- this.comandoPilhaExecucao = (conexao) => {
117
- let linhasResposta = '';
118
- linhasResposta += "Recebido comando 'pilha-execucao'\n";
119
- const pilhaEscoposExecucao = this.interpretador.pilhaEscoposExecucao;
120
- linhasResposta += '--- pilha-execucao-resposta ---\n';
121
- try {
122
- for (let i = pilhaEscoposExecucao.pilha.length - 1; i > 0; i--) {
123
- const elementoPilha = pilhaEscoposExecucao.pilha[i];
124
- const posicaoDeclaracaoAtual = elementoPilha.declaracaoAtual >= elementoPilha.declaracoes.length
125
- ? elementoPilha.declaracoes.length - 1
126
- : elementoPilha.declaracaoAtual;
127
- const declaracaoAtual = elementoPilha.declaracoes[posicaoDeclaracaoAtual];
128
- linhasResposta +=
129
- this.instanciaNucleoExecucao.conteudoArquivosAbertos[declaracaoAtual.hashArquivo][declaracaoAtual.linha - 1].trim() +
130
- ' --- ' +
131
- this.instanciaNucleoExecucao.arquivosAbertos[declaracaoAtual.hashArquivo] +
132
- '::' +
133
- declaracaoAtual.assinaturaMetodo +
134
- '::' +
135
- declaracaoAtual.linha +
136
- '\n';
137
- }
138
- linhasResposta += '--- fim-pilha-execucao-resposta ---\n';
139
- conexao.write(linhasResposta);
140
- }
141
- catch (erro) {
142
- conexao.write(erro + '\n');
143
- }
144
- };
145
- this.comandoPontosParada = (conexao) => {
146
- let linhasResposta = '';
147
- linhasResposta += "Recebido comando 'pontos-parada'\n";
148
- for (const pontoParada of this.interpretador.pontosParada) {
149
- linhasResposta +=
150
- this.instanciaNucleoExecucao.arquivosAbertos[pontoParada.hashArquivo] + ': ' + pontoParada.linha + '\n';
151
- }
152
- conexao.write(linhasResposta);
153
- };
154
- this.comandoProximo = async (conexao) => {
155
- let linhasResposta = '';
156
- linhasResposta += "Recebido comando 'proximo'\n";
157
- linhasResposta += '--- proximo-resposta ---\n';
158
- this.interpretador.comando = 'proximo';
159
- this.interpretador.pontoDeParadaAtivo = false;
160
- try {
161
- await this.interpretador.instrucaoPasso();
162
- }
163
- catch (erro) {
164
- console.error(erro);
165
- }
166
- conexao.write(linhasResposta);
167
- };
168
- this.comandoRemoverPontoParada = (comando, conexao) => {
169
- let linhasResposta = '';
170
- linhasResposta += "Recebido comando 'remover-ponto-parada'\n";
171
- if (comando.length < 3) {
172
- linhasResposta += `[adicionar-ponto-parada]: Formato: adicionar-ponto-parada /caminho/do/arquivo.egua 1\n`;
173
- conexao.write(linhasResposta);
174
- return;
175
- }
176
- const validacaoPontoParada = this.validarPontoParada(comando[1], parseInt(comando[2]), conexao);
177
- if (validacaoPontoParada.sucesso) {
178
- this.interpretador.pontosParada = this.interpretador.pontosParada.filter((p) => p.hashArquivo !== validacaoPontoParada.hashArquivo && p.linha !== validacaoPontoParada.linha);
179
- }
180
- };
181
- this.comandoSairEscopo = async (conexao) => {
182
- let linhasResposta = '';
183
- linhasResposta += "Recebido comando 'sair-escopo'\n";
184
- this.interpretador.pontoDeParadaAtivo = false;
185
- await this.interpretador.instrucaoProximoESair();
186
- linhasResposta += '--- sair-escopo-resposta ---\n';
187
- conexao.write(linhasResposta);
188
- };
189
- this.comandoVariaveis = (conexao) => {
190
- let linhasResposta = '';
191
- linhasResposta += "Recebido comando 'variaveis'. Enviando variáveis do escopo atual\n";
192
- const todasVariaveis = this.interpretador.pilhaEscoposExecucao.obterTodasVariaveis([]);
193
- linhasResposta += '--- variaveis-resposta ---\n';
194
- for (const variavel of todasVariaveis) {
195
- linhasResposta += variavel.nome + ' :: ' + variavel.tipo + ' :: ' + variavel.valor + '\n';
196
- }
197
- linhasResposta += '--- fim-variaveis-resposta ---\n';
198
- conexao.write(linhasResposta);
199
- };
200
- /**
201
- * Função que descreve como conexão com clientes de depuração deve ser operada.
202
- * @param conexao Instância de conexão, tipo net.Socket.
203
- */
204
- this.operarConexao = (conexao) => {
205
- const enderecoRemoto = conexao.remoteAddress + ':' + conexao.remotePort;
206
- process.stdout.write('\n[Depurador] Nova conexão de cliente de ' + enderecoRemoto + '\ndelegua> ');
207
- conexao.setEncoding('utf8');
208
- this.conexoes[this.contadorConexoes++] = conexao;
209
- // Aqui, dados pode ter uma série de comandos, sendo um por linha.
210
- const aoReceberDados = (dados) => {
211
- const comandos = String(dados).split('\n');
212
- process.stdout.write('\n[Depurador] Dados da conexão vindos de ' + enderecoRemoto + ': ' + comandos + '\ndelegua> ');
213
- for (const comando of comandos) {
214
- const partesComando = comando.split(' ');
215
- switch (partesComando[0]) {
216
- case 'adentrar-escopo':
217
- this.comandoAdentrarEscopo(conexao);
218
- break;
219
- case 'adicionar-ponto-parada':
220
- this.comandoAdicionarPontoParada(partesComando, conexao);
221
- break;
222
- case 'avaliar':
223
- this.comandoAvaliar(partesComando, conexao);
224
- break;
225
- case 'avaliar-variavel':
226
- this.comandoAvaliarVariavel(partesComando, conexao);
227
- break;
228
- case 'continuar':
229
- this.comandoContinuar(conexao);
230
- break;
231
- case 'pilha-execucao':
232
- this.comandoPilhaExecucao(conexao);
233
- break;
234
- case 'pontos-parada':
235
- this.comandoPontosParada(conexao);
236
- break;
237
- case 'proximo':
238
- this.comandoProximo(conexao);
239
- break;
240
- case 'remover-ponto-parada':
241
- this.comandoRemoverPontoParada(partesComando, conexao);
242
- break;
243
- case 'sair-escopo':
244
- this.comandoSairEscopo(conexao);
245
- break;
246
- case 'tchau':
247
- conexao.write("Recebido comando 'tchau'. Conexão será encerrada\n");
248
- this.finalizarServidorDepuracao();
249
- return;
250
- case 'variaveis':
251
- this.comandoVariaveis(conexao);
252
- break;
253
- }
254
- }
255
- };
256
- const aoFecharConexao = () => {
257
- process.stdout.write('\n[Depurador] Conexão de ' + enderecoRemoto + ' fechada\ndelegua> ');
258
- };
259
- const aoObterErro = (erro) => {
260
- process.stdout.write('\n[Depurador] Conexão ' + enderecoRemoto + ' com erro: ' + erro.message + '\ndelegua> ');
261
- };
262
- // `.bind()` é necessário aqui para que os eventos não usem net.Socket ou net.Server como o `this`,
263
- // como acontece normalmente se o `.bind()` não é chamado.
264
- conexao.on('data', aoReceberDados.bind(this));
265
- conexao.once('close', aoFecharConexao.bind(this));
266
- conexao.on('error', aoObterErro.bind(this));
267
- };
268
- this.instanciaNucleoExecucao = instanciaNucleoExecucao;
269
- this.instanciaNucleoExecucao.funcaoDeRetorno = this.escreverSaidaParaTodosClientes.bind(this);
270
- this.interpretador = this.instanciaNucleoExecucao.interpretador;
271
- this.interpretador.funcaoDeRetorno = this.escreverSaidaParaTodosClientes.bind(this);
272
- this.servidor = net.createServer();
273
- this.conexoes = {};
274
- this.contadorConexoes = 0;
275
- this.operarConexao.bind(this);
276
- }
277
- iniciarServidorDepuracao() {
278
- // É necessário mudar o `this` aqui por `.bind()`, senão `this` será net.Server dentro dos métodos.
279
- this.servidor.on('connection', this.operarConexao.bind(this));
280
- this.servidor.listen(7777);
281
- process.stdout.write('\n[Depurador] Servidor de depuração iniciado na porta 7777');
282
- return this.servidor.address();
283
- }
284
- escreverSaidaParaTodosClientes(mensagem) {
285
- Object.keys(this.conexoes).forEach((chave) => {
286
- this.conexoes[chave].write('Enviando mensagem de saída\n--- mensagem-saida ---\n' + mensagem + '\n');
287
- });
288
- }
289
- finalizarServidorDepuracao() {
290
- Object.keys(this.conexoes).forEach((chave) => {
291
- this.conexoes[chave].write('--- finalizando ---\n');
292
- this.conexoes[chave].end();
293
- });
294
- this.servidor.close();
295
- }
296
- }
297
- exports.ServidorDepuracao = ServidorDepuracao;
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.ServidorDepuracao = void 0;
27
+ const net = __importStar(require("net"));
28
+ const depuracao_1 = require("@designliquido/delegua/depuracao");
29
+ /**
30
+ * Esta foi a primeira implementacão do mecanismo de depuração, usando comunicação por _sockets_.
31
+ * Inicialmente uma integração foi implementada na extensão do VSCode, mas o protocolo de
32
+ * comunicação nunca foi exatamente maturado, em favor de uma implementação na extensão
33
+ * usando a linguagem diretamente.
34
+ *
35
+ * Mecanismo poderá ser maturado num futuro próximo. Para mais detalhes, ler `README.md`.
36
+ */
37
+ class ServidorDepuracao {
38
+ constructor(instanciaNucleoExecucao) {
39
+ this.validarPontoParada = (caminhoArquivo, linha, conexao) => {
40
+ const hashArquivo = (0, depuracao_1.cyrb53)(caminhoArquivo.toLowerCase());
41
+ if (!this.instanciaNucleoExecucao.arquivosAbertos.hasOwnProperty(hashArquivo)) {
42
+ conexao.write(`[adicionar-ponto-parada]: Arquivo '${caminhoArquivo}' não encontrado\n`);
43
+ return { sucesso: false };
44
+ }
45
+ if (this.instanciaNucleoExecucao.conteudoArquivosAbertos[hashArquivo].length < linha) {
46
+ conexao.write(`[adicionar-ponto-parada]: Linha ${linha} não existente em arquivo '${caminhoArquivo}'\n`);
47
+ return { sucesso: false };
48
+ }
49
+ return { sucesso: true, hashArquivo, linha };
50
+ };
51
+ this.comandoAdentrarEscopo = async (conexao) => {
52
+ let linhasResposta = '';
53
+ linhasResposta += "Recebido comando 'adentrar-escopo'\n";
54
+ linhasResposta += '--- adentrar-escopo-resposta ---\n';
55
+ this.interpretador.comando = 'adentrarEscopo';
56
+ this.interpretador.pontoDeParadaAtivo = false;
57
+ await this.interpretador.instrucaoPasso();
58
+ conexao.write(linhasResposta);
59
+ };
60
+ this.comandoAdicionarPontoParada = (comando, conexao) => {
61
+ conexao.write("Recebido comando 'adicionar-ponto-parada'\n");
62
+ if (comando.length < 3) {
63
+ conexao.write(`[adicionar-ponto-parada]: Formato: adicionar-ponto-parada /caminho/do/arquivo.egua 1\n`);
64
+ return;
65
+ }
66
+ const validacaoPontoParada = this.validarPontoParada(comando[1], parseInt(comando[2]), conexao);
67
+ if (validacaoPontoParada.sucesso) {
68
+ this.interpretador.pontosParada.push({
69
+ hashArquivo: validacaoPontoParada.hashArquivo,
70
+ linha: validacaoPontoParada.linha,
71
+ });
72
+ }
73
+ };
74
+ this.comandoAvaliar = async (comando, conexao) => {
75
+ let linhasResposta = '';
76
+ comando.shift();
77
+ const expressaoAvaliar = comando.join(' ');
78
+ let retornoInterpretacao;
79
+ let resultadoInterpretacao;
80
+ try {
81
+ retornoInterpretacao = await this.instanciaNucleoExecucao.executarUmaLinha(expressaoAvaliar);
82
+ resultadoInterpretacao = retornoInterpretacao.resultado;
83
+ }
84
+ catch (erro) {
85
+ resultadoInterpretacao = [String(erro)];
86
+ }
87
+ linhasResposta += "Recebido comando 'avaliar'\n";
88
+ linhasResposta += '--- avaliar-resposta ---\n';
89
+ linhasResposta += JSON.stringify(resultadoInterpretacao[0]) + '\n';
90
+ linhasResposta += '--- fim-avaliar-resposta ---\n';
91
+ conexao.write(linhasResposta);
92
+ };
93
+ this.comandoAvaliarVariavel = async (comando, conexao) => {
94
+ let linhasResposta = '';
95
+ comando.shift();
96
+ const nomeVariavel = comando.join(' ');
97
+ linhasResposta += "Recebido comando 'avaliar-variavel'\n";
98
+ linhasResposta += '--- avaliar-variavel-resposta ---\n';
99
+ try {
100
+ linhasResposta += JSON.stringify(this.interpretador.obterVariavel(nomeVariavel)) + '\n';
101
+ }
102
+ catch (erro) {
103
+ linhasResposta += String(erro) + '\n';
104
+ }
105
+ linhasResposta += '--- fim-avaliar-variavel-resposta ---\n';
106
+ conexao.write(linhasResposta);
107
+ };
108
+ this.comandoContinuar = async (conexao) => {
109
+ let linhasResposta = '';
110
+ linhasResposta += "Recebido comando 'continuar'\n";
111
+ this.interpretador.pontoDeParadaAtivo = false;
112
+ await this.interpretador.instrucaoContinuarInterpretacao();
113
+ linhasResposta += '--- continuar-resposta ---\n';
114
+ conexao.write(linhasResposta);
115
+ };
116
+ this.comandoPilhaExecucao = (conexao) => {
117
+ let linhasResposta = '';
118
+ linhasResposta += "Recebido comando 'pilha-execucao'\n";
119
+ const pilhaEscoposExecucao = this.interpretador.pilhaEscoposExecucao;
120
+ linhasResposta += '--- pilha-execucao-resposta ---\n';
121
+ try {
122
+ for (let i = pilhaEscoposExecucao.pilha.length - 1; i > 0; i--) {
123
+ const elementoPilha = pilhaEscoposExecucao.pilha[i];
124
+ const posicaoDeclaracaoAtual = elementoPilha.declaracaoAtual >= elementoPilha.declaracoes.length
125
+ ? elementoPilha.declaracoes.length - 1
126
+ : elementoPilha.declaracaoAtual;
127
+ const declaracaoAtual = elementoPilha.declaracoes[posicaoDeclaracaoAtual];
128
+ linhasResposta +=
129
+ this.instanciaNucleoExecucao.conteudoArquivosAbertos[declaracaoAtual.hashArquivo][declaracaoAtual.linha - 1].trim() +
130
+ ' --- ' +
131
+ this.instanciaNucleoExecucao.arquivosAbertos[declaracaoAtual.hashArquivo] +
132
+ '::' +
133
+ declaracaoAtual.assinaturaMetodo +
134
+ '::' +
135
+ declaracaoAtual.linha +
136
+ '\n';
137
+ }
138
+ linhasResposta += '--- fim-pilha-execucao-resposta ---\n';
139
+ conexao.write(linhasResposta);
140
+ }
141
+ catch (erro) {
142
+ conexao.write(erro + '\n');
143
+ }
144
+ };
145
+ this.comandoPontosParada = (conexao) => {
146
+ let linhasResposta = '';
147
+ linhasResposta += "Recebido comando 'pontos-parada'\n";
148
+ for (const pontoParada of this.interpretador.pontosParada) {
149
+ linhasResposta +=
150
+ this.instanciaNucleoExecucao.arquivosAbertos[pontoParada.hashArquivo] + ': ' + pontoParada.linha + '\n';
151
+ }
152
+ conexao.write(linhasResposta);
153
+ };
154
+ this.comandoProximo = async (conexao) => {
155
+ let linhasResposta = '';
156
+ linhasResposta += "Recebido comando 'proximo'\n";
157
+ linhasResposta += '--- proximo-resposta ---\n';
158
+ this.interpretador.comando = 'proximo';
159
+ this.interpretador.pontoDeParadaAtivo = false;
160
+ try {
161
+ await this.interpretador.instrucaoPasso();
162
+ }
163
+ catch (erro) {
164
+ console.error(erro);
165
+ }
166
+ conexao.write(linhasResposta);
167
+ };
168
+ this.comandoRemoverPontoParada = (comando, conexao) => {
169
+ let linhasResposta = '';
170
+ linhasResposta += "Recebido comando 'remover-ponto-parada'\n";
171
+ if (comando.length < 3) {
172
+ linhasResposta += `[adicionar-ponto-parada]: Formato: adicionar-ponto-parada /caminho/do/arquivo.egua 1\n`;
173
+ conexao.write(linhasResposta);
174
+ return;
175
+ }
176
+ const validacaoPontoParada = this.validarPontoParada(comando[1], parseInt(comando[2]), conexao);
177
+ if (validacaoPontoParada.sucesso) {
178
+ this.interpretador.pontosParada = this.interpretador.pontosParada.filter((p) => p.hashArquivo !== validacaoPontoParada.hashArquivo && p.linha !== validacaoPontoParada.linha);
179
+ }
180
+ };
181
+ this.comandoSairEscopo = async (conexao) => {
182
+ let linhasResposta = '';
183
+ linhasResposta += "Recebido comando 'sair-escopo'\n";
184
+ this.interpretador.pontoDeParadaAtivo = false;
185
+ await this.interpretador.instrucaoProximoESair();
186
+ linhasResposta += '--- sair-escopo-resposta ---\n';
187
+ conexao.write(linhasResposta);
188
+ };
189
+ this.comandoVariaveis = (conexao) => {
190
+ let linhasResposta = '';
191
+ linhasResposta += "Recebido comando 'variaveis'. Enviando variáveis do escopo atual\n";
192
+ const todasVariaveis = this.interpretador.pilhaEscoposExecucao.obterTodasVariaveis([]);
193
+ linhasResposta += '--- variaveis-resposta ---\n';
194
+ for (const variavel of todasVariaveis) {
195
+ linhasResposta += variavel.nome + ' :: ' + variavel.tipo + ' :: ' + variavel.valor + '\n';
196
+ }
197
+ linhasResposta += '--- fim-variaveis-resposta ---\n';
198
+ conexao.write(linhasResposta);
199
+ };
200
+ /**
201
+ * Função que descreve como conexão com clientes de depuração deve ser operada.
202
+ * @param conexao Instância de conexão, tipo net.Socket.
203
+ */
204
+ this.operarConexao = (conexao) => {
205
+ const enderecoRemoto = conexao.remoteAddress + ':' + conexao.remotePort;
206
+ process.stdout.write('\n[Depurador] Nova conexão de cliente de ' + enderecoRemoto + '\ndelegua> ');
207
+ conexao.setEncoding('utf8');
208
+ this.conexoes[this.contadorConexoes++] = conexao;
209
+ // Aqui, dados pode ter uma série de comandos, sendo um por linha.
210
+ const aoReceberDados = (dados) => {
211
+ const comandos = String(dados).split('\n');
212
+ process.stdout.write('\n[Depurador] Dados da conexão vindos de ' + enderecoRemoto + ': ' + comandos + '\ndelegua> ');
213
+ for (const comando of comandos) {
214
+ const partesComando = comando.split(' ');
215
+ switch (partesComando[0]) {
216
+ case 'adentrar-escopo':
217
+ this.comandoAdentrarEscopo(conexao);
218
+ break;
219
+ case 'adicionar-ponto-parada':
220
+ this.comandoAdicionarPontoParada(partesComando, conexao);
221
+ break;
222
+ case 'avaliar':
223
+ this.comandoAvaliar(partesComando, conexao);
224
+ break;
225
+ case 'avaliar-variavel':
226
+ this.comandoAvaliarVariavel(partesComando, conexao);
227
+ break;
228
+ case 'continuar':
229
+ this.comandoContinuar(conexao);
230
+ break;
231
+ case 'pilha-execucao':
232
+ this.comandoPilhaExecucao(conexao);
233
+ break;
234
+ case 'pontos-parada':
235
+ this.comandoPontosParada(conexao);
236
+ break;
237
+ case 'proximo':
238
+ this.comandoProximo(conexao);
239
+ break;
240
+ case 'remover-ponto-parada':
241
+ this.comandoRemoverPontoParada(partesComando, conexao);
242
+ break;
243
+ case 'sair-escopo':
244
+ this.comandoSairEscopo(conexao);
245
+ break;
246
+ case 'tchau':
247
+ conexao.write("Recebido comando 'tchau'. Conexão será encerrada\n");
248
+ this.finalizarServidorDepuracao();
249
+ return;
250
+ case 'variaveis':
251
+ this.comandoVariaveis(conexao);
252
+ break;
253
+ }
254
+ }
255
+ };
256
+ const aoFecharConexao = () => {
257
+ process.stdout.write('\n[Depurador] Conexão de ' + enderecoRemoto + ' fechada\ndelegua> ');
258
+ };
259
+ const aoObterErro = (erro) => {
260
+ process.stdout.write('\n[Depurador] Conexão ' + enderecoRemoto + ' com erro: ' + erro.message + '\ndelegua> ');
261
+ };
262
+ // `.bind()` é necessário aqui para que os eventos não usem net.Socket ou net.Server como o `this`,
263
+ // como acontece normalmente se o `.bind()` não é chamado.
264
+ conexao.on('data', aoReceberDados.bind(this));
265
+ conexao.once('close', aoFecharConexao.bind(this));
266
+ conexao.on('error', aoObterErro.bind(this));
267
+ };
268
+ this.instanciaNucleoExecucao = instanciaNucleoExecucao;
269
+ this.instanciaNucleoExecucao.funcaoDeRetorno = this.escreverSaidaParaTodosClientes.bind(this);
270
+ this.interpretador = this.instanciaNucleoExecucao.interpretador;
271
+ this.interpretador.funcaoDeRetorno = this.escreverSaidaParaTodosClientes.bind(this);
272
+ this.servidor = net.createServer();
273
+ this.conexoes = {};
274
+ this.contadorConexoes = 0;
275
+ this.operarConexao.bind(this);
276
+ }
277
+ iniciarServidorDepuracao() {
278
+ // É necessário mudar o `this` aqui por `.bind()`, senão `this` será net.Server dentro dos métodos.
279
+ this.servidor.on('connection', this.operarConexao.bind(this));
280
+ this.servidor.listen(7777);
281
+ process.stdout.write('\n[Depurador] Servidor de depuração iniciado na porta 7777');
282
+ return this.servidor.address();
283
+ }
284
+ escreverSaidaParaTodosClientes(mensagem) {
285
+ Object.keys(this.conexoes).forEach((chave) => {
286
+ this.conexoes[chave].write('Enviando mensagem de saída\n--- mensagem-saida ---\n' + mensagem + '\n');
287
+ });
288
+ }
289
+ finalizarServidorDepuracao() {
290
+ Object.keys(this.conexoes).forEach((chave) => {
291
+ this.conexoes[chave].write('--- finalizando ---\n');
292
+ this.conexoes[chave].end();
293
+ });
294
+ this.servidor.close();
295
+ }
296
+ }
297
+ exports.ServidorDepuracao = ServidorDepuracao;
298
298
  //# sourceMappingURL=servidor-depuracao.js.map