@mocoto/mahoraga 0.14.1 → 0.14.3
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 +0 -34
- package/dist/analysts/architects/analyst-structure.js +20 -20
- package/dist/analysts/architects/archetypes-custom.js +16 -19
- package/dist/analysts/architects/detector-archetypes.js +43 -36
- package/dist/analysts/architects/orchestrator-archetypes.js +3 -3
- package/dist/analysts/architects/signals-project-advanced.js +26 -28
- package/dist/analysts/architects/signals-project.js +2 -2
- package/dist/analysts/architects/strategist-structure.js +47 -66
- package/dist/analysts/azure-pipelines/analysts/analyst-azure.js +41 -35
- package/dist/analysts/azure-pipelines/corrections/correction-azure.js +22 -19
- package/dist/analysts/azure-pipelines/detectors/detector-azure-performance.js +21 -18
- package/dist/analysts/azure-pipelines/detectors/detector-azure-security.js +25 -20
- package/dist/analysts/azure-pipelines/detectors/detector-azure-structure.js +39 -40
- package/dist/analysts/azure-pipelines/scorers/scorer-azure.js +10 -7
- package/dist/analysts/circleci/analysts/analyst-circleci.js +33 -27
- package/dist/analysts/circleci/corrections/correction-circleci.js +22 -20
- package/dist/analysts/circleci/detectors/detector-circleci-performance.js +23 -19
- package/dist/analysts/circleci/detectors/detector-circleci-security.js +78 -82
- package/dist/analysts/circleci/detectors/detector-circleci-structure.js +22 -22
- package/dist/analysts/converters/convert-registry.js +1 -1
- package/dist/analysts/converters/engines/converter-gha-to-gitlab.js +17 -15
- package/dist/analysts/converters/index.js +1 -1
- package/dist/analysts/corrections/analyst-quick-fixes.js +25 -28
- package/dist/analysts/corrections/analyst-scoring.js +24 -21
- package/dist/analysts/corrections/auto-fix-engine.js +1 -1
- package/dist/analysts/corrections/corrector-structure.js +43 -42
- package/dist/analysts/corrections/fix-alias-imports.js +10 -6
- package/dist/analysts/corrections/fix-md-fences.js +23 -23
- package/dist/analysts/corrections/map-reversion.js +56 -53
- package/dist/analysts/corrections/pruning.js +19 -16
- package/dist/analysts/corrections/quick-fixes/fix-any-to-proper-type.js +57 -61
- package/dist/analysts/corrections/quick-fixes/fix-unknown-to-specific-type.js +30 -30
- package/dist/analysts/corrections/reorganize-barrels.js +13 -13
- package/dist/analysts/corrections/rewrite-testes-aliases.js +23 -22
- package/dist/analysts/corrections/scoring-shared.js +19 -18
- package/dist/analysts/corrections/type-safety/context-analyzer.js +15 -10
- package/dist/analysts/corrections/type-safety/type-analyzer.js +3 -3
- package/dist/analysts/corrections/type-safety/type-validator.js +4 -3
- package/dist/analysts/corrections/type-safety/usage-analyzer.js +39 -42
- package/dist/analysts/css/analysts/analyst-css.js +42 -42
- package/dist/analysts/css/corrections/correction-css.js +19 -11
- package/dist/analysts/css/detectors/detector-css-best-practices.js +129 -118
- package/dist/analysts/css/scorers/scorer-css.js +23 -18
- package/dist/analysts/css-in-js/analysts/analyst-css-in-js.js +24 -17
- package/dist/analysts/css-in-js/corrections/correction-css-in-js.js +31 -16
- package/dist/analysts/css-in-js/detectors/detector-css-in-js-best-practices.js +28 -30
- package/dist/analysts/css-in-js/scorers/scorer-css-in-js.js +79 -54
- package/dist/analysts/css-in-js/shared.js +7 -0
- package/dist/analysts/detectors/detector-architecture.js +91 -85
- package/dist/analysts/detectors/detector-bugs-ml.js +29 -27
- package/dist/analysts/detectors/detector-code-fragile.js +41 -36
- package/dist/analysts/detectors/detector-dependencies.js +5 -5
- package/dist/analysts/detectors/detector-duplications.js +26 -26
- package/dist/analysts/detectors/detector-monorepo.js +51 -45
- package/dist/analysts/detectors/detector-performance.js +24 -17
- package/dist/analysts/detectors/detector-recommendation-architecture.js +40 -36
- package/dist/analysts/detectors/detector-security.js +43 -42
- package/dist/analysts/detectors/detector-structure.js +31 -28
- package/dist/analysts/github-actions/analysts/analyst-github-actions.js +5 -8
- package/dist/analysts/github-actions/detectors/detector-workflow-accessibility.js +1 -9
- package/dist/analysts/github-actions/detectors/detector-workflow-structure.js +1 -4
- package/dist/analysts/github-actions/detectors/detector-workflow-trigger-unsafe.js +6 -5
- package/dist/analysts/gitlab-ci/analysts/analyst-gitlab-ci.js +2 -2
- package/dist/analysts/gitlab-ci/detectors/detector-gitlab-ci-structure.js +0 -3
- package/dist/analysts/go/analysts/analyst-best-practices.js +2 -2
- package/dist/analysts/go/analysts/analyst-concurrency.js +1 -1
- package/dist/analysts/go/analysts/analyst-security.js +1 -1
- package/dist/analysts/go/detectors/detector-conventions.js +1 -1
- package/dist/analysts/html/analysts/analyst-html.js +10 -12
- package/dist/analysts/html/detectors/detector-html.js +3 -3
- package/dist/analysts/js-ts/analysts/analyst-commands-cli.js +22 -22
- package/dist/analysts/js-ts/analysts/analyst-functions-long.js +5 -5
- package/dist/analysts/js-ts/analysts/analyst-patterns-usage.js +6 -2
- package/dist/analysts/js-ts/detectors/detector-anti-patterns-async.js +84 -9
- package/dist/analysts/js-ts/detectors/detector-constructions-syntactic.js +33 -10
- package/dist/analysts/js-ts/detectors/detector-context-smart.js +6 -6
- package/dist/analysts/js-ts/detectors/detector-leaks-memory.js +1 -1
- package/dist/analysts/js-ts/detectors/detector-types-unsafe.js +33 -2
- package/dist/analysts/php/analysts/analyst-php.js +3 -3
- package/dist/analysts/php/detectors/detector-php-best-practices.js +5 -5
- package/dist/analysts/php/detectors/detector-php-security.js +5 -5
- package/dist/analysts/php/scorers/scorer-php.js +2 -2
- package/dist/analysts/plugins/detector-documentation.js +6 -6
- package/dist/analysts/plugins/detector-markdown.js +7 -7
- package/dist/analysts/python/analysts/analyst-python.js +2 -5
- package/dist/analysts/react/analysts/analyst-react-hooks.js +66 -9
- package/dist/analysts/react/analysts/analyst-react.js +46 -2
- package/dist/analysts/react/corrections/correction-react.js +41 -1
- package/dist/analysts/react/detectors/detector-react-best-practices.js +5 -5
- package/dist/analysts/react/scorers/scorer-react.js +36 -1
- package/dist/analysts/registry/autodiscovery.js +2 -2
- package/dist/analysts/rust/analysts/analyst-best-practices.js +42 -3
- package/dist/analysts/rust/analysts/analyst-memory.js +2 -2
- package/dist/analysts/rust/analysts/analyst-rust.js +52 -5
- package/dist/analysts/rust/analysts/analyst-security.js +29 -1
- package/dist/analysts/scorers/scorer.js +5 -5
- package/dist/analysts/shell/analysts/analyst-shell.js +81 -5
- package/dist/analysts/shell/corrections/correction-shell.js +34 -1
- package/dist/analysts/shell/detectors/detector-shell-security.js +88 -0
- package/dist/analysts/shell/scorers/scorer-shell.js +58 -1
- package/dist/analysts/strategists/operator-structure.js +5 -7
- package/dist/analysts/strategists/suggestions-contextuais.js +5 -2
- package/dist/analysts/svg/analysts/analyst-svg.js +1 -0
- package/dist/analysts/tailwind/analysts/analyst-tailwind.js +79 -55
- package/dist/analysts/tailwind/corrections/correction-tailwind.js +108 -9
- package/dist/analysts/tailwind/detectors/detector-tailwind-best-practices.js +122 -7
- package/dist/analysts/tailwind/scorers/scorer-tailwind.js +62 -11
- package/dist/analysts/xml/analysts/analyst-xml.js +2 -2
- package/dist/app/index.js +1 -0
- package/dist/bin/cli-bootstrap.js +6 -4
- package/dist/bin/index.js +6 -4
- package/dist/caretakers/scoring.js +1 -0
- package/dist/cli/commands/command-analysts.js +4 -3
- package/dist/cli/commands/command-azure.js +1 -1
- package/dist/cli/commands/command-circleci.js +1 -1
- package/dist/cli/commands/command-compliance.js +1 -1
- package/dist/cli/commands/command-diagnose.js +10 -13
- package/dist/cli/commands/command-fix-types.js +9 -32
- package/dist/cli/commands/command-formatters.js +2 -2
- package/dist/cli/commands/command-github-actions.js +1 -1
- package/dist/cli/commands/command-gitlab-ci.js +1 -1
- package/dist/cli/commands/command-guardian.js +1 -1
- package/dist/cli/commands/command-imports.js +6 -6
- package/dist/cli/commands/command-jenkins.js +1 -1
- package/dist/cli/commands/command-licenses.js +1 -1
- package/dist/cli/commands/command-marketplace.js +7 -7
- package/dist/cli/commands/command-names.js +3 -8
- package/dist/cli/commands/command-perf.js +7 -9
- package/dist/cli/commands/command-plugins.js +4 -4
- package/dist/cli/diagnostic/auto-fix.js +2 -2
- package/dist/cli/diagnostic/exporters/json-exporter.js +1 -1
- package/dist/cli/diagnostic/exporters/sharded-exporter.js +0 -3
- package/dist/cli/diagnostic/exporters/svg-optimization-exporter.js +1 -1
- package/dist/cli/diagnostic/filters.js +9 -9
- package/dist/cli/diagnostic/handlers/archetype-handler.js +3 -6
- package/dist/cli/diagnostic/handlers/auto-fix-handler.js +4 -4
- package/dist/cli/diagnostic/handlers/guardian-handler.js +1 -1
- package/dist/cli/diagnostic/processing-diagnostic.js +31 -35
- package/dist/cli/diagnostic/processing-helpers.js +2 -2
- package/dist/cli/handlers/fix-types-exporter.js +1 -4
- package/dist/cli/helpers/display-frame.js +5 -5
- package/dist/core/config/auto/auto-fix-config.js +0 -6
- package/dist/core/config/chalk-safe.js +6 -6
- package/dist/core/config/config.js +11 -13
- package/dist/core/config/conventions.js +1 -1
- package/dist/core/config/security.js +2 -2
- package/dist/core/execution/analysis-cache.js +5 -8
- package/dist/core/execution/ast-cache.js +1 -3
- package/dist/core/execution/executor.js +8 -21
- package/dist/core/execution/inquisitor.js +24 -21
- package/dist/core/execution/results.js +1 -0
- package/dist/core/execution/scanner.js +4 -4
- package/dist/core/messages/en/analysts/analyst-github-actions-messages.js +1 -1
- package/dist/core/messages/en/analysts/analyst-patterns-usage-messages.js +1 -0
- package/dist/core/messages/en/analysts/analyst-shell-messages.js +15 -0
- package/dist/core/messages/en/analysts/detector-constructions-syntactic-messages.js +6 -0
- package/dist/core/messages/en/analysts/detector-js-ts-messages.js +27 -0
- package/dist/core/messages/en/analysts/detector-react-messages.js +8 -0
- package/dist/core/messages/en/analysts/detector-shell-messages.js +17 -0
- package/dist/core/messages/en/analysts/detector-tailwind-messages.js +3 -3
- package/dist/core/messages/en/analysts/report-circleci-messages.js +7 -7
- package/dist/core/messages/en/caretakers/caretaker-messages.js +1 -7
- package/dist/core/messages/en/core/plugin-messages.js +31 -3
- package/dist/core/messages/en/log/log.js +4 -4
- package/dist/core/messages/en/ui/filter-config.js +1 -5
- package/dist/core/messages/i18n-system.js +3 -3
- package/dist/core/messages/index.js +3 -3
- package/dist/core/messages/ja/analysts/analyst-github-actions-messages.js +1 -1
- package/dist/core/messages/ja/analysts/analyst-patterns-usage-messages.js +1 -0
- package/dist/core/messages/ja/analysts/analyst-shell-messages.js +15 -0
- package/dist/core/messages/ja/analysts/detector-constructions-syntactic-messages.js +6 -0
- package/dist/core/messages/ja/analysts/detector-js-ts-messages.js +27 -0
- package/dist/core/messages/ja/analysts/detector-react-messages.js +8 -0
- package/dist/core/messages/ja/analysts/detector-shell-messages.js +17 -0
- package/dist/core/messages/ja/analysts/detector-tailwind-messages.js +3 -3
- package/dist/core/messages/ja/analysts/report-circleci-messages.js +7 -7
- package/dist/core/messages/ja/caretakers/caretaker-messages.js +1 -7
- package/dist/core/messages/ja/core/plugin-messages.js +31 -3
- package/dist/core/messages/ja/log/log.js +4 -4
- package/dist/core/messages/ja/ui/filter-config.js +1 -1
- package/dist/core/messages/pt/analysts/analyst-github-actions-messages.js +1 -1
- package/dist/core/messages/pt/analysts/analyst-patterns-usage-messages.js +1 -0
- package/dist/core/messages/pt/analysts/analyst-shell-messages.js +15 -0
- package/dist/core/messages/pt/analysts/detector-constructions-syntactic-messages.js +6 -0
- package/dist/core/messages/pt/analysts/detector-js-ts-messages.js +27 -0
- package/dist/core/messages/pt/analysts/detector-react-messages.js +8 -0
- package/dist/core/messages/pt/analysts/detector-shell-messages.js +17 -0
- package/dist/core/messages/pt/analysts/detector-tailwind-messages.js +3 -3
- package/dist/core/messages/pt/analysts/report-circleci-messages.js +7 -7
- package/dist/core/messages/pt/caretakers/caretaker-messages.js +1 -7
- package/dist/core/messages/pt/core/plugin-messages.js +31 -3
- package/dist/core/messages/pt/log/log-engine.js +6 -6
- package/dist/core/messages/pt/log/log.js +3 -3
- package/dist/core/messages/pt/ui/filter-config.js +1 -1
- package/dist/core/messages/shared/icons.js +3 -3
- package/dist/core/messages/zh/analysts/analyst-github-actions-messages.js +1 -1
- package/dist/core/messages/zh/analysts/analyst-patterns-usage-messages.js +1 -0
- package/dist/core/messages/zh/analysts/analyst-shell-messages.js +15 -0
- package/dist/core/messages/zh/analysts/detector-constructions-syntactic-messages.js +6 -0
- package/dist/core/messages/zh/analysts/detector-js-ts-messages.js +27 -0
- package/dist/core/messages/zh/analysts/detector-react-messages.js +8 -0
- package/dist/core/messages/zh/analysts/detector-shell-messages.js +17 -0
- package/dist/core/messages/zh/analysts/detector-tailwind-messages.js +3 -3
- package/dist/core/messages/zh/analysts/report-circleci-messages.js +7 -7
- package/dist/core/messages/zh/caretakers/caretaker-messages.js +1 -7
- package/dist/core/messages/zh/core/plugin-messages.js +31 -3
- package/dist/core/messages/zh/log/log.js +3 -3
- package/dist/core/messages/zh/ui/filter-config.js +1 -5
- package/dist/core/parsing/filters.js +3 -3
- package/dist/core/parsing/langs/json.js +1 -1
- package/dist/core/parsing/langs/python.js +1 -1
- package/dist/core/parsing/langs/typescript.js +1 -1
- package/dist/core/parsing/parser.js +3 -4
- package/dist/core/parsing/utils.js +1 -0
- package/dist/core/registry/file-registry.js +3 -2
- package/dist/core/registry/paths.js +3 -3
- package/dist/core/reporting/default-reporter.js +2 -2
- package/dist/core/schema/version.js +6 -6
- package/dist/core/workers/worker-executor.js +3 -3
- package/dist/core/workers/worker-pool.js +0 -0
- package/dist/guardian/baseline.js +1 -1
- package/dist/guardian/gpg.js +3 -1
- package/dist/guardian/integrity.js +2 -7
- package/dist/guardian/records.js +7 -1
- package/dist/guardian/result.js +1 -1
- package/dist/guardian/sentinel.js +7 -1
- package/dist/guardian/watcher-hidden.js +6 -1
- package/dist/licenses/fs-utils.js +5 -1
- package/dist/licenses/generate-notices.js +1 -1
- package/dist/licenses/index.js +1 -0
- package/dist/licenses/normalizer.js +10 -9
- package/dist/node.loader.js +224 -4
- package/dist/reports/analise-async-patterns.js +1 -1
- package/dist/reports/filter-smart.js +2 -5
- package/dist/reports/generator-report.js +7 -7
- package/dist/reports/report-archetypes.js +10 -10
- package/dist/reports/report-caretaker-health.js +2 -1
- package/dist/reports/report-patterns-usage.js +1 -1
- package/dist/sdk/analyzer.js +1 -1
- package/dist/shared/data-processing/fragment-report.js +11 -11
- package/dist/shared/data-processing/json.js +1 -1
- package/dist/shared/data-processing/occurrences.js +3 -2
- package/dist/shared/formatters/code-min-formatter.js +1 -1
- package/dist/shared/formatters/engines/prettier.js +1 -1
- package/dist/shared/formatters/engines/stylelint.js +43 -40
- package/dist/shared/formatters/formatter.js +8 -8
- package/dist/shared/formatters/formatters/code.js +3 -3
- package/dist/shared/formatters/formatters/css.js +2 -10
- package/dist/shared/formatters/formatters/dotfiles.js +1 -1
- package/dist/shared/formatters/formatters/html.js +1 -5
- package/dist/shared/formatters/formatters/json.js +0 -3
- package/dist/shared/formatters/formatters/markdown.js +19 -24
- package/dist/shared/formatters/formatters/properties.js +2 -2
- package/dist/shared/formatters/formatters/shell.js +1 -4
- package/dist/shared/formatters/formatters/sql.js +0 -3
- package/dist/shared/formatters/formatters/xml.js +5 -7
- package/dist/shared/formatters/formatters/yaml.js +2 -7
- package/dist/shared/formatters/index.js +1 -1
- package/dist/shared/helpers/framework-detector.js +6 -2
- package/dist/shared/helpers/json.js +1 -1
- package/dist/shared/helpers/magic-constants-whitelist.js +1 -1
- package/dist/shared/helpers/masking.js +17 -17
- package/dist/shared/helpers/reader-report.js +0 -12
- package/dist/shared/helpers/structural-hash.js +3 -2
- package/dist/shared/helpers/structure.js +1 -1
- package/dist/shared/marketplace/registry.js +1 -1
- package/dist/shared/marketplace/remote.js +4 -4
- package/dist/shared/persistence/persistence.js +13 -6
- package/dist/shared/plugins/core-plugin.js +5 -1
- package/dist/shared/plugins/registry.js +3 -2
- package/dist/types/analysts/tailwind-correction.js +2 -0
- package/dist/types/caretakers/imports-barrel.js +1 -0
- package/dist/types/caretakers/index.js +4 -0
- package/dist/types/caretakers/map-reversion.js +1 -0
- package/dist/types/caretakers/pruning.js +1 -0
- package/dist/types/caretakers/scoring.js +1 -0
- package/dist/types/common/analysts.js +1 -1
- package/dist/types/core/config/filters.js +1 -0
- package/dist/types/core/config/index.js +2 -0
- package/dist/types/core/execution/ambiente.js +1 -0
- package/dist/types/core/execution/linguagens.js +1 -0
- package/dist/types/core/execution/parse-errors.js +1 -0
- package/dist/types/core/execution/results.js +1 -0
- package/dist/types/core/execution/structure-json.js +1 -0
- package/dist/types/core/index.js +1 -0
- package/dist/types/core/messages/index.js +1 -0
- package/dist/types/core/messages/log.js +1 -0
- package/dist/types/core/parsing/babel-narrow.js +1 -0
- package/dist/types/core/parsing/index.js +1 -0
- package/dist/types/core/runtime.js +1 -0
- package/dist/types/guardian/index.js +2 -0
- package/dist/types/guardian/integrity.js +7 -0
- package/dist/types/guardian/snapshot.js +1 -0
- package/dist/types/index.js +4 -4
- package/dist/types/licenses/index.js +2 -0
- package/dist/types/processing/display.js +16 -13
- package/dist/types/processing/filters.js +8 -11
- package/dist/types/reports/compliance.js +1 -0
- package/dist/types/reports/streaming.js +1 -0
- package/dist/types/scripts/index.js +1 -0
- package/dist/types/scripts/migrar-aliases.js +1 -0
- package/dist/types/sdk/index.js +1 -0
- package/dist/types/shared/index.js +2 -0
- package/dist/types/vulnerabilities/index.js +2 -0
- package/dist/vulnerabilities/scanner.js +3 -2
- package/package.json +14 -20
|
@@ -10,9 +10,10 @@ import { analyzeTypeUsage } from '../type-safety/type-analyzer.js';
|
|
|
10
10
|
import { createTypeDefinition } from '../type-safety/type-creator.js';
|
|
11
11
|
import { validateTypeReplacement } from '../type-safety/type-validator.js';
|
|
12
12
|
const { MENSAGENS_CORRECAO_TIPOS } = getMessages();
|
|
13
|
+
const CONFIANCA_MEDIA = 60;
|
|
13
14
|
const CONFIANCA_NIVEIS = {
|
|
14
15
|
HIGH: 85,
|
|
15
|
-
MEDIUM:
|
|
16
|
+
MEDIUM: CONFIANCA_MEDIA,
|
|
16
17
|
DEFAULT: 70
|
|
17
18
|
};
|
|
18
19
|
export const fixAnyToProperTipo = {
|
|
@@ -62,66 +63,7 @@ export async function fixAnyToProperTypeAsync(match, fullCode, fileCaminho, ast)
|
|
|
62
63
|
const typeAnalise = analyzeTypeUsage(match, fullCode, fileCaminho, ast);
|
|
63
64
|
// 2. Estratégia baseada em confiança
|
|
64
65
|
if (typeAnalise.confidence >= CONFIANCA_NIVEIS.HIGH) {
|
|
65
|
-
|
|
66
|
-
if (typeAnalise.isSimpleType) {
|
|
67
|
-
// Tipo primitivo: substituir diretamente
|
|
68
|
-
const fixedCodigo = fullCode.replace(match[0], `: ${typeAnalise.inferredTipo}`);
|
|
69
|
-
// Validar resultado
|
|
70
|
-
const validation = await validateTypeReplacement(fullCode, fixedCodigo, typeAnalise);
|
|
71
|
-
if (!validation.isCompatible) {
|
|
72
|
-
return {
|
|
73
|
-
code: fullCode,
|
|
74
|
-
applied: false,
|
|
75
|
-
reason: `Validação falhou: ${validation.errors.join(', ')}`,
|
|
76
|
-
warnings: validation.warnings.map(dimensaoLargura => ({
|
|
77
|
-
type: 'unsafe-type',
|
|
78
|
-
message: dimensaoLargura,
|
|
79
|
-
suggestion: 'Revise manualmente'
|
|
80
|
-
}))
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
return {
|
|
84
|
-
code: fixedCodigo,
|
|
85
|
-
applied: true,
|
|
86
|
-
warnings: validation.warnings.map(dimensaoLargura => ({
|
|
87
|
-
type: 'type-suggestion',
|
|
88
|
-
message: dimensaoLargura,
|
|
89
|
-
suggestion: MENSAGENS_CORRECAO_TIPOS.validacao.revisar
|
|
90
|
-
}))
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
// Tipo complexo: criar interface
|
|
95
|
-
const typeCaminho = await createTypeDefinition(typeAnalise, fileCaminho);
|
|
96
|
-
const importStatement = `import type { ${typeAnalise.typeName} } from '${typeCaminho}';\n`;
|
|
97
|
-
// Adicionar import no topo e substituir any
|
|
98
|
-
const lines = fullCode.split('\n');
|
|
99
|
-
const importIndex = findImportInsertionPoint(lines);
|
|
100
|
-
lines.splice(importIndex, 0, importStatement);
|
|
101
|
-
let fixedCodigo = lines.join('\n');
|
|
102
|
-
fixedCodigo = fixedCodigo.replace(match[0], `: ${typeAnalise.typeName}`);
|
|
103
|
-
// Validar resultado
|
|
104
|
-
const validation = await validateTypeReplacement(fullCode, fixedCodigo, typeAnalise);
|
|
105
|
-
if (!validation.isCompatible) {
|
|
106
|
-
return {
|
|
107
|
-
code: fullCode,
|
|
108
|
-
applied: false,
|
|
109
|
-
reason: `Validação falhou: ${validation.errors.join(', ')}`
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
return {
|
|
113
|
-
code: fixedCodigo,
|
|
114
|
-
applied: true,
|
|
115
|
-
additionalChanges: [{
|
|
116
|
-
type: 'add-import',
|
|
117
|
-
content: importStatement
|
|
118
|
-
}, {
|
|
119
|
-
type: 'create-type-file',
|
|
120
|
-
content: typeAnalise.typeDefinition,
|
|
121
|
-
path: buildTypesRelPathPosix(typeAnalise.suggestedPath)
|
|
122
|
-
}]
|
|
123
|
-
};
|
|
124
|
-
}
|
|
66
|
+
return await applyHighConfidenceAnyFix(match, fullCode, fileCaminho, typeAnalise);
|
|
125
67
|
}
|
|
126
68
|
else if (typeAnalise.confidence >= CONFIANCA_NIVEIS.MEDIUM) {
|
|
127
69
|
// MÉDIA CONFIANÇA: Sugerir mas não aplicar
|
|
@@ -162,6 +104,60 @@ export async function fixAnyToProperTypeAsync(match, fullCode, fileCaminho, ast)
|
|
|
162
104
|
};
|
|
163
105
|
}
|
|
164
106
|
}
|
|
107
|
+
async function applyHighConfidenceAnyFix(match, fullCode, fileCaminho, typeAnalise) {
|
|
108
|
+
if (typeAnalise.isSimpleType) {
|
|
109
|
+
const fixedCodigo = fullCode.replace(match[0], `: ${typeAnalise.inferredTipo}`);
|
|
110
|
+
const validation = await validateTypeReplacement(fullCode, fixedCodigo, typeAnalise);
|
|
111
|
+
if (!validation.isCompatible) {
|
|
112
|
+
return {
|
|
113
|
+
code: fullCode,
|
|
114
|
+
applied: false,
|
|
115
|
+
reason: `Validação falhou: ${validation.errors.join(', ')}`,
|
|
116
|
+
warnings: validation.warnings.map(dimensaoLargura => ({
|
|
117
|
+
type: 'unsafe-type',
|
|
118
|
+
message: dimensaoLargura,
|
|
119
|
+
suggestion: 'Revise manualmente'
|
|
120
|
+
}))
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
code: fixedCodigo,
|
|
125
|
+
applied: true,
|
|
126
|
+
warnings: validation.warnings.map(dimensaoLargura => ({
|
|
127
|
+
type: 'type-suggestion',
|
|
128
|
+
message: dimensaoLargura,
|
|
129
|
+
suggestion: MENSAGENS_CORRECAO_TIPOS.validacao.revisar
|
|
130
|
+
}))
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
const typeCaminho = await createTypeDefinition(typeAnalise, fileCaminho);
|
|
134
|
+
const importStatement = `import type { ${typeAnalise.typeName} } from '${typeCaminho}';\n`;
|
|
135
|
+
const lines = fullCode.split('\n');
|
|
136
|
+
const importIndex = findImportInsertionPoint(lines);
|
|
137
|
+
lines.splice(importIndex, 0, importStatement);
|
|
138
|
+
let fixedCodigo = lines.join('\n');
|
|
139
|
+
fixedCodigo = fixedCodigo.replace(match[0], `: ${typeAnalise.typeName}`);
|
|
140
|
+
const validation = await validateTypeReplacement(fullCode, fixedCodigo, typeAnalise);
|
|
141
|
+
if (!validation.isCompatible) {
|
|
142
|
+
return {
|
|
143
|
+
code: fullCode,
|
|
144
|
+
applied: false,
|
|
145
|
+
reason: `Validação falhou: ${validation.errors.join(', ')}`
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
code: fixedCodigo,
|
|
150
|
+
applied: true,
|
|
151
|
+
additionalChanges: [{
|
|
152
|
+
type: 'add-import',
|
|
153
|
+
content: importStatement
|
|
154
|
+
}, {
|
|
155
|
+
type: 'create-type-file',
|
|
156
|
+
content: typeAnalise.typeDefinition,
|
|
157
|
+
path: buildTypesRelPathPosix(typeAnalise.suggestedPath)
|
|
158
|
+
}]
|
|
159
|
+
};
|
|
160
|
+
}
|
|
165
161
|
/**
|
|
166
162
|
* Encontra ponto de inserção para import
|
|
167
163
|
*/
|
|
@@ -51,36 +51,7 @@ export async function fixUnknownToSpecificTypeAsync(match, fullCode, fileCaminho
|
|
|
51
51
|
const typeAnalise = await analyzeUnknownUsage(match, fullCode, fileCaminho, ast);
|
|
52
52
|
// 2. Estratégia mais conservadora (requer >= 90% confiança)
|
|
53
53
|
if (typeAnalise.confidence >= 90) {
|
|
54
|
-
|
|
55
|
-
const typeCaminho = await createTypeDefinition(typeAnalise, fileCaminho);
|
|
56
|
-
const importStatement = `import type { ${typeAnalise.typeName} } from '${typeCaminho}';\n`;
|
|
57
|
-
// Adicionar import e substituir unknown
|
|
58
|
-
const lines = fullCode.split('\n');
|
|
59
|
-
const importIndex = findImportInsertionPoint(lines);
|
|
60
|
-
lines.splice(importIndex, 0, importStatement);
|
|
61
|
-
let fixedCodigo = lines.join('\n');
|
|
62
|
-
fixedCodigo = fixedCodigo.replace(match[0], `: ${typeAnalise.typeName}`);
|
|
63
|
-
// Validar
|
|
64
|
-
const validation = await validateTypeReplacement(fullCode, fixedCodigo, typeAnalise);
|
|
65
|
-
if (!validation.isCompatible) {
|
|
66
|
-
return {
|
|
67
|
-
code: fullCode,
|
|
68
|
-
applied: false,
|
|
69
|
-
reason: `Validação falhou: ${validation.errors.join(', ')}`
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
return {
|
|
73
|
-
code: fixedCodigo,
|
|
74
|
-
applied: true,
|
|
75
|
-
additionalChanges: [{
|
|
76
|
-
type: 'add-import',
|
|
77
|
-
content: importStatement
|
|
78
|
-
}, {
|
|
79
|
-
type: 'create-type-file',
|
|
80
|
-
content: typeAnalise.typeDefinition,
|
|
81
|
-
path: buildTypesRelPathPosix(typeAnalise.suggestedPath)
|
|
82
|
-
}]
|
|
83
|
-
};
|
|
54
|
+
return await applyHighConfidenceUnknownFix(match, fullCode, fileCaminho, typeAnalise);
|
|
84
55
|
}
|
|
85
56
|
else if (typeAnalise.confidence >= 70) {
|
|
86
57
|
// MÉDIA CONFIANÇA: Sugerir tipo
|
|
@@ -120,6 +91,35 @@ export async function fixUnknownToSpecificTypeAsync(match, fullCode, fileCaminho
|
|
|
120
91
|
};
|
|
121
92
|
}
|
|
122
93
|
}
|
|
94
|
+
async function applyHighConfidenceUnknownFix(match, fullCode, fileCaminho, typeAnalise) {
|
|
95
|
+
const typeCaminho = await createTypeDefinition(typeAnalise, fileCaminho);
|
|
96
|
+
const importStatement = `import type { ${typeAnalise.typeName} } from '${typeCaminho}';\n`;
|
|
97
|
+
const lines = fullCode.split('\n');
|
|
98
|
+
const importIndex = findImportInsertionPoint(lines);
|
|
99
|
+
lines.splice(importIndex, 0, importStatement);
|
|
100
|
+
let fixedCodigo = lines.join('\n');
|
|
101
|
+
fixedCodigo = fixedCodigo.replace(match[0], `: ${typeAnalise.typeName}`);
|
|
102
|
+
const validation = await validateTypeReplacement(fullCode, fixedCodigo, typeAnalise);
|
|
103
|
+
if (!validation.isCompatible) {
|
|
104
|
+
return {
|
|
105
|
+
code: fullCode,
|
|
106
|
+
applied: false,
|
|
107
|
+
reason: `Validação falhou: ${validation.errors.join(', ')}`
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
code: fixedCodigo,
|
|
112
|
+
applied: true,
|
|
113
|
+
additionalChanges: [{
|
|
114
|
+
type: 'add-import',
|
|
115
|
+
content: importStatement
|
|
116
|
+
}, {
|
|
117
|
+
type: 'create-type-file',
|
|
118
|
+
content: typeAnalise.typeDefinition,
|
|
119
|
+
path: buildTypesRelPathPosix(typeAnalise.suggestedPath)
|
|
120
|
+
}]
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
123
|
/**
|
|
124
124
|
* Encontra ponto de inserção para import
|
|
125
125
|
*/
|
|
@@ -28,6 +28,15 @@ function resolverImportRelativo(arquivoRel, importSpec) {
|
|
|
28
28
|
const dir = path.posix.dirname(normalizarRel(arquivoRel));
|
|
29
29
|
return path.posix.normalize(path.posix.join(dir, importSpec));
|
|
30
30
|
}
|
|
31
|
+
function resolverImportSpec(spec, rel) {
|
|
32
|
+
if (spec.startsWith('@/')) {
|
|
33
|
+
return semExt(normalizarRel(`src/${spec.slice(2)}`));
|
|
34
|
+
}
|
|
35
|
+
if (spec.startsWith('@')) {
|
|
36
|
+
return semExt(normalizarRel(`src/${spec.slice(1)}`)).replace(/^src\//, '');
|
|
37
|
+
}
|
|
38
|
+
return semExt(resolverImportRelativo(rel, spec));
|
|
39
|
+
}
|
|
31
40
|
function criarMapaMovimentos(mapa, _baseDir) {
|
|
32
41
|
const movimentos = new Map();
|
|
33
42
|
for (const entry of mapa) {
|
|
@@ -231,16 +240,7 @@ async function atualizarImportsGlobais(srcDir, movimentos) {
|
|
|
231
240
|
if (!isRelative && !isAlias) {
|
|
232
241
|
continue;
|
|
233
242
|
}
|
|
234
|
-
|
|
235
|
-
if (spec.startsWith('@/')) {
|
|
236
|
-
resolved = semExt(normalizarRel(`src/${spec.slice(2)}`));
|
|
237
|
-
}
|
|
238
|
-
else if (spec.startsWith('@')) {
|
|
239
|
-
resolved = semExt(normalizarRel(`src/${spec.slice(1)}`)).replace(/^src\//, '');
|
|
240
|
-
}
|
|
241
|
-
else {
|
|
242
|
-
resolved = semExt(resolverImportRelativo(rel, spec));
|
|
243
|
-
}
|
|
243
|
+
const resolved = resolverImportSpec(spec, rel);
|
|
244
244
|
const moveDestino = movimentos.get(resolved);
|
|
245
245
|
if (!moveDestino) {
|
|
246
246
|
continue;
|
|
@@ -301,9 +301,9 @@ async function extrairNomesExportados(srcDir, relPath, visitados = new Set(), pr
|
|
|
301
301
|
nomes.add(exportDecl[1]);
|
|
302
302
|
}
|
|
303
303
|
// export { name1, name2 as alias, ... }
|
|
304
|
-
const exportList = trimmed.match(/^export\s+type\s
|
|
304
|
+
const exportList = trimmed.match(/^export\s+(?:type\s+)?\s*\{([^}]+)\}/);
|
|
305
305
|
if (exportList) {
|
|
306
|
-
const body = exportList[1]
|
|
306
|
+
const body = exportList[1];
|
|
307
307
|
if (body) {
|
|
308
308
|
body.split(',').forEach(part => {
|
|
309
309
|
const m = part.trim().match(/^(\w+)(?:\s+as\s+\w+)?$/);
|
|
@@ -469,7 +469,7 @@ async function repararImportsBarrelPerdidos(srcDir, barrelsPerdidos, _movimentos
|
|
|
469
469
|
if (!match) {
|
|
470
470
|
return null;
|
|
471
471
|
}
|
|
472
|
-
return { imported: match[1], local: match[2]
|
|
472
|
+
return { imported: match[1], local: match[2] || match[1] };
|
|
473
473
|
}).filter((n) => n !== null);
|
|
474
474
|
const nomesQueFicam = [];
|
|
475
475
|
const nomesQueMoveram = [];
|
|
@@ -19,7 +19,7 @@ function exists(caminho) {
|
|
|
19
19
|
function pathFromAlias(aliasSpec, srcRoot) {
|
|
20
20
|
const spec = aliasSpec.replace(/^@/, '');
|
|
21
21
|
const parts = spec.split('/');
|
|
22
|
-
const top = parts
|
|
22
|
+
const top = parts?.shift();
|
|
23
23
|
return path.join(srcRoot, top ?? '', parts.join('/'));
|
|
24
24
|
}
|
|
25
25
|
export function pickExtForAlias(aliasBase, srcRoot) {
|
|
@@ -67,40 +67,41 @@ export function rewriteToAlias(spec, ctx) {
|
|
|
67
67
|
export function transformCodeForTests(code, ctx) {
|
|
68
68
|
let changed = false;
|
|
69
69
|
const rewrite = (spec) => rewriteToAlias(spec, ctx);
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
let result = code;
|
|
71
|
+
result = result.replace(/(import\s+[^'"\n]+?from\s+)(["'])([^"']+?)\2/g, (substring, p1, delimitadorString, spec) => {
|
|
72
|
+
const res = rewrite(spec);
|
|
73
|
+
if (!res.changed) {
|
|
74
|
+
return substring;
|
|
74
75
|
}
|
|
75
76
|
changed = true;
|
|
76
|
-
return `${p1}${delimitadorString}${
|
|
77
|
+
return `${p1}${delimitadorString}${res.value}${delimitadorString}`;
|
|
77
78
|
});
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
if (!
|
|
81
|
-
return
|
|
79
|
+
result = result.replace(/(import\s*)(["'])([^"']+?)\2/g, (substring, p1, delimitadorString, spec) => {
|
|
80
|
+
const res = rewrite(spec);
|
|
81
|
+
if (!res.changed) {
|
|
82
|
+
return substring;
|
|
82
83
|
}
|
|
83
84
|
changed = true;
|
|
84
|
-
return `${p1}${delimitadorString}${
|
|
85
|
+
return `${p1}${delimitadorString}${res.value}${delimitadorString}`;
|
|
85
86
|
});
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
if (!
|
|
89
|
-
return
|
|
87
|
+
result = result.replace(/(import\s*\()(\s*["'])([^"']+?)(["']\s*\))/g, (substring, p1, q1, spec, q2) => {
|
|
88
|
+
const res = rewrite(spec);
|
|
89
|
+
if (!res.changed) {
|
|
90
|
+
return substring;
|
|
90
91
|
}
|
|
91
92
|
changed = true;
|
|
92
|
-
return `${p1}${q1}${
|
|
93
|
+
return `${p1}${q1}${res.value}${q2}`;
|
|
93
94
|
});
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
if (!
|
|
97
|
-
return
|
|
95
|
+
result = result.replace(/(vi\.(?:do)?mock\s*\()(\s*["'])([^"']+?)(["'])(\s*,?)/g, (substring, p1, q1, spec, q2, comma = '') => {
|
|
96
|
+
const res = rewrite(spec);
|
|
97
|
+
if (!res.changed) {
|
|
98
|
+
return substring;
|
|
98
99
|
}
|
|
99
100
|
changed = true;
|
|
100
|
-
return `${p1}${q1}${
|
|
101
|
+
return `${p1}${q1}${res.value}${q2}${comma}`;
|
|
101
102
|
});
|
|
102
103
|
return {
|
|
103
|
-
code,
|
|
104
|
+
code: result,
|
|
104
105
|
changed
|
|
105
106
|
};
|
|
106
107
|
}
|
|
@@ -236,6 +236,24 @@ export function fixSpacingAroundPunct(string) {
|
|
|
236
236
|
count
|
|
237
237
|
};
|
|
238
238
|
}
|
|
239
|
+
function getCharacterDisplayName(ch) {
|
|
240
|
+
try {
|
|
241
|
+
if (typeof Intl !== 'undefined') {
|
|
242
|
+
const intlApi = Intl;
|
|
243
|
+
const DisplayNomesCtor = intlApi.DisplayNames;
|
|
244
|
+
if (DisplayNomesCtor) {
|
|
245
|
+
const displayNomes = new DisplayNomesCtor(['en'], {
|
|
246
|
+
type: 'language'
|
|
247
|
+
});
|
|
248
|
+
return typeof displayNomes.of === 'function' ? displayNomes.of(ch) ?? '' : '';
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return '';
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
return '';
|
|
255
|
+
}
|
|
256
|
+
}
|
|
239
257
|
/**
|
|
240
258
|
* Detecta caracteres fora do range ASCII comum.
|
|
241
259
|
*/
|
|
@@ -248,24 +266,7 @@ export function detectUncommonChars(text, limite) {
|
|
|
248
266
|
}
|
|
249
267
|
const code = ch.codePointAt(0) ?? 0;
|
|
250
268
|
if (code >= LIMITES.ASCII_EXTENDED_MIN && !isCaractereComum(code)) {
|
|
251
|
-
const name = (
|
|
252
|
-
try {
|
|
253
|
-
if (typeof Intl !== 'undefined') {
|
|
254
|
-
const intlApi = Intl;
|
|
255
|
-
const DisplayNomesCtor = intlApi.DisplayNames;
|
|
256
|
-
if (DisplayNomesCtor) {
|
|
257
|
-
const displayNomes = new DisplayNomesCtor(['en'], {
|
|
258
|
-
type: 'language'
|
|
259
|
-
});
|
|
260
|
-
return typeof displayNomes.of === 'function' ? displayNomes.of(ch) ?? '' : '';
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
return '';
|
|
264
|
-
}
|
|
265
|
-
catch {
|
|
266
|
-
return '';
|
|
267
|
-
}
|
|
268
|
-
})();
|
|
269
|
+
const name = getCharacterDisplayName(ch);
|
|
269
270
|
issues.push({
|
|
270
271
|
tipo: 'caracteres-incomuns',
|
|
271
272
|
posicao: pos,
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Analisador de contexto para Type Safety Auto-Fix
|
|
6
6
|
* Detecta contextos onde any/unknown NÃO devem ser modificados
|
|
7
7
|
*/
|
|
8
|
+
const CONFIANCA_PADRAO = 60;
|
|
8
9
|
export { isInComment, isInString, isInStringOrComment } from '../../../shared/helpers/index.js';
|
|
9
10
|
/**
|
|
10
11
|
* Verifica se está em contexto TypeScript específico que deve ser ignorado
|
|
@@ -152,6 +153,13 @@ export function extractLineContext(code, position) {
|
|
|
152
153
|
}
|
|
153
154
|
return '';
|
|
154
155
|
}
|
|
156
|
+
function hasInternalValidation(code, lineContext) {
|
|
157
|
+
if (!/(analise|result|data|value)\s*:\s*unknown/.test(lineContext)) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
const beforeFunc = code.substring(Math.max(0, lineContext.length - 200), lineContext.length + 100);
|
|
161
|
+
return /if\s*\(/.test(beforeFunc) || /typeof\s+\w+\s*===/.test(beforeFunc);
|
|
162
|
+
}
|
|
155
163
|
export function categorizarUnknown(code, fileCaminho, lineContext) {
|
|
156
164
|
// Type Guards - 100% legítimo
|
|
157
165
|
if (/:\s*unknown\)\s*:\s*\w+\s+is\s+/.test(lineContext)) {
|
|
@@ -393,15 +401,12 @@ export function categorizarUnknown(code, fileCaminho, lineContext) {
|
|
|
393
401
|
};
|
|
394
402
|
}
|
|
395
403
|
// Função de análise com validação interna - 90% legítimo
|
|
396
|
-
if (
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
motivo: 'Parâmetro com validação/narrowing interna - unknown é seguro quando verificado'
|
|
403
|
-
};
|
|
404
|
-
}
|
|
404
|
+
if (hasInternalValidation(code, lineContext)) {
|
|
405
|
+
return {
|
|
406
|
+
categoria: 'legitimo',
|
|
407
|
+
confianca: 90,
|
|
408
|
+
motivo: 'Parâmetro com validação/narrowing interna - unknown é seguro quando verificado'
|
|
409
|
+
};
|
|
405
410
|
}
|
|
406
411
|
// Getter de keys com validação - 95% legítimo
|
|
407
412
|
if (/value\s*:\s*unknown/.test(lineContext) && /Object\.keys/.test(contextoAmplo)) {
|
|
@@ -422,7 +427,7 @@ export function categorizarUnknown(code, fileCaminho, lineContext) {
|
|
|
422
427
|
// Default: melhorável com análise incerta
|
|
423
428
|
return {
|
|
424
429
|
categoria: 'melhoravel',
|
|
425
|
-
confianca:
|
|
430
|
+
confianca: CONFIANCA_PADRAO,
|
|
426
431
|
motivo: 'Tipo unknown genérico - análise contextual limitada',
|
|
427
432
|
sugestao: 'Analisar fluxo de dados para inferir tipo correto',
|
|
428
433
|
variantes: ['Se vem de API externa: definir interface baseada na resposta esperada', 'Se é callback: especificar assinatura da função', 'Se é config/options: criar interface com campos opcionais', 'Se é polimórfico: considerar discriminated union ou generics']
|
|
@@ -62,14 +62,14 @@ export function analyzeTypeUsage(match, fullCode, fileCaminho, ast) {
|
|
|
62
62
|
/**
|
|
63
63
|
* Analisa uso de unknown com foco em type guards
|
|
64
64
|
*/
|
|
65
|
-
export
|
|
65
|
+
export function analyzeUnknownUsage(match, fullCode, fileCaminho, ast) {
|
|
66
66
|
// Mesma lógica de analyzeTypeUsage, mas mais conservador
|
|
67
67
|
const analysis = analyzeTypeUsage(match, fullCode, fileCaminho, ast);
|
|
68
68
|
// Penalizar confiança em 10% para unknown (mais conservador)
|
|
69
69
|
analysis.confidence = Math.max(0, analysis.confidence - 10);
|
|
70
70
|
// Se confiança ainda é baixa, sugerir manter unknown
|
|
71
71
|
if (analysis.confidence < 70) {
|
|
72
|
-
analysis.suggestion =
|
|
72
|
+
analysis.suggestion = `Confiança baixa para substituir unknown. Considere adicionar type guards ou criar tipo dedicado em ${getTypesDirectoryDisplay()}`;
|
|
73
73
|
}
|
|
74
|
-
return analysis;
|
|
74
|
+
return Promise.resolve(analysis);
|
|
75
75
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Verifica compatibilidade e compilação TypeScript
|
|
5
5
|
*/
|
|
6
6
|
import { findExistingType, isSameType } from './type-creator.js';
|
|
7
|
+
const CONFIANCA_MINIMA = 60;
|
|
7
8
|
/**
|
|
8
9
|
* Valida substituição de tipo (any/unknown → specific)
|
|
9
10
|
*/
|
|
@@ -18,13 +19,13 @@ export async function validateTypeReplacement(originalCode, fixedCodigo, typeAna
|
|
|
18
19
|
if (typeAnalise.createdNewType) {
|
|
19
20
|
const existingTipo = await findExistingType(typeAnalise.typeName);
|
|
20
21
|
if (existingTipo && !isSameType(existingTipo, typeAnalise.typeDefinition)) {
|
|
21
|
-
result.warnings.push(`Tipo ${typeAnalise.typeName} já existe com definição diferente.
|
|
22
|
+
result.warnings.push(`Tipo ${typeAnalise.typeName} já existe com definição diferente. Verifique conflito em ${existingTipo.path}`);
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
// 2. Verificar se tipo inferido é compatível com uso
|
|
25
26
|
const usageValidation = validateTypeUsageCompatibility(fixedCodigo, typeAnalise);
|
|
26
27
|
if (!usageValidation.isCompatible) {
|
|
27
|
-
result.errors.push(`Tipo inferido ${typeAnalise.inferredTipo} incompatível com uso detectado.
|
|
28
|
+
result.errors.push(`Tipo inferido ${typeAnalise.inferredTipo} incompatível com uso detectado. Esperado: ${usageValidation.expectedType}`);
|
|
28
29
|
result.isCompatible = false;
|
|
29
30
|
}
|
|
30
31
|
// 3. Verificar se import foi adicionado corretamente
|
|
@@ -36,7 +37,7 @@ export async function validateTypeReplacement(originalCode, fixedCodigo, typeAna
|
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
39
|
// 4. Verificar confiança mínima
|
|
39
|
-
if (typeAnalise.confidence <
|
|
40
|
+
if (typeAnalise.confidence < CONFIANCA_MINIMA) {
|
|
40
41
|
result.warnings.push(`Confiança muito baixa (${typeAnalise.confidence}%). Considere revisão manual.`);
|
|
41
42
|
}
|
|
42
43
|
// 5. Validar sintaxe básica do código modificado
|
|
@@ -128,49 +128,46 @@ function extractObjectProperties(usages) {
|
|
|
128
128
|
}
|
|
129
129
|
return Array.from(propertiesMap.values());
|
|
130
130
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
131
|
+
function detectTypeofGuard(usage, context, guards) {
|
|
132
|
+
const match = context.match(/typeof\s+\w+\s*===\s*['"](\w+)['"]/);
|
|
133
|
+
if (match) {
|
|
134
|
+
guards.push({
|
|
135
|
+
type: 'typeof',
|
|
136
|
+
expression: usage.context,
|
|
137
|
+
inferredTipo: match[1],
|
|
138
|
+
confidence: 95
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function detectInstanceofGuard(usage, context, guards) {
|
|
143
|
+
const match = context.match(/\w+\s+instanceof\s+(\w+)/);
|
|
144
|
+
if (match) {
|
|
145
|
+
guards.push({
|
|
146
|
+
type: 'instanceof',
|
|
147
|
+
expression: usage.context,
|
|
148
|
+
inferredTipo: match[1],
|
|
149
|
+
confidence: 95
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function detectInGuard(usage, context, guards) {
|
|
154
|
+
const match = context.match(/['"](\w+)['"]\s+in\s+\w+/);
|
|
155
|
+
if (match) {
|
|
156
|
+
guards.push({
|
|
157
|
+
type: 'in',
|
|
158
|
+
expression: usage.context,
|
|
159
|
+
inferredTipo: `{ ${match[1]}: unknown }`,
|
|
160
|
+
confidence: 80
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
134
164
|
function detectTypeGuards(usages) {
|
|
135
165
|
const guards = [];
|
|
136
166
|
for (const usage of usages) {
|
|
137
167
|
const context = usage.context.toLowerCase();
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if (match) {
|
|
142
|
-
guards.push({
|
|
143
|
-
type: 'typeof',
|
|
144
|
-
expression: usage.context,
|
|
145
|
-
inferredTipo: match[1],
|
|
146
|
-
confidence: 95
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
// instanceof guards
|
|
151
|
-
if (context.includes('instanceof')) {
|
|
152
|
-
const match = context.match(/\w+\s+instanceof\s+(\w+)/);
|
|
153
|
-
if (match) {
|
|
154
|
-
guards.push({
|
|
155
|
-
type: 'instanceof',
|
|
156
|
-
expression: usage.context,
|
|
157
|
-
inferredTipo: match[1],
|
|
158
|
-
confidence: 95
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
// 'in' operator guards
|
|
163
|
-
if (context.includes(' in ')) {
|
|
164
|
-
const match = context.match(/['"](\w+)['"]\s+in\s+\w+/);
|
|
165
|
-
if (match) {
|
|
166
|
-
guards.push({
|
|
167
|
-
type: 'in',
|
|
168
|
-
expression: usage.context,
|
|
169
|
-
inferredTipo: `{ ${match[1]}: unknown }`,
|
|
170
|
-
confidence: 80
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
}
|
|
168
|
+
detectTypeofGuard(usage, context, guards);
|
|
169
|
+
detectInstanceofGuard(usage, context, guards);
|
|
170
|
+
detectInGuard(usage, context, guards);
|
|
174
171
|
}
|
|
175
172
|
return guards;
|
|
176
173
|
}
|
|
@@ -214,7 +211,7 @@ function extractUsageFromNode(node, varNome) {
|
|
|
214
211
|
* Extrai informações de MemberExpression
|
|
215
212
|
*/
|
|
216
213
|
function extractMemberExpressionUsage(node, varNome) {
|
|
217
|
-
const property = node.property?.name ?? node.property.value;
|
|
214
|
+
const property = node.property?.name ?? String(node.property.value);
|
|
218
215
|
return {
|
|
219
216
|
name: varNome,
|
|
220
217
|
nodeType: 'MemberExpression',
|
|
@@ -222,7 +219,7 @@ function extractMemberExpressionUsage(node, varNome) {
|
|
|
222
219
|
column: node.loc?.start?.column ?? 0,
|
|
223
220
|
context: extractNodeContext(node),
|
|
224
221
|
operation: 'access',
|
|
225
|
-
property: property
|
|
222
|
+
property: property || undefined
|
|
226
223
|
};
|
|
227
224
|
}
|
|
228
225
|
/**
|
|
@@ -250,7 +247,7 @@ function extractNodeContext(node) {
|
|
|
250
247
|
}
|
|
251
248
|
if (node.type === 'MemberExpression') {
|
|
252
249
|
const obj = node.object?.name ?? extractNodeContext(node.object);
|
|
253
|
-
const prop = node.property?.name ?? node.property.value;
|
|
250
|
+
const prop = node.property?.name ?? String(node.property.value);
|
|
254
251
|
return `${obj}.${prop}`;
|
|
255
252
|
}
|
|
256
253
|
if (node.type === 'CallExpression') {
|