@semacode/cli 1.5.28 → 1.5.30
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/README.md +144 -144
- package/dist/bridge.d.ts +52 -0
- package/dist/bridge.js +318 -0
- package/dist/bridge.js.map +1 -0
- package/dist/comandos.d.ts +11 -0
- package/dist/comandos.js +146 -0
- package/dist/comandos.js.map +1 -0
- package/dist/contexto.d.ts +34 -0
- package/dist/contexto.js +197 -0
- package/dist/contexto.js.map +1 -0
- package/dist/drift.d.ts +1 -1
- package/dist/drift.js +32 -5
- package/dist/drift.js.map +1 -1
- package/dist/guard.d.ts +35 -0
- package/dist/guard.js +164 -0
- package/dist/guard.js.map +1 -0
- package/dist/index.js +391 -64
- package/dist/index.js.map +1 -1
- package/dist/lua-symbols.d.ts +0 -6
- package/dist/lua-symbols.js +11 -78
- package/dist/lua-symbols.js.map +1 -1
- package/dist/projeto.js +6 -0
- package/dist/projeto.js.map +1 -1
- package/dist/tipos.d.ts +1 -1
- package/exemplos/.prepack-generated +1 -0
- package/exemplos/author_obra_comum.sema +294 -294
- package/exemplos/author_tema_sensivel.sema +264 -264
- package/exemplos/profile_game.sema +114 -114
- package/exemplos/profile_legal.sema +105 -105
- package/exemplos/profile_ops.sema +110 -110
- package/exemplos/profile_research.sema +104 -104
- package/exemplos/profile_software.sema +123 -123
- package/exemplos/profile_workflow_n8n.sema +99 -99
- package/node_modules/@sema/gerador-css/package.json +14 -7
- package/node_modules/@sema/gerador-css/src/index.ts +605 -0
- package/node_modules/@sema/gerador-css/tsconfig.json +13 -0
- package/node_modules/@sema/gerador-css/tsconfig.tsbuildinfo +1 -0
- package/node_modules/@sema/gerador-dart/package.json +14 -7
- package/node_modules/@sema/gerador-dart/src/index.ts +52 -0
- package/node_modules/@sema/gerador-dart/tsconfig.json +13 -0
- package/node_modules/@sema/gerador-dart/tsconfig.tsbuildinfo +1 -0
- package/node_modules/@sema/gerador-html/package.json +14 -7
- package/node_modules/@sema/gerador-html/src/index.ts +185 -0
- package/node_modules/@sema/gerador-html/tsconfig.json +13 -0
- package/node_modules/@sema/gerador-html/tsconfig.tsbuildinfo +1 -0
- package/node_modules/@sema/gerador-javascript/package.json +14 -7
- package/node_modules/@sema/gerador-javascript/src/index.ts +461 -0
- package/node_modules/@sema/gerador-javascript/tsconfig.json +13 -0
- package/node_modules/@sema/gerador-javascript/tsconfig.tsbuildinfo +1 -0
- package/node_modules/@sema/gerador-lua/package.json +14 -7
- package/node_modules/@sema/gerador-lua/src/index.ts +359 -0
- package/node_modules/@sema/gerador-lua/tsconfig.json +13 -0
- package/node_modules/@sema/gerador-lua/tsconfig.tsbuildinfo +1 -0
- package/node_modules/@sema/gerador-python/package.json +14 -7
- package/node_modules/@sema/gerador-python/src/index.ts +850 -0
- package/node_modules/@sema/gerador-python/tsconfig.json +13 -0
- package/node_modules/@sema/gerador-python/tsconfig.tsbuildinfo +1 -0
- package/node_modules/@sema/gerador-typescript/package.json +14 -7
- package/node_modules/@sema/gerador-typescript/src/index.ts +876 -0
- package/node_modules/@sema/gerador-typescript/tsconfig.json +13 -0
- package/node_modules/@sema/gerador-typescript/tsconfig.tsbuildinfo +1 -0
- package/node_modules/@sema/nucleo/dist/ast/tipos.d.ts +1 -1
- package/node_modules/@sema/nucleo/dist/index.d.ts +17 -0
- package/node_modules/@sema/nucleo/dist/index.js +28 -0
- package/node_modules/@sema/nucleo/dist/index.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/ir/conversor.js +4 -0
- package/node_modules/@sema/nucleo/dist/ir/conversor.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/ir/modelos.d.ts +3 -3
- package/node_modules/@sema/nucleo/dist/parser/parser.js +2 -0
- package/node_modules/@sema/nucleo/dist/parser/parser.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.d.ts +2 -2
- package/node_modules/@sema/nucleo/dist/semantico/analisador.js +3 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.js.map +1 -1
- package/node_modules/@sema/nucleo/package.json +10 -7
- package/node_modules/@sema/nucleo/src/ast/tipos.ts +207 -0
- package/node_modules/@sema/nucleo/src/diagnosticos/index.ts +43 -0
- package/node_modules/@sema/nucleo/src/formatador/index.ts +530 -0
- package/node_modules/@sema/nucleo/src/index.ts +183 -0
- package/node_modules/@sema/nucleo/src/ir/conversor.ts +1037 -0
- package/node_modules/@sema/nucleo/src/ir/modelos.ts +403 -0
- package/node_modules/@sema/nucleo/src/lexer/lexer.ts +166 -0
- package/node_modules/@sema/nucleo/src/lexer/tokens.ts +79 -0
- package/node_modules/@sema/nucleo/src/parser/gramatica.ebnf +41 -0
- package/node_modules/@sema/nucleo/src/parser/parser.ts +936 -0
- package/node_modules/@sema/nucleo/src/persistencia/contratos.ts +379 -0
- package/node_modules/@sema/nucleo/src/semantico/analisador.ts +3126 -0
- package/node_modules/@sema/nucleo/src/semantico/estruturas.ts +665 -0
- package/node_modules/@sema/nucleo/src/semantico/seguranca.ts +362 -0
- package/node_modules/@sema/nucleo/src/util/arquivos.ts +28 -0
- package/node_modules/@sema/nucleo/tsconfig.json +9 -0
- package/node_modules/@sema/nucleo/tsconfig.tsbuildinfo +1 -0
- package/node_modules/@sema/padroes/package.json +10 -7
- package/node_modules/@sema/padroes/src/index.ts +382 -0
- package/node_modules/@sema/padroes/tsconfig.json +9 -0
- package/node_modules/@sema/padroes/tsconfig.tsbuildinfo +1 -0
- package/package.json +74 -74
- package/AGENTS.md +0 -280
- package/LICENSE +0 -22
- package/SEMA_BRIEF.curto.txt +0 -11
- package/SEMA_BRIEF.md +0 -112
- package/SEMA_BRIEF.micro.txt +0 -9
- package/SEMA_INDEX.json +0 -1534
- package/dist/php-symbols.d.ts +0 -24
- package/dist/php-symbols.js +0 -375
- package/dist/php-symbols.js.map +0 -1
- package/docs/AGENT_STARTER.md +0 -109
- package/docs/cli.md +0 -175
- package/docs/como-ensinar-a-sema-para-ia.md +0 -155
- package/docs/deploy.md +0 -93
- package/docs/documentacao.md +0 -88
- package/docs/env.md +0 -105
- package/docs/extensao-vscode.md +0 -53
- package/docs/fluxo-pratico-ia-sema.md +0 -187
- package/docs/instalacao-e-primeiro-uso.md +0 -134
- package/docs/integracao-com-ia.md +0 -110
- package/docs/mcp.md +0 -292
- package/docs/pagamento-ponta-a-ponta.md +0 -171
- package/docs/persistencia-vendor-first.md +0 -151
- package/docs/prompt-base-ia-sema.md +0 -111
- package/docs/repositories.md +0 -54
- package/docs/rollback.md +0 -49
- package/docs/seguranca.md +0 -126
- package/docs/sintaxe.md +0 -218
- package/llms-full.txt +0 -34
- package/llms.txt +0 -17
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export type SeveridadeDiagnostico = "erro" | "aviso" | "informacao";
|
|
2
|
+
|
|
3
|
+
export interface PosicaoFonte {
|
|
4
|
+
indice: number;
|
|
5
|
+
linha: number;
|
|
6
|
+
coluna: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface IntervaloFonte {
|
|
10
|
+
inicio: PosicaoFonte;
|
|
11
|
+
fim: PosicaoFonte;
|
|
12
|
+
arquivo?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface Diagnostico {
|
|
16
|
+
codigo: string;
|
|
17
|
+
mensagem: string;
|
|
18
|
+
severidade: SeveridadeDiagnostico;
|
|
19
|
+
intervalo?: IntervaloFonte;
|
|
20
|
+
dica?: string;
|
|
21
|
+
contexto?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function formatarDiagnostico(diagnostico: Diagnostico): string {
|
|
25
|
+
const local = diagnostico.intervalo
|
|
26
|
+
? `${diagnostico.intervalo.arquivo ?? "arquivo"}:${diagnostico.intervalo.inicio.linha}:${diagnostico.intervalo.inicio.coluna}`
|
|
27
|
+
: "local desconhecido";
|
|
28
|
+
const dica = diagnostico.dica ? `\nDica: ${diagnostico.dica}` : "";
|
|
29
|
+
const contexto = diagnostico.contexto ? `\nContexto: ${diagnostico.contexto}` : "";
|
|
30
|
+
return `[${diagnostico.severidade.toUpperCase()} ${diagnostico.codigo}] ${diagnostico.mensagem} (${local})${dica}${contexto}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function criarDiagnostico(
|
|
34
|
+
codigo: string,
|
|
35
|
+
mensagem: string,
|
|
36
|
+
severidade: SeveridadeDiagnostico,
|
|
37
|
+
intervalo?: IntervaloFonte,
|
|
38
|
+
dica?: string,
|
|
39
|
+
contexto?: string,
|
|
40
|
+
): Diagnostico {
|
|
41
|
+
return { codigo, mensagem, severidade, intervalo, dica, contexto };
|
|
42
|
+
}
|
|
43
|
+
|
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
BlocoAst,
|
|
3
|
+
BlocoCasoTesteAst,
|
|
4
|
+
BlocoGenericoAst,
|
|
5
|
+
CampoAst,
|
|
6
|
+
EntityAst,
|
|
7
|
+
EnumAst,
|
|
8
|
+
FlowAst,
|
|
9
|
+
ModuloAst,
|
|
10
|
+
RouteAst,
|
|
11
|
+
StateAst,
|
|
12
|
+
TaskAst,
|
|
13
|
+
TypeAst,
|
|
14
|
+
UseAst,
|
|
15
|
+
} from "../ast/tipos.js";
|
|
16
|
+
import type { Diagnostico } from "../diagnosticos/index.js";
|
|
17
|
+
import { parsear } from "../parser/parser.js";
|
|
18
|
+
import { tokenizar } from "../lexer/lexer.js";
|
|
19
|
+
|
|
20
|
+
const ORDEM_BLOCOS_MODULO = new Map<string, number>([
|
|
21
|
+
["docs", 0],
|
|
22
|
+
["comments", 1],
|
|
23
|
+
["use", 2],
|
|
24
|
+
["vinculos", 3],
|
|
25
|
+
["database", 4],
|
|
26
|
+
["type", 5],
|
|
27
|
+
["entity", 6],
|
|
28
|
+
["enum", 7],
|
|
29
|
+
["state", 8],
|
|
30
|
+
["task", 9],
|
|
31
|
+
["flow", 10],
|
|
32
|
+
["route", 11],
|
|
33
|
+
["worker", 12],
|
|
34
|
+
["evento", 13],
|
|
35
|
+
["fila", 14],
|
|
36
|
+
["cron", 15],
|
|
37
|
+
["webhook", 16],
|
|
38
|
+
["cache", 17],
|
|
39
|
+
["storage", 18],
|
|
40
|
+
["policy", 19],
|
|
41
|
+
["tests", 20],
|
|
42
|
+
["desconhecido", 21],
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
const ORDEM_SUBBLOCOS_TASK = new Map<string, number>([
|
|
46
|
+
["docs", 0],
|
|
47
|
+
["comments", 1],
|
|
48
|
+
["input", 2],
|
|
49
|
+
["output", 3],
|
|
50
|
+
["rules", 4],
|
|
51
|
+
["effects", 5],
|
|
52
|
+
["auth", 6],
|
|
53
|
+
["authz", 7],
|
|
54
|
+
["dados", 8],
|
|
55
|
+
["audit", 9],
|
|
56
|
+
["segredos", 10],
|
|
57
|
+
["forbidden", 11],
|
|
58
|
+
["impl", 12],
|
|
59
|
+
["vinculos", 13],
|
|
60
|
+
["execucao", 14],
|
|
61
|
+
["state", 15],
|
|
62
|
+
["guarantees", 16],
|
|
63
|
+
["error", 17],
|
|
64
|
+
["tests", 18],
|
|
65
|
+
["desconhecido", 19],
|
|
66
|
+
]);
|
|
67
|
+
|
|
68
|
+
const ORDEM_SUBBLOCOS_ROUTE = new Map<string, number>([
|
|
69
|
+
["input", 0],
|
|
70
|
+
["output", 1],
|
|
71
|
+
["effects", 2],
|
|
72
|
+
["auth", 3],
|
|
73
|
+
["authz", 4],
|
|
74
|
+
["dados", 5],
|
|
75
|
+
["audit", 6],
|
|
76
|
+
["segredos", 7],
|
|
77
|
+
["forbidden", 8],
|
|
78
|
+
["vinculos", 9],
|
|
79
|
+
["error", 10],
|
|
80
|
+
["docs", 11],
|
|
81
|
+
["comments", 12],
|
|
82
|
+
["desconhecido", 13],
|
|
83
|
+
]);
|
|
84
|
+
|
|
85
|
+
const ORDEM_SUBBLOCOS_FLOW = new Map<string, number>([
|
|
86
|
+
["effects", 0],
|
|
87
|
+
["vinculos", 1],
|
|
88
|
+
["docs", 2],
|
|
89
|
+
["comments", 3],
|
|
90
|
+
["desconhecido", 4],
|
|
91
|
+
]);
|
|
92
|
+
|
|
93
|
+
const ORDEM_SUBBLOCOS_SUPERFICIE = new Map<string, number>([
|
|
94
|
+
["input", 0],
|
|
95
|
+
["output", 1],
|
|
96
|
+
["effects", 2],
|
|
97
|
+
["auth", 3],
|
|
98
|
+
["authz", 4],
|
|
99
|
+
["dados", 5],
|
|
100
|
+
["audit", 6],
|
|
101
|
+
["segredos", 7],
|
|
102
|
+
["forbidden", 8],
|
|
103
|
+
["impl", 9],
|
|
104
|
+
["vinculos", 10],
|
|
105
|
+
["execucao", 11],
|
|
106
|
+
["error", 12],
|
|
107
|
+
["docs", 13],
|
|
108
|
+
["comments", 14],
|
|
109
|
+
["desconhecido", 15],
|
|
110
|
+
]);
|
|
111
|
+
|
|
112
|
+
const ORDEM_SUBBLOCOS_STATE = new Map<string, number>([
|
|
113
|
+
["fields", 0],
|
|
114
|
+
["invariants", 1],
|
|
115
|
+
["transitions", 2],
|
|
116
|
+
["docs", 3],
|
|
117
|
+
["comments", 4],
|
|
118
|
+
["desconhecido", 5],
|
|
119
|
+
]);
|
|
120
|
+
|
|
121
|
+
const ORDEM_SUBBLOCOS_TESTE = new Map<string, number>([
|
|
122
|
+
["given", 0],
|
|
123
|
+
["when", 1],
|
|
124
|
+
["expect", 2],
|
|
125
|
+
["error", 3],
|
|
126
|
+
["docs", 4],
|
|
127
|
+
["comments", 5],
|
|
128
|
+
["desconhecido", 6],
|
|
129
|
+
]);
|
|
130
|
+
|
|
131
|
+
const ORDEM_CAMPOS_POR_BLOCO = new Map<string, Map<string, number>>([
|
|
132
|
+
["vinculos", new Map<string, number>([
|
|
133
|
+
["arquivo", 0],
|
|
134
|
+
["simbolo", 1],
|
|
135
|
+
["rota", 2],
|
|
136
|
+
["superficie", 3],
|
|
137
|
+
["recurso", 4],
|
|
138
|
+
["tabela", 5],
|
|
139
|
+
["fila", 6],
|
|
140
|
+
["worker", 7],
|
|
141
|
+
["evento", 8],
|
|
142
|
+
["cron", 9],
|
|
143
|
+
["webhook", 10],
|
|
144
|
+
["cache", 11],
|
|
145
|
+
["storage", 12],
|
|
146
|
+
["policy", 13],
|
|
147
|
+
["teste", 14],
|
|
148
|
+
])],
|
|
149
|
+
["execucao", new Map<string, number>([
|
|
150
|
+
["idempotencia", 0],
|
|
151
|
+
["timeout", 1],
|
|
152
|
+
["retry", 2],
|
|
153
|
+
["compensacao", 3],
|
|
154
|
+
["criticidade_operacional", 4],
|
|
155
|
+
])],
|
|
156
|
+
["auth", new Map<string, number>([
|
|
157
|
+
["modo", 0],
|
|
158
|
+
["estrategia", 1],
|
|
159
|
+
["principal", 2],
|
|
160
|
+
["origem", 3],
|
|
161
|
+
])],
|
|
162
|
+
["authz", new Map<string, number>([
|
|
163
|
+
["papeis", 0],
|
|
164
|
+
["papel", 1],
|
|
165
|
+
["escopos", 2],
|
|
166
|
+
["escopo", 3],
|
|
167
|
+
["politica", 4],
|
|
168
|
+
["tenant", 5],
|
|
169
|
+
])],
|
|
170
|
+
["dados", new Map<string, number>([
|
|
171
|
+
["classificacao_padrao", 0],
|
|
172
|
+
["redacao_log", 1],
|
|
173
|
+
["retencao", 2],
|
|
174
|
+
])],
|
|
175
|
+
["audit", new Map<string, number>([
|
|
176
|
+
["evento", 0],
|
|
177
|
+
["ator", 1],
|
|
178
|
+
["correlacao", 2],
|
|
179
|
+
["retencao", 3],
|
|
180
|
+
["motivo", 4],
|
|
181
|
+
])],
|
|
182
|
+
["database", new Map<string, number>([
|
|
183
|
+
["engine", 0],
|
|
184
|
+
["schema", 1],
|
|
185
|
+
["database", 2],
|
|
186
|
+
["consistency", 3],
|
|
187
|
+
["durability", 4],
|
|
188
|
+
["transaction_model", 5],
|
|
189
|
+
["query_model", 6],
|
|
190
|
+
["portavel", 7],
|
|
191
|
+
["adapter", 8],
|
|
192
|
+
])],
|
|
193
|
+
]);
|
|
194
|
+
|
|
195
|
+
export interface ResultadoFormatacao {
|
|
196
|
+
modulo?: ModuloAst;
|
|
197
|
+
codigoFormatado?: string;
|
|
198
|
+
diagnosticos: Diagnostico[];
|
|
199
|
+
alterado: boolean;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function indentacao(nivel: number): string {
|
|
203
|
+
return " ".repeat(nivel);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function ordenarPorMapa<T>(itens: T[], extrairChave: (item: T) => string, ordem: Map<string, number>): T[] {
|
|
207
|
+
return [...itens].sort((a, b) => {
|
|
208
|
+
const ordemA = ordem.get(extrairChave(a)) ?? Number.MAX_SAFE_INTEGER;
|
|
209
|
+
const ordemB = ordem.get(extrairChave(b)) ?? Number.MAX_SAFE_INTEGER;
|
|
210
|
+
if (ordemA !== ordemB) {
|
|
211
|
+
return ordemA - ordemB;
|
|
212
|
+
}
|
|
213
|
+
return extrairChave(a).localeCompare(extrairChave(b), "pt-BR");
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function normalizarEspacos(texto: string): string {
|
|
218
|
+
const marcadorSeta = "__SEMA_SETA__";
|
|
219
|
+
const marcadorMaiorIgual = "__SEMA_MAIOR_IGUAL__";
|
|
220
|
+
const marcadorMenorIgual = "__SEMA_MENOR_IGUAL__";
|
|
221
|
+
const marcadorIgual = "__SEMA_IGUAL__";
|
|
222
|
+
const marcadorDiferente = "__SEMA_DIFERENTE__";
|
|
223
|
+
return texto
|
|
224
|
+
.trim()
|
|
225
|
+
.replace(/\s*->\s*/g, ` ${marcadorSeta} `)
|
|
226
|
+
.replace(/\s*-\s*>\s*/g, ` ${marcadorSeta} `)
|
|
227
|
+
.replace(/\s+/g, " ")
|
|
228
|
+
.replace(/\s*,\s*/g, ", ")
|
|
229
|
+
.replace(/\(\s+/g, "(")
|
|
230
|
+
.replace(/\s+\)/g, ")")
|
|
231
|
+
.replace(/\[\s+/g, "[")
|
|
232
|
+
.replace(/\s+\]/g, "]")
|
|
233
|
+
.replace(/\s*>=\s*/g, ` ${marcadorMaiorIgual} `)
|
|
234
|
+
.replace(/\s*<=\s*/g, ` ${marcadorMenorIgual} `)
|
|
235
|
+
.replace(/\s*==\s*/g, ` ${marcadorIgual} `)
|
|
236
|
+
.replace(/\s*!=\s*/g, ` ${marcadorDiferente} `)
|
|
237
|
+
.replace(/\s*>\s*/g, " > ")
|
|
238
|
+
.replace(/\s*<\s*/g, " < ")
|
|
239
|
+
.replace(new RegExp(`\\s*${marcadorMaiorIgual}\\s*`, "g"), " >= ")
|
|
240
|
+
.replace(new RegExp(`\\s*${marcadorMenorIgual}\\s*`, "g"), " <= ")
|
|
241
|
+
.replace(new RegExp(`\\s*${marcadorIgual}\\s*`, "g"), " == ")
|
|
242
|
+
.replace(new RegExp(`\\s*${marcadorDiferente}\\s*`, "g"), " != ")
|
|
243
|
+
.replace(new RegExp(`\\s*${marcadorSeta}\\s*`, "g"), " -> ");
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function normalizarCaminho(texto: string): string {
|
|
247
|
+
return texto
|
|
248
|
+
.trim()
|
|
249
|
+
.replace(/\s*\/\s*/g, "/")
|
|
250
|
+
.replace(/\s+/g, "");
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function eLiteralEscalar(texto: string): boolean {
|
|
254
|
+
const normalizado = texto.trim();
|
|
255
|
+
return /^-?\d+(?:\.\d+)?$/.test(normalizado) || ["verdadeiro", "falso", "nulo"].includes(normalizado);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function deveColocarAspas(contexto: string, campo: CampoAst, combinado: string): boolean {
|
|
259
|
+
if (campo.nome === "metodo") {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
if (campo.nome === "caminho") {
|
|
263
|
+
return /[{}]/.test(combinado);
|
|
264
|
+
}
|
|
265
|
+
if (contexto === "vinculos" && ["arquivo", "webhook"].includes(campo.nome)) {
|
|
266
|
+
return true;
|
|
267
|
+
}
|
|
268
|
+
if (["timeout", "retry", "compensacao", "retencao", "rotacao"].includes(campo.nome)) {
|
|
269
|
+
return true;
|
|
270
|
+
}
|
|
271
|
+
if (contexto === "docs" || contexto === "comments") {
|
|
272
|
+
return true;
|
|
273
|
+
}
|
|
274
|
+
if (contexto === "error") {
|
|
275
|
+
return !eLiteralEscalar(combinado);
|
|
276
|
+
}
|
|
277
|
+
if (contexto === "given" || contexto === "when" || contexto === "expect") {
|
|
278
|
+
return !eLiteralEscalar(combinado);
|
|
279
|
+
}
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function normalizarValorCampo(campo: CampoAst): string {
|
|
284
|
+
return [campo.valor, ...campo.modificadores]
|
|
285
|
+
.filter(Boolean)
|
|
286
|
+
.join(" ")
|
|
287
|
+
.replace(/\s+/g, " ")
|
|
288
|
+
.trim();
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function ordenarCampos(bloco: BlocoGenericoAst): CampoAst[] {
|
|
292
|
+
const ordem = ORDEM_CAMPOS_POR_BLOCO.get(bloco.palavraChave);
|
|
293
|
+
if (!ordem) {
|
|
294
|
+
return bloco.campos;
|
|
295
|
+
}
|
|
296
|
+
return ordenarPorMapa(bloco.campos, (campo) => campo.nome, ordem);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function renderizarCampo(campo: CampoAst, nivel: number, contexto: string): string {
|
|
300
|
+
let combinado = normalizarValorCampo(campo);
|
|
301
|
+
|
|
302
|
+
if (campo.nome === "caminho") {
|
|
303
|
+
combinado = normalizarCaminho(combinado);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (deveColocarAspas(contexto, campo, combinado)) {
|
|
307
|
+
combinado = JSON.stringify(combinado);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return `${indentacao(nivel)}${campo.nome}: ${combinado}`;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function renderizarLinha(linha: string, nivel: number): string {
|
|
314
|
+
return `${indentacao(nivel)}${normalizarEspacos(linha)}`;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function renderizarCasoTeste(caso: BlocoCasoTesteAst, nivel: number): string {
|
|
318
|
+
const partes: string[] = [];
|
|
319
|
+
if (caso.given) {
|
|
320
|
+
partes.push(renderizarBlocoGenerico(caso.given, nivel + 1));
|
|
321
|
+
}
|
|
322
|
+
if (caso.when) {
|
|
323
|
+
partes.push(renderizarBlocoGenerico(caso.when, nivel + 1));
|
|
324
|
+
}
|
|
325
|
+
if (caso.expect) {
|
|
326
|
+
partes.push(renderizarBlocoGenerico(caso.expect, nivel + 1));
|
|
327
|
+
}
|
|
328
|
+
if (caso.error) {
|
|
329
|
+
partes.push(renderizarBlocoGenerico(caso.error, nivel + 1));
|
|
330
|
+
}
|
|
331
|
+
if (caso.docs) {
|
|
332
|
+
partes.push(renderizarBlocoGenerico(caso.docs, nivel + 1));
|
|
333
|
+
}
|
|
334
|
+
if (caso.comments) {
|
|
335
|
+
partes.push(renderizarBlocoGenerico(caso.comments, nivel + 1));
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return `${indentacao(nivel)}caso ${JSON.stringify(caso.nome)} {\n${partes.join("\n\n")}\n${indentacao(nivel)}}`;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function renderizarBlocoAst(bloco: BlocoAst, nivel: number): string {
|
|
342
|
+
switch (bloco.tipo) {
|
|
343
|
+
case "caso_teste":
|
|
344
|
+
return renderizarCasoTeste(bloco, nivel);
|
|
345
|
+
case "bloco_generico":
|
|
346
|
+
return renderizarBlocoGenerico(bloco, nivel);
|
|
347
|
+
case "use":
|
|
348
|
+
return `${indentacao(nivel)}use ${bloco.origem === "sema" ? "" : `${bloco.origem} `}${bloco.caminho}`.trimEnd();
|
|
349
|
+
case "enum":
|
|
350
|
+
return renderizarEnum(bloco, nivel);
|
|
351
|
+
case "type":
|
|
352
|
+
return renderizarTipo(bloco, nivel);
|
|
353
|
+
case "entity":
|
|
354
|
+
return renderizarEntity(bloco, nivel);
|
|
355
|
+
case "task":
|
|
356
|
+
return renderizarTask(bloco, nivel);
|
|
357
|
+
case "flow":
|
|
358
|
+
return renderizarFlow(bloco, nivel);
|
|
359
|
+
case "route":
|
|
360
|
+
return renderizarRoute(bloco, nivel);
|
|
361
|
+
case "state":
|
|
362
|
+
return renderizarState(bloco, nivel);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
function ordenarSubblocos(bloco: BlocoGenericoAst): BlocoAst[] {
|
|
367
|
+
if (bloco.palavraChave === "task") {
|
|
368
|
+
return ordenarPorMapa(bloco.blocos, (item) => item.tipo === "bloco_generico" ? item.palavraChave : item.tipo, ORDEM_SUBBLOCOS_TASK);
|
|
369
|
+
}
|
|
370
|
+
if (bloco.palavraChave === "route") {
|
|
371
|
+
return ordenarPorMapa(bloco.blocos, (item) => item.tipo === "bloco_generico" ? item.palavraChave : item.tipo, ORDEM_SUBBLOCOS_ROUTE);
|
|
372
|
+
}
|
|
373
|
+
if (bloco.palavraChave === "flow") {
|
|
374
|
+
return ordenarPorMapa(bloco.blocos, (item) => item.tipo === "bloco_generico" ? item.palavraChave : item.tipo, ORDEM_SUBBLOCOS_FLOW);
|
|
375
|
+
}
|
|
376
|
+
if (["worker", "evento", "fila", "cron", "webhook", "cache", "storage", "policy"].includes(bloco.palavraChave)) {
|
|
377
|
+
return ordenarPorMapa(bloco.blocos, (item) => item.tipo === "bloco_generico" ? item.palavraChave : item.tipo, ORDEM_SUBBLOCOS_SUPERFICIE);
|
|
378
|
+
}
|
|
379
|
+
if (bloco.palavraChave === "state") {
|
|
380
|
+
return ordenarPorMapa(bloco.blocos, (item) => item.tipo === "bloco_generico" ? item.palavraChave : item.tipo, ORDEM_SUBBLOCOS_STATE);
|
|
381
|
+
}
|
|
382
|
+
if (bloco.palavraChave === "tests") {
|
|
383
|
+
return ordenarPorMapa(bloco.blocos, (item) => item.tipo === "caso_teste" ? "case" : item.tipo === "bloco_generico" ? item.palavraChave : item.tipo, ORDEM_SUBBLOCOS_TESTE);
|
|
384
|
+
}
|
|
385
|
+
return bloco.blocos;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function renderizarBlocoGenerico(bloco: BlocoGenericoAst, nivel: number): string {
|
|
389
|
+
const identificadorBloco = bloco.palavraChave === "desconhecido" && bloco.nome
|
|
390
|
+
? bloco.nome
|
|
391
|
+
: `${bloco.palavraChave}${bloco.nome ? ` ${bloco.nome}` : ""}`;
|
|
392
|
+
const cabecalho = `${indentacao(nivel)}${identificadorBloco} {`;
|
|
393
|
+
const linhasCampos = ordenarCampos(bloco).map((campo) => renderizarCampo(campo, nivel + 1, bloco.palavraChave));
|
|
394
|
+
const linhasDeclarativas = bloco.linhas.map((linha) => renderizarLinha(linha.conteudo, nivel + 1));
|
|
395
|
+
const blocosInternos = ordenarSubblocos(bloco).map((subbloco) => renderizarBlocoAst(subbloco, nivel + 1));
|
|
396
|
+
const corpo = [...linhasCampos, ...linhasDeclarativas, ...blocosInternos];
|
|
397
|
+
if (corpo.length === 0) {
|
|
398
|
+
return `${cabecalho}\n${indentacao(nivel)}}`;
|
|
399
|
+
}
|
|
400
|
+
return `${cabecalho}\n${corpo.join("\n")}\n${indentacao(nivel)}}`;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
function renderizarEnum(enumeracao: EnumAst, nivel: number): string {
|
|
404
|
+
const corpo = enumeracao.valores.map((valor, indice) => `${indentacao(nivel + 1)}${valor}${indice < enumeracao.valores.length - 1 ? "," : ""}`);
|
|
405
|
+
return `${indentacao(nivel)}enum ${enumeracao.nome} {\n${corpo.join("\n")}\n${indentacao(nivel)}}`;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
function renderizarTipo(type: TypeAst, nivel: number): string {
|
|
409
|
+
return `${indentacao(nivel)}type ${type.nome} {\n${renderizarCorpoSimples(type.corpo, nivel + 1)}\n${indentacao(nivel)}}`;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
function renderizarEntity(entity: EntityAst, nivel: number): string {
|
|
413
|
+
return `${indentacao(nivel)}entity ${entity.nome} {\n${renderizarCorpoSimples(entity.corpo, nivel + 1)}\n${indentacao(nivel)}}`;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function renderizarTask(task: TaskAst, nivel: number): string {
|
|
417
|
+
return `${indentacao(nivel)}task ${task.nome} {\n${renderizarCorpoSimples(task.corpo, nivel + 1)}\n${indentacao(nivel)}}`;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
function renderizarFlow(flow: FlowAst, nivel: number): string {
|
|
421
|
+
return `${indentacao(nivel)}flow ${flow.nome} {\n${renderizarCorpoSimples(flow.corpo, nivel + 1)}\n${indentacao(nivel)}}`;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function renderizarRoute(route: RouteAst, nivel: number): string {
|
|
425
|
+
return `${indentacao(nivel)}route ${route.nome} {\n${renderizarCorpoSimples(route.corpo, nivel + 1)}\n${indentacao(nivel)}}`;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
function renderizarState(state: StateAst, nivel: number): string {
|
|
429
|
+
return `${indentacao(nivel)}state${state.nome ? ` ${state.nome}` : ""} {\n${renderizarCorpoSimples(state.corpo, nivel + 1)}\n${indentacao(nivel)}}`;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
function renderizarCorpoSimples(bloco: BlocoGenericoAst, nivel: number): string {
|
|
433
|
+
const conteudo = ordenarSubblocos(bloco).map((subbloco) => renderizarBlocoAst(subbloco, nivel));
|
|
434
|
+
const campos = ordenarCampos(bloco).map((campo) => renderizarCampo(campo, nivel, bloco.palavraChave));
|
|
435
|
+
const linhas = bloco.linhas.map((linha) => renderizarLinha(linha.conteudo, nivel));
|
|
436
|
+
const corpo = [...campos, ...linhas, ...conteudo];
|
|
437
|
+
return corpo.join("\n");
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
function renderizarModulo(modulo: ModuloAst): string {
|
|
441
|
+
const blocos: Array<{ chave: string; conteudo: string }> = [];
|
|
442
|
+
|
|
443
|
+
if (modulo.docs) {
|
|
444
|
+
blocos.push({ chave: "docs", conteudo: renderizarBlocoGenerico(modulo.docs, 1) });
|
|
445
|
+
}
|
|
446
|
+
if (modulo.comments) {
|
|
447
|
+
blocos.push({ chave: "comments", conteudo: renderizarBlocoGenerico(modulo.comments, 1) });
|
|
448
|
+
}
|
|
449
|
+
for (const use of modulo.uses) {
|
|
450
|
+
blocos.push({ chave: "use", conteudo: renderizarBlocoAst(use, 1) });
|
|
451
|
+
}
|
|
452
|
+
if (modulo.vinculos) {
|
|
453
|
+
blocos.push({ chave: "vinculos", conteudo: renderizarBlocoGenerico(modulo.vinculos, 1) });
|
|
454
|
+
}
|
|
455
|
+
for (const database of modulo.databases) {
|
|
456
|
+
blocos.push({ chave: "database", conteudo: renderizarBlocoGenerico(database, 1) });
|
|
457
|
+
}
|
|
458
|
+
for (const type of modulo.types) {
|
|
459
|
+
blocos.push({ chave: "type", conteudo: renderizarBlocoAst(type, 1) });
|
|
460
|
+
}
|
|
461
|
+
for (const entity of modulo.entities) {
|
|
462
|
+
blocos.push({ chave: "entity", conteudo: renderizarBlocoAst(entity, 1) });
|
|
463
|
+
}
|
|
464
|
+
for (const enumeracao of modulo.enums) {
|
|
465
|
+
blocos.push({ chave: "enum", conteudo: renderizarBlocoAst(enumeracao, 1) });
|
|
466
|
+
}
|
|
467
|
+
for (const state of modulo.states) {
|
|
468
|
+
blocos.push({ chave: "state", conteudo: renderizarBlocoAst(state, 1) });
|
|
469
|
+
}
|
|
470
|
+
for (const task of modulo.tasks) {
|
|
471
|
+
blocos.push({ chave: "task", conteudo: renderizarBlocoAst(task, 1) });
|
|
472
|
+
}
|
|
473
|
+
for (const flow of modulo.flows) {
|
|
474
|
+
blocos.push({ chave: "flow", conteudo: renderizarBlocoAst(flow, 1) });
|
|
475
|
+
}
|
|
476
|
+
for (const route of modulo.routes) {
|
|
477
|
+
blocos.push({ chave: "route", conteudo: renderizarBlocoAst(route, 1) });
|
|
478
|
+
}
|
|
479
|
+
for (const worker of modulo.workers) {
|
|
480
|
+
blocos.push({ chave: "worker", conteudo: renderizarBlocoGenerico(worker, 1) });
|
|
481
|
+
}
|
|
482
|
+
for (const evento of modulo.eventos) {
|
|
483
|
+
blocos.push({ chave: "evento", conteudo: renderizarBlocoGenerico(evento, 1) });
|
|
484
|
+
}
|
|
485
|
+
for (const fila of modulo.filas) {
|
|
486
|
+
blocos.push({ chave: "fila", conteudo: renderizarBlocoGenerico(fila, 1) });
|
|
487
|
+
}
|
|
488
|
+
for (const cron of modulo.crons) {
|
|
489
|
+
blocos.push({ chave: "cron", conteudo: renderizarBlocoGenerico(cron, 1) });
|
|
490
|
+
}
|
|
491
|
+
for (const webhook of modulo.webhooks) {
|
|
492
|
+
blocos.push({ chave: "webhook", conteudo: renderizarBlocoGenerico(webhook, 1) });
|
|
493
|
+
}
|
|
494
|
+
for (const cache of modulo.caches) {
|
|
495
|
+
blocos.push({ chave: "cache", conteudo: renderizarBlocoGenerico(cache, 1) });
|
|
496
|
+
}
|
|
497
|
+
for (const storage of modulo.storages) {
|
|
498
|
+
blocos.push({ chave: "storage", conteudo: renderizarBlocoGenerico(storage, 1) });
|
|
499
|
+
}
|
|
500
|
+
for (const policy of modulo.policies) {
|
|
501
|
+
blocos.push({ chave: "policy", conteudo: renderizarBlocoGenerico(policy, 1) });
|
|
502
|
+
}
|
|
503
|
+
if (modulo.tests) {
|
|
504
|
+
blocos.push({ chave: "tests", conteudo: renderizarBlocoGenerico(modulo.tests, 1) });
|
|
505
|
+
}
|
|
506
|
+
for (const extra of modulo.extras) {
|
|
507
|
+
blocos.push({ chave: "desconhecido", conteudo: renderizarBlocoGenerico(extra, 1) });
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
const ordenados = ordenarPorMapa(blocos, (item) => item.chave, ORDEM_BLOCOS_MODULO);
|
|
511
|
+
return `module ${modulo.nome} {\n${ordenados.map((item) => item.conteudo).join("\n\n")}\n}\n`;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
export function formatarCodigo(codigo: string, arquivo?: string): ResultadoFormatacao {
|
|
515
|
+
const resultadoLexer = tokenizar(codigo, arquivo);
|
|
516
|
+
const resultadoParser = parsear(resultadoLexer.tokens);
|
|
517
|
+
const diagnosticos = [...resultadoLexer.diagnosticos, ...resultadoParser.diagnosticos];
|
|
518
|
+
|
|
519
|
+
if (!resultadoParser.modulo) {
|
|
520
|
+
return { diagnosticos, alterado: false };
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
const codigoFormatado = renderizarModulo(resultadoParser.modulo);
|
|
524
|
+
return {
|
|
525
|
+
modulo: resultadoParser.modulo,
|
|
526
|
+
codigoFormatado,
|
|
527
|
+
diagnosticos,
|
|
528
|
+
alterado: codigoFormatado !== codigo,
|
|
529
|
+
};
|
|
530
|
+
}
|