@djodjonx/wiredi 0.0.2
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/LICENSE +22 -0
- package/README.md +516 -0
- package/dist/index.cjs +931 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1139 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +1139 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +915 -0
- package/dist/index.mjs.map +1 -0
- package/dist/plugin/ConfigurationAnalyzer.d.ts +59 -0
- package/dist/plugin/ConfigurationAnalyzer.d.ts.map +1 -0
- package/dist/plugin/ConfigurationAnalyzer.js +321 -0
- package/dist/plugin/ConfigurationAnalyzer.js.map +1 -0
- package/dist/plugin/DependencyAnalyzer.d.ts +54 -0
- package/dist/plugin/DependencyAnalyzer.d.ts.map +1 -0
- package/dist/plugin/DependencyAnalyzer.js +208 -0
- package/dist/plugin/DependencyAnalyzer.js.map +1 -0
- package/dist/plugin/TokenNormalizer.d.ts +51 -0
- package/dist/plugin/TokenNormalizer.d.ts.map +1 -0
- package/dist/plugin/TokenNormalizer.js +208 -0
- package/dist/plugin/TokenNormalizer.js.map +1 -0
- package/dist/plugin/ValidationEngine.d.ts +53 -0
- package/dist/plugin/ValidationEngine.d.ts.map +1 -0
- package/dist/plugin/ValidationEngine.js +250 -0
- package/dist/plugin/ValidationEngine.js.map +1 -0
- package/dist/plugin/index.d.ts +2 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +144 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/package.json +6 -0
- package/dist/plugin/types.d.ts +152 -0
- package/dist/plugin/types.d.ts.map +1 -0
- package/dist/plugin/types.js +3 -0
- package/dist/plugin/types.js.map +1 -0
- package/package.json +95 -0
- package/plugin.js +1 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ValidationEngine = void 0;
|
|
4
|
+
const ConfigurationAnalyzer_1 = require("./ConfigurationAnalyzer");
|
|
5
|
+
const DependencyAnalyzer_1 = require("./DependencyAnalyzer");
|
|
6
|
+
/**
|
|
7
|
+
* Moteur de validation des dépendances DI
|
|
8
|
+
*
|
|
9
|
+
* Orchestre l'analyse des configurations et des classes pour
|
|
10
|
+
* détecter les dépendances manquantes.
|
|
11
|
+
*/
|
|
12
|
+
class ValidationEngine {
|
|
13
|
+
constructor(typescript, checker, logger) {
|
|
14
|
+
this.checker = checker;
|
|
15
|
+
this.logger = logger;
|
|
16
|
+
this.typescript = typescript;
|
|
17
|
+
this.configAnalyzer = new ConfigurationAnalyzer_1.ConfigurationAnalyzer(typescript, checker, logger);
|
|
18
|
+
this.dependencyAnalyzer = new DependencyAnalyzer_1.DependencyAnalyzer(typescript, checker, logger);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Valide un programme TypeScript et retourne les erreurs
|
|
22
|
+
*/
|
|
23
|
+
validate(program) {
|
|
24
|
+
const errors = [];
|
|
25
|
+
// Phase 1: Collecter toutes les configurations
|
|
26
|
+
const allConfigs = this.collectAllConfigs(program);
|
|
27
|
+
this.logger(`Trouvé ${allConfigs.size} configuration(s)`);
|
|
28
|
+
// Phase 2: Collecter toutes les classes analysées
|
|
29
|
+
const allClasses = this.collectAllClasses(program);
|
|
30
|
+
this.logger(`Trouvé ${allClasses.size} classe(s) avec dépendances`);
|
|
31
|
+
// Phase 3: Valider chaque configuration de type 'builder'
|
|
32
|
+
for (const [_symbol, config] of allConfigs) {
|
|
33
|
+
if (config.type !== 'builder')
|
|
34
|
+
continue;
|
|
35
|
+
const configErrors = this.validateConfig(config, allConfigs, allClasses);
|
|
36
|
+
errors.push(...configErrors);
|
|
37
|
+
}
|
|
38
|
+
return errors;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Collecte toutes les configurations du programme
|
|
42
|
+
*/
|
|
43
|
+
collectAllConfigs(program) {
|
|
44
|
+
const configs = new Map();
|
|
45
|
+
for (const sourceFile of program.getSourceFiles()) {
|
|
46
|
+
if (sourceFile.isDeclarationFile)
|
|
47
|
+
continue;
|
|
48
|
+
const fileConfigs = this.configAnalyzer.analyzeSourceFile(sourceFile);
|
|
49
|
+
for (const config of fileConfigs) {
|
|
50
|
+
if (config.symbol) {
|
|
51
|
+
configs.set(config.symbol, config);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return configs;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Collecte toutes les classes analysées du programme
|
|
59
|
+
*/
|
|
60
|
+
collectAllClasses(program) {
|
|
61
|
+
const classes = new Map();
|
|
62
|
+
for (const sourceFile of program.getSourceFiles()) {
|
|
63
|
+
if (sourceFile.isDeclarationFile)
|
|
64
|
+
continue;
|
|
65
|
+
const fileClasses = this.dependencyAnalyzer.analyzeSourceFile(sourceFile);
|
|
66
|
+
for (const cls of fileClasses) {
|
|
67
|
+
classes.set(cls.symbol, cls);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return classes;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Valide une configuration spécifique
|
|
74
|
+
*/
|
|
75
|
+
validateConfig(config, allConfigs, allClasses) {
|
|
76
|
+
const errors = [];
|
|
77
|
+
const visitedSet = new Set();
|
|
78
|
+
// Résoudre tous les tokens fournis (avec héritage)
|
|
79
|
+
const providedTokens = this.configAnalyzer.resolveAllProvidedTokens(config, allConfigs, visitedSet);
|
|
80
|
+
this.logger(`Config "${config.builderId}": ${providedTokens.size} token(s) fournis`);
|
|
81
|
+
// Collecter toutes les classes à valider (providers)
|
|
82
|
+
const classesToValidate = this.collectClassesToValidate(config, allConfigs, new Set());
|
|
83
|
+
// Valider chaque classe
|
|
84
|
+
for (const [classSymbol, provider] of classesToValidate) {
|
|
85
|
+
const analyzedClass = allClasses.get(classSymbol);
|
|
86
|
+
if (!analyzedClass) {
|
|
87
|
+
// La classe n'a peut-être pas de dépendances ou n'a pas été analysée
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const classErrors = this.validateClassDependencies(analyzedClass, providedTokens, provider, config);
|
|
91
|
+
errors.push(...classErrors);
|
|
92
|
+
}
|
|
93
|
+
return errors;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Collecte toutes les classes qui doivent être validées pour une configuration
|
|
97
|
+
*/
|
|
98
|
+
collectClassesToValidate(config, allConfigs, visitedSet) {
|
|
99
|
+
const classes = new Map();
|
|
100
|
+
// Ajouter les providers locaux
|
|
101
|
+
for (const provider of config.localProviders) {
|
|
102
|
+
if (provider.providerClass) {
|
|
103
|
+
classes.set(provider.providerClass, provider);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Ajouter les providers des configs parentes
|
|
107
|
+
for (const parentSymbol of config.parentConfigs) {
|
|
108
|
+
const parentConfig = allConfigs.get(parentSymbol);
|
|
109
|
+
if (parentConfig) {
|
|
110
|
+
const parentClasses = this.collectClassesToValidate(parentConfig, allConfigs, visitedSet);
|
|
111
|
+
for (const [classSymbol, provider] of parentClasses) {
|
|
112
|
+
if (!classes.has(classSymbol)) {
|
|
113
|
+
classes.set(classSymbol, provider);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return classes;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Valide les dépendances d'une classe contre les tokens fournis
|
|
122
|
+
*/
|
|
123
|
+
validateClassDependencies(analyzedClass, providedTokens, provider, config) {
|
|
124
|
+
const errors = [];
|
|
125
|
+
for (const dependency of analyzedClass.dependencies) {
|
|
126
|
+
const registeredProvider = providedTokens.get(dependency.token.id);
|
|
127
|
+
if (!registeredProvider) {
|
|
128
|
+
// Token non enregistré
|
|
129
|
+
errors.push(this.createMissingDependencyError(analyzedClass, dependency, provider, config));
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
// Vérifier la compatibilité de type
|
|
133
|
+
const typeError = this.checkTypeCompatibility(dependency, registeredProvider, analyzedClass, config);
|
|
134
|
+
if (typeError) {
|
|
135
|
+
errors.push(typeError);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return errors;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Vérifie la compatibilité de type entre le provider enregistré et le type attendu
|
|
143
|
+
*/
|
|
144
|
+
checkTypeCompatibility(dependency, registeredProvider, analyzedClass, config) {
|
|
145
|
+
// Skip si pas de type attendu ou pas de type provider
|
|
146
|
+
if (!dependency.expectedType || !registeredProvider.providerType) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
// Skip pour les factories et values (type dynamique)
|
|
150
|
+
if (registeredProvider.registrationType === 'factory' ||
|
|
151
|
+
registeredProvider.registrationType === 'value') {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
const expectedType = dependency.expectedType;
|
|
155
|
+
const providerType = registeredProvider.providerType;
|
|
156
|
+
// Vérifier si le type du provider est assignable au type attendu
|
|
157
|
+
// On utilise isTypeAssignableTo pour vérifier la compatibilité structurelle
|
|
158
|
+
const isCompatible = this.checker.isTypeAssignableTo(providerType, expectedType);
|
|
159
|
+
if (!isCompatible) {
|
|
160
|
+
const expectedTypeName = this.checker.typeToString(expectedType);
|
|
161
|
+
const providerTypeName = this.checker.typeToString(providerType);
|
|
162
|
+
const className = analyzedClass.name;
|
|
163
|
+
const tokenName = dependency.token.displayName;
|
|
164
|
+
const paramIndex = dependency.parameterIndex;
|
|
165
|
+
const _builderId = config.builderId || config.variableName || 'unknown';
|
|
166
|
+
// L'erreur est reportée sur le provider là où il est ENREGISTRÉ
|
|
167
|
+
// (peut être dans un partial différent du builder)
|
|
168
|
+
const errorNode = registeredProvider.node;
|
|
169
|
+
const errorSourceFile = errorNode.getSourceFile(); // Fichier où le provider est défini
|
|
170
|
+
return {
|
|
171
|
+
message: `[WireDI] Type mismatch: Provider doesn't match expected type\n\n` +
|
|
172
|
+
`Service '${className}' expects type '${expectedTypeName}' for '${tokenName}' (parameter #${paramIndex}),\n` +
|
|
173
|
+
`but the registered provider '${registeredProvider.providerClassName || 'unknown'}' ` +
|
|
174
|
+
`returns '${providerTypeName}'.\n\n` +
|
|
175
|
+
`💡 Fix: Register a provider that implements '${expectedTypeName}' or use a factory to adapt the type.`,
|
|
176
|
+
file: errorSourceFile,
|
|
177
|
+
start: errorNode.getStart(errorSourceFile),
|
|
178
|
+
length: errorNode.getWidth(errorSourceFile),
|
|
179
|
+
relatedInformation: [
|
|
180
|
+
{
|
|
181
|
+
file: dependency.parameterNode.getSourceFile(),
|
|
182
|
+
start: dependency.parameterNode.getStart(),
|
|
183
|
+
length: dependency.parameterNode.getWidth(),
|
|
184
|
+
message: `The type '${expectedTypeName}' is expected here`,
|
|
185
|
+
},
|
|
186
|
+
],
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Crée une erreur de dépendance manquante
|
|
193
|
+
*/
|
|
194
|
+
createMissingDependencyError(analyzedClass, dependency, provider, config) {
|
|
195
|
+
const className = analyzedClass.name;
|
|
196
|
+
const tokenName = dependency.token.displayName;
|
|
197
|
+
const builderId = config.builderId || config.variableName || 'unknown';
|
|
198
|
+
const paramIndex = dependency.parameterIndex;
|
|
199
|
+
// L'erreur est reportée sur le provider dans la configuration
|
|
200
|
+
const errorNode = provider.node;
|
|
201
|
+
const errorSourceFile = config.sourceFile;
|
|
202
|
+
return {
|
|
203
|
+
message: `[WireDI] Missing dependency: '${className}' requires '${tokenName}' but it's not registered\n\n` +
|
|
204
|
+
`The service '${className}' expects '${tokenName}' as parameter #${paramIndex}, ` +
|
|
205
|
+
`but this token is not provided in the '${builderId}' configuration or its partials.\n\n` +
|
|
206
|
+
`💡 Fix: Add '{ token: ${tokenName} }' to your injections array.`,
|
|
207
|
+
file: errorSourceFile,
|
|
208
|
+
start: errorNode.getStart(errorSourceFile),
|
|
209
|
+
length: errorNode.getWidth(errorSourceFile),
|
|
210
|
+
relatedInformation: [
|
|
211
|
+
{
|
|
212
|
+
file: dependency.parameterNode.getSourceFile(),
|
|
213
|
+
start: dependency.parameterNode.getStart(),
|
|
214
|
+
length: dependency.parameterNode.getWidth(),
|
|
215
|
+
message: `The dependency '${tokenName}' is required here`,
|
|
216
|
+
},
|
|
217
|
+
],
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Convertit les erreurs de validation en diagnostics TypeScript
|
|
222
|
+
*/
|
|
223
|
+
convertToDiagnostics(errors) {
|
|
224
|
+
const ts = this.typescript;
|
|
225
|
+
return errors.map(error => {
|
|
226
|
+
const diagnostic = {
|
|
227
|
+
file: error.file,
|
|
228
|
+
start: error.start,
|
|
229
|
+
length: error.length,
|
|
230
|
+
messageText: error.message,
|
|
231
|
+
category: ts.DiagnosticCategory.Error,
|
|
232
|
+
code: 90001, // Code arbitraire unique au plugin
|
|
233
|
+
source: 'di-validator',
|
|
234
|
+
};
|
|
235
|
+
if (error.relatedInformation && error.relatedInformation.length > 0) {
|
|
236
|
+
diagnostic.relatedInformation = error.relatedInformation.map(info => ({
|
|
237
|
+
file: info.file,
|
|
238
|
+
start: info.start,
|
|
239
|
+
length: info.length,
|
|
240
|
+
messageText: info.message,
|
|
241
|
+
category: ts.DiagnosticCategory.Message,
|
|
242
|
+
code: 90001,
|
|
243
|
+
}));
|
|
244
|
+
}
|
|
245
|
+
return diagnostic;
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
exports.ValidationEngine = ValidationEngine;
|
|
250
|
+
//# sourceMappingURL=ValidationEngine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ValidationEngine.js","sourceRoot":"","sources":["../../src/LanguageServer/plugin/ValidationEngine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/LanguageServer/plugin/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const ValidationEngine_1 = require("./ValidationEngine");
|
|
4
|
+
/**
|
|
5
|
+
* Obtient la version d'un fichier source pour le cache
|
|
6
|
+
*/
|
|
7
|
+
function getFileVersion(sourceFile) {
|
|
8
|
+
// Utiliser la version si disponible, sinon la longueur du texte
|
|
9
|
+
return sourceFile.version || sourceFile.getText().length.toString();
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Fichiers externes que le plugin veut ajouter au projet
|
|
13
|
+
*/
|
|
14
|
+
function getExternalFilesImpl() {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Appelé quand les fichiers du projet changent
|
|
19
|
+
*/
|
|
20
|
+
function onConfigurationChangedImpl(_config) {
|
|
21
|
+
// Possibilité de mettre à jour la config à chaud
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* TypeScript Language Service Plugin pour la validation DI
|
|
25
|
+
*
|
|
26
|
+
* Ce plugin s'intègre au service de langage TypeScript pour fournir
|
|
27
|
+
* des diagnostics en temps réel sur les erreurs d'injection de dépendances.
|
|
28
|
+
*
|
|
29
|
+
* Architecture: Pattern Décorateur sur ts.LanguageService
|
|
30
|
+
*
|
|
31
|
+
* @see https://github.com/microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin
|
|
32
|
+
*/
|
|
33
|
+
function init(modules) {
|
|
34
|
+
const typescript = modules.typescript;
|
|
35
|
+
function create(info) {
|
|
36
|
+
const config = info.config || {};
|
|
37
|
+
// Logger TOUJOURS - pour le diagnostic
|
|
38
|
+
const forceLog = (msg) => {
|
|
39
|
+
info.project.projectService.logger.info(`[DI-Validator] ${msg}`);
|
|
40
|
+
};
|
|
41
|
+
forceLog('===== Plugin initialisé =====');
|
|
42
|
+
forceLog(`Config: ${JSON.stringify(config)}`);
|
|
43
|
+
forceLog(`Project root: ${info.project.getCurrentDirectory()}`);
|
|
44
|
+
// Logger via le TSServer (verbose pour les détails)
|
|
45
|
+
const logger = (msg) => {
|
|
46
|
+
if (config.verbose) {
|
|
47
|
+
info.project.projectService.logger.info(`[DI-Validator] ${msg}`);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
// Cache par fichier pour les performances
|
|
51
|
+
const fileCache = new Map();
|
|
52
|
+
// Créer le proxy du Language Service (Pattern Décorateur)
|
|
53
|
+
const proxy = Object.create(null);
|
|
54
|
+
const originalLS = info.languageService;
|
|
55
|
+
// Délégation par défaut de toutes les méthodes
|
|
56
|
+
for (const key of Object.keys(originalLS)) {
|
|
57
|
+
const method = originalLS[key];
|
|
58
|
+
if (typeof method === 'function') {
|
|
59
|
+
;
|
|
60
|
+
proxy[key] = (...args) => method.apply(originalLS, args);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// ============================================================
|
|
64
|
+
// INTERCEPTION: getSemanticDiagnostics
|
|
65
|
+
// ============================================================
|
|
66
|
+
proxy.getSemanticDiagnostics = (fileName) => {
|
|
67
|
+
// Obtenir les diagnostics originaux de TypeScript
|
|
68
|
+
const originalDiagnostics = originalLS.getSemanticDiagnostics(fileName);
|
|
69
|
+
const program = originalLS.getProgram();
|
|
70
|
+
if (!program) {
|
|
71
|
+
logger('Pas de program disponible');
|
|
72
|
+
return originalDiagnostics;
|
|
73
|
+
}
|
|
74
|
+
const sourceFile = program.getSourceFile(fileName);
|
|
75
|
+
if (!sourceFile) {
|
|
76
|
+
return originalDiagnostics;
|
|
77
|
+
}
|
|
78
|
+
// Ne pas analyser les fichiers de déclaration
|
|
79
|
+
if (sourceFile.isDeclarationFile) {
|
|
80
|
+
return originalDiagnostics;
|
|
81
|
+
}
|
|
82
|
+
// Ne pas analyser les fichiers node_modules
|
|
83
|
+
if (fileName.includes('node_modules')) {
|
|
84
|
+
return originalDiagnostics;
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
// Vérifier le cache
|
|
88
|
+
const version = getFileVersion(sourceFile);
|
|
89
|
+
const cached = fileCache.get(fileName);
|
|
90
|
+
if (cached && cached.version === version) {
|
|
91
|
+
// Utiliser le cache si la version n'a pas changé
|
|
92
|
+
// Note: On ne cache pas les diagnostics car ils dépendent du contexte global
|
|
93
|
+
}
|
|
94
|
+
// Effectuer la validation DI
|
|
95
|
+
const diDiagnostics = validateDI(program, sourceFile, logger);
|
|
96
|
+
// Fusion des diagnostics
|
|
97
|
+
return [...originalDiagnostics, ...diDiagnostics];
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
logger(`Erreur lors de la validation: ${error}`);
|
|
101
|
+
return originalDiagnostics;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
// ============================================================
|
|
105
|
+
// INTERCEPTION OPTIONNELLE: getQuickInfoAtPosition
|
|
106
|
+
// Affiche les infos DI au survol (future feature)
|
|
107
|
+
// ============================================================
|
|
108
|
+
// proxy.getQuickInfoAtPosition = (fileName: string, position: number) => {
|
|
109
|
+
// const original = originalLS.getQuickInfoAtPosition(fileName, position)
|
|
110
|
+
// // Ajouter des infos sur les dépendances...
|
|
111
|
+
// return original
|
|
112
|
+
// }
|
|
113
|
+
/**
|
|
114
|
+
* Valide les dépendances DI et retourne les diagnostics
|
|
115
|
+
*/
|
|
116
|
+
function validateDI(program, currentFile, log) {
|
|
117
|
+
const checker = program.getTypeChecker();
|
|
118
|
+
const engine = new ValidationEngine_1.ValidationEngine(typescript, checker, log);
|
|
119
|
+
// Log des fichiers sources disponibles dans le program
|
|
120
|
+
const sourceFiles = program.getSourceFiles();
|
|
121
|
+
const projectFiles = sourceFiles.filter(sf => !sf.isDeclarationFile && !sf.fileName.includes('node_modules'));
|
|
122
|
+
info.project.projectService.logger.info(`[DI-Validator] Programme: ${projectFiles.length} fichier(s) source(s) projet`);
|
|
123
|
+
for (const sf of projectFiles.slice(0, 10)) {
|
|
124
|
+
info.project.projectService.logger.info(`[DI-Validator] - ${sf.fileName}`);
|
|
125
|
+
}
|
|
126
|
+
// Validation complète du programme
|
|
127
|
+
const errors = engine.validate(program);
|
|
128
|
+
info.project.projectService.logger.info(`[DI-Validator] Validation: ${errors.length} erreur(s) totale(s) trouvée(s)`);
|
|
129
|
+
// Filtrer les erreurs pour le fichier courant
|
|
130
|
+
const fileErrors = errors.filter(error => error.file.fileName === currentFile.fileName);
|
|
131
|
+
info.project.projectService.logger.info(`[DI-Validator] Fichier ${currentFile.fileName}: ${fileErrors.length} erreur(s)`);
|
|
132
|
+
return engine.convertToDiagnostics(fileErrors);
|
|
133
|
+
}
|
|
134
|
+
return proxy;
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
create,
|
|
138
|
+
getExternalFiles: getExternalFilesImpl,
|
|
139
|
+
onConfigurationChanged: onConfigurationChangedImpl,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
// Export CommonJS requis pour les plugins TypeScript
|
|
143
|
+
module.exports = init;
|
|
144
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/LanguageServer/plugin/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import type ts from 'typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Identifiant unique pour un token d'injection
|
|
4
|
+
* Format: "TYPE:path/to/file.ts:position" ou "STRING:literal" ou "CLASS:path:name"
|
|
5
|
+
*/
|
|
6
|
+
export type TokenId = string;
|
|
7
|
+
/**
|
|
8
|
+
* Types de tokens supportés
|
|
9
|
+
*/
|
|
10
|
+
export type TokenType = 'symbol' | 'class' | 'string' | 'unknown';
|
|
11
|
+
/**
|
|
12
|
+
* Représente un token d'injection normalisé
|
|
13
|
+
*/
|
|
14
|
+
export interface NormalizedToken {
|
|
15
|
+
/** Identifiant unique calculé pour comparaison */
|
|
16
|
+
id: TokenId;
|
|
17
|
+
/** Type du token */
|
|
18
|
+
type: TokenType;
|
|
19
|
+
/** Nom lisible pour les messages d'erreur */
|
|
20
|
+
displayName: string;
|
|
21
|
+
/** Noeud AST original */
|
|
22
|
+
node: ts.Node;
|
|
23
|
+
/** Fichier source */
|
|
24
|
+
sourceFile: ts.SourceFile;
|
|
25
|
+
/** Position dans le fichier */
|
|
26
|
+
position: number;
|
|
27
|
+
/** Symbole TypeScript du token (pour vérification de type) */
|
|
28
|
+
symbol?: ts.Symbol;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Représente un provider enregistré dans une configuration
|
|
32
|
+
*/
|
|
33
|
+
export interface RegisteredProvider {
|
|
34
|
+
/** Token sous lequel le provider est enregistré */
|
|
35
|
+
token: NormalizedToken;
|
|
36
|
+
/** Classe qui implémente le provider (si applicable) */
|
|
37
|
+
providerClass?: ts.Symbol;
|
|
38
|
+
/** Nom de la classe provider */
|
|
39
|
+
providerClassName?: string;
|
|
40
|
+
/** Type d'enregistrement */
|
|
41
|
+
registrationType: 'class' | 'symbol-provider' | 'value' | 'factory';
|
|
42
|
+
/** Noeud AST de l'enregistrement */
|
|
43
|
+
node: ts.Node;
|
|
44
|
+
/** Type TypeScript du provider (pour vérification de compatibilité) */
|
|
45
|
+
providerType?: ts.Type;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Représente une dépendance requise par un constructeur
|
|
49
|
+
*/
|
|
50
|
+
export interface RequiredDependency {
|
|
51
|
+
/** Token requis */
|
|
52
|
+
token: NormalizedToken;
|
|
53
|
+
/** Index du paramètre dans le constructeur */
|
|
54
|
+
parameterIndex: number;
|
|
55
|
+
/** Noeud du paramètre */
|
|
56
|
+
parameterNode: ts.ParameterDeclaration;
|
|
57
|
+
/** Méthode d'injection: décorateur @inject ou type implicite */
|
|
58
|
+
injectionMethod: 'decorator' | 'type';
|
|
59
|
+
/** Type attendu de la dépendance */
|
|
60
|
+
expectedType?: ts.Type;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Représente l'analyse d'une classe injectable
|
|
64
|
+
*/
|
|
65
|
+
export interface AnalyzedClass {
|
|
66
|
+
/** Symbole de la classe */
|
|
67
|
+
symbol: ts.Symbol;
|
|
68
|
+
/** Nom de la classe */
|
|
69
|
+
name: string;
|
|
70
|
+
/** Fichier source de la déclaration */
|
|
71
|
+
sourceFile: ts.SourceFile;
|
|
72
|
+
/** Noeud de déclaration */
|
|
73
|
+
declaration: ts.ClassDeclaration;
|
|
74
|
+
/** Dépendances du constructeur */
|
|
75
|
+
dependencies: RequiredDependency[];
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Représente une configuration analysée (Builder ou Partial)
|
|
79
|
+
*/
|
|
80
|
+
export interface AnalyzedConfig {
|
|
81
|
+
/** Type de configuration */
|
|
82
|
+
type: 'builder' | 'partial';
|
|
83
|
+
/** Identifiant du builder (si applicable) */
|
|
84
|
+
builderId?: string;
|
|
85
|
+
/** Nom de la variable (si assignée) */
|
|
86
|
+
variableName?: string;
|
|
87
|
+
/** Symbole de la variable de config */
|
|
88
|
+
symbol?: ts.Symbol;
|
|
89
|
+
/** Providers enregistrés directement dans cette config */
|
|
90
|
+
localProviders: RegisteredProvider[];
|
|
91
|
+
/** Tokens fournis (calculé avec héritage) */
|
|
92
|
+
providedTokens: Map<TokenId, RegisteredProvider>;
|
|
93
|
+
/** Références aux configs parentes (extends) */
|
|
94
|
+
parentConfigs: ts.Symbol[];
|
|
95
|
+
/** Noeud de l'appel defineBuilderConfig/definePartialConfig */
|
|
96
|
+
callNode: ts.CallExpression;
|
|
97
|
+
/** Fichier source */
|
|
98
|
+
sourceFile: ts.SourceFile;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Erreur de validation DI
|
|
102
|
+
*/
|
|
103
|
+
export interface DIValidationError {
|
|
104
|
+
/** Message d'erreur */
|
|
105
|
+
message: string;
|
|
106
|
+
/** Fichier où reporter l'erreur */
|
|
107
|
+
file: ts.SourceFile;
|
|
108
|
+
/** Position de début */
|
|
109
|
+
start: number;
|
|
110
|
+
/** Longueur du span */
|
|
111
|
+
length: number;
|
|
112
|
+
/** Informations connexes (ex: où la dépendance est requise) */
|
|
113
|
+
relatedInformation?: Array<{
|
|
114
|
+
file: ts.SourceFile;
|
|
115
|
+
start: number;
|
|
116
|
+
length: number;
|
|
117
|
+
message: string;
|
|
118
|
+
}>;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Configuration du plugin
|
|
122
|
+
*/
|
|
123
|
+
export interface DIPluginConfig {
|
|
124
|
+
/** Mode verbeux pour debug */
|
|
125
|
+
verbose?: boolean;
|
|
126
|
+
/** Nom des fonctions de config à détecter */
|
|
127
|
+
configFunctions?: {
|
|
128
|
+
builder: string;
|
|
129
|
+
partial: string;
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Cache pour un fichier source
|
|
134
|
+
*/
|
|
135
|
+
export interface FileCache {
|
|
136
|
+
/** Version du fichier (pour invalidation) */
|
|
137
|
+
version: string;
|
|
138
|
+
/** Classes analysées dans ce fichier */
|
|
139
|
+
analyzedClasses: Map<string, AnalyzedClass>;
|
|
140
|
+
/** Configs analysées dans ce fichier */
|
|
141
|
+
analyzedConfigs: AnalyzedConfig[];
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* État global du validateur
|
|
145
|
+
*/
|
|
146
|
+
export interface ValidatorState {
|
|
147
|
+
/** Cache par fichier */
|
|
148
|
+
fileCache: Map<string, FileCache>;
|
|
149
|
+
/** Set des configs visitées (détection de cycles) */
|
|
150
|
+
visitedConfigs: Set<ts.Symbol>;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/LanguageServer/plugin/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/LanguageServer/plugin/types.ts"],"names":[],"mappings":""}
|