1099
return result;
1100
}
1102
>
1103
>
export class ExtensionRegistryReporter implements IProblemReporter {
1104
>
constructor(private _collector: ExtensionMessageCollector, private _validationStatus: ValidationStatus = new ValidationStatus()) {
1105
}
1107
>
public info(message: string): void {
1108
this._validationStatus.state = ValidationState.Info;
1109
this._collector.info(message);
1110
}
1112
>
public warn(message: string): void {
1113
this._validationStatus.state = ValidationState.Warning;
1114
this._collector.warn(message);
1115
}
1117
>
public error(message: string): void {
1118
this._validationStatus.state = ValidationState.Error;
1119
this._collector.error(message);
1120
}
1122
>
public fatal(message: string): void {
1123
this._validationStatus.state = ValidationState.Fatal;
1124
this._collector.error(message);
1125
}
1127
>
public get status(): ValidationStatus {
1128
return this._validationStatus;
1129
}
1131
>
1132
>
export namespace Schemas {
1133
>
1134
>
export const ProblemPattern: IJSONSchema = {
1135
>
default: {
1136
>
regexp: '^([^\\\\s].*)\\\\((\\\\d+,\\\\d+)\\\\):\\\\s*(.*)$',
1137
>
file: 1,
1138
>
location: 2,
1139
>
message: 3
1140
>
},
1141
>
type: 'object',
1142
>
additionalProperties: false,
1143
>
properties: {
1144
>
regexp: {
1145
>
type: 'string',
1146
>
description: localize('ProblemPatternSchema.regexp', 'The regular expression to find an error, warning or info in the output.')
1147
>
},
1148
>
kind: {
1149
>
type: 'string',
1150
>
description: localize('ProblemPatternSchema.kind', 'whether the pattern matches a location (file and line) or only a file.')
1151
>
},
1152
>
file: {
1153
>
type: 'integer',
1154
>
description: localize('ProblemPatternSchema.file', 'The match group index of the filename. If omitted 1 is used.')
1155
>
},
1156
>
location: {
1157
>
type: 'integer',
1158
>
description: localize('ProblemPatternSchema.location', 'The match group index of the problem\'s location. Valid location patterns are: (line), (line,column) and (startLine,startColumn,endLine,endColumn). If omitted (line,column) is assumed.')
1159
>
},
1160
>
line: {
1161
>
type: 'integer',
1162
>
description: localize('ProblemPatternSchema.line', 'The match group index of the problem\'s line. Defaults to 2')
1163
>
},
1164
>
column: {
1165
>
type: 'integer',
1166
>
description: localize('ProblemPatternSchema.column', 'The match group index of the problem\'s line character. Defaults to 3')
1167
>
},
1168
>
endLine: {
1169
>
type: 'integer',
1170
>
description: localize('ProblemPatternSchema.endLine', 'The match group index of the problem\'s end line. Defaults to undefined')
1171
>
},
1172
>
endColumn: {
1173
>
type: 'integer',
1174
>
description: localize('ProblemPatternSchema.endColumn', 'The match group index of the problem\'s end line character. Defaults to undefined')
1175
>
},
1176
>
severity: {
1177
>
type: 'integer',
1178
>
description: localize('ProblemPatternSchema.severity', 'The match group index of the problem\'s severity. Defaults to undefined')
1179
>
},
1180
>
code: {
1181
>
type: 'integer',
1182
>
description: localize('ProblemPatternSchema.code', 'The match group index of the problem\'s code. Defaults to undefined')
1183
>
},
1184
>
message: {
1185
>
type: 'integer',
1186
>
description: localize('ProblemPatternSchema.message', 'The match group index of the message. If omitted it defaults to 4 if location is specified. Otherwise it defaults to 5.')
1187
>
},
1188
>
loop: {
1189
>
type: 'boolean',
1190
>
description: localize('ProblemPatternSchema.loop', 'In a multi line matcher loop indicated whether this pattern is executed in a loop as long as it matches. Can only specified on a last pattern in a multi line pattern.')
1191
>
}
1192
>
}
1193
>
};
1194
>
1195
>
export const NamedProblemPattern: IJSONSchema = Objects.deepClone(ProblemPattern);
1196
>
NamedProblemPattern.properties = Objects.deepClone(NamedProblemPattern.properties) || {};
1197
>
NamedProblemPattern.properties['name'] = {
1198
>
type: 'string',
1199
>
description: localize('NamedProblemPatternSchema.name', 'The name of the problem pattern.')
1200
>
};
1201
>
1202
>
export const MultiLineProblemPattern: IJSONSchema = {
1203
>
type: 'array',
1204
>
items: ProblemPattern
1205
>
};
1206
>
1207
>
export const NamedMultiLineProblemPattern: IJSONSchema = {
1208
>
type: 'object',
1209
>
additionalProperties: false,
1210
>
properties: {
1211
>
name: {
1212
>
type: 'string',
1213
>
description: localize('NamedMultiLineProblemPatternSchema.name', 'The name of the problem multi line problem pattern.')
1214
>
},
1215
>
patterns: {
1216
>
type: 'array',
1217
>
description: localize('NamedMultiLineProblemPatternSchema.patterns', 'The actual patterns.'),
1218
>
items: ProblemPattern
1219
>
}
1220
>
}
1221
>
};
1222
>
1223
>
export const WatchingPattern: IJSONSchema = {
1224
>
type: 'object',
1225
>
additionalProperties: false,
1226
>
properties: {
1227
>
regexp: {
1228
>
type: 'string',
1229
>
description: localize('WatchingPatternSchema.regexp', 'The regular expression to detect the begin or end of a background task.')
1230
>
},
1231
>
file: {
1232
>
type: 'integer',
1233
>
description: localize('WatchingPatternSchema.file', 'The match group index of the filename. Can be omitted.')
1234
>
},
1235
>
}
1236
>
};
1237
>
1238
>
export const PatternType: IJSONSchema = {
1239
>
anyOf: [
1240
>
{
1241
>
type: 'string',
1242
>
description: localize('PatternTypeSchema.name', 'The name of a contributed or predefined pattern')
1243
>
},
1244
>
Schemas.ProblemPattern,
1245
>
Schemas.MultiLineProblemPattern
1246
>
],
1247
>
description: localize('PatternTypeSchema.description', 'A problem pattern or the name of a contributed or predefined problem pattern. Can be omitted if base is specified.')
1248
>
};
1249
>
1250
>
export const ProblemMatcher: IJSONSchema = {
1251
>
type: 'object',
1252
>
additionalProperties: false,
1253
>
properties: {
1254
>
base: {
1255
>
type: 'string',
1256
>
description: localize('ProblemMatcherSchema.base', 'The name of a base problem matcher to use.')
1257
>
},
1258
>
owner: {
1259
>
type: 'string',
1260
>
description: localize('ProblemMatcherSchema.owner', 'The owner of the problem inside Code. Can be omitted if base is specified. Defaults to \'external\' if omitted and base is not specified.')
1261
>
},
1262
>
source: {
1263
>
type: 'string',
1264
>
description: localize('ProblemMatcherSchema.source', 'A human-readable string describing the source of this diagnostic, e.g. \'typescript\' or \'super lint\'.')
1265
>
},
1266
>
severity: {
1267
>
type: 'string',
1268
>
enum: ['error', 'warning', 'info'],
1269
>
description: localize('ProblemMatcherSchema.severity', 'The default severity for captures problems. Is used if the pattern doesn\'t define a match group for severity.')
1270
>
},
1271
>
applyTo: {
1272
>
type: 'string',
1273
>
enum: ['allDocuments', 'openDocuments', 'closedDocuments'],
1274
>
description: localize('ProblemMatcherSchema.applyTo', 'Controls if a problem reported on a text document is applied only to open, closed or all documents.')
1275
>
},
1276
>
pattern: PatternType,
1277
>
fileLocation: {
1278
>
oneOf: [
1279
>
{
1280
>
type: 'string',
1281
>
enum: ['absolute', 'relative', 'autoDetect', 'search']
1282
>
},
1283
>
{
1284
>
type: 'array',
1285
>
prefixItems: [
1286
>
{
1287
>
type: 'string',
1288
>
enum: ['absolute', 'relative', 'autoDetect', 'search']
1289
>
},
1290
>
],
1291
>
minItems: 1,
1292
>
maxItems: 1,
1293
>
additionalItems: false
1294
>
},
1295
>
{
1296
>
type: 'array',
1297
>
prefixItems: [
1298
>
{ type: 'string', enum: ['relative', 'autoDetect'] },
1299
>
{ type: 'string' },
1300
>
],
1301
>
minItems: 2,
1302
>
maxItems: 2,
1303
>
additionalItems: false,
1304
>
examples: [
1305
>
['relative', '${workspaceFolder}'],
1306
>
['autoDetect', '${workspaceFolder}'],
1307
>
]
1308
>
},
1309
>
{
1310
>
type: 'array',
1311
>
prefixItems: [
1312
>
{ type: 'string', enum: ['search'] },
1313
>
{
1314
>
type: 'object',
1315
>
properties: {
1316
>
'include': {
1317
>
oneOf: [
1318
>
{ type: 'string' },
1319
>
{ type: 'array', items: { type: 'string' } }
1320
>
]
1321
>
},
1322
>
'exclude': {
1323
>
oneOf: [
1324
>
{ type: 'string' },
1325
>
{ type: 'array', items: { type: 'string' } }
1326
>
]
1327
>
},
1328
>
},
1329
>
required: ['include']
1330
>
}
1331
>
],
1332
>
minItems: 2,
1333
>
maxItems: 2,
1334
>
additionalItems: false,
1335
>
examples: [
1336
>
['search', { 'include': ['${workspaceFolder}'] }],
1337
>
['search', { 'include': ['${workspaceFolder}'], 'exclude': [] }]
1338
>
],
1339
>
}
1340
>
],
1341
>
description: localize('ProblemMatcherSchema.fileLocation', 'Defines how file names reported in a problem pattern should be interpreted. A relative fileLocation may be an array, where the second element of the array is the path of the relative file location. The search fileLocation mode, performs a deep (and, possibly, heavy) file system search within the directories specified by the include/exclude properties of the second element (or the current workspace directory if not specified).')
1342
>
},
1343
>
background: {
1344
>
type: 'object',
1345
>
additionalProperties: false,
1346
>
description: localize('ProblemMatcherSchema.background', 'Patterns to track the begin and end of a matcher active on a background task.'),
1347
>
properties: {
1348
>
activeOnStart: {
1349
>
type: 'boolean',
1350
>
description: localize('ProblemMatcherSchema.background.activeOnStart', 'If set to true the background monitor starts in active mode. This is the same as outputting a line that matches beginsPattern when the task starts.')
1351
>
},
1352
>
beginsPattern: {
1353
>
oneOf: [
1354
>
{
1355
>
type: 'string'
1356
>
},
1357
>
Schemas.WatchingPattern
1358
>
],
1359
>
description: localize('ProblemMatcherSchema.background.beginsPattern', 'If matched in the output the start of a background task is signaled.')
1360
>
},
1361
>
endsPattern: {
1362
>
oneOf: [
1363
>
{
1364
>
type: 'string'
1365
>
},
1366
>
Schemas.WatchingPattern
1367
>
],
1368
>
description: localize('ProblemMatcherSchema.background.endsPattern', 'If matched in the output the end of a background task is signaled.')
1369
>
}
1370
>
}
1371
>
},
1372
>
watching: {
1373
>
type: 'object',
1374
>
additionalProperties: false,
1375
>
deprecationMessage: localize('ProblemMatcherSchema.watching.deprecated', 'The watching property is deprecated. Use background instead.'),
1376
>
description: localize('ProblemMatcherSchema.watching', 'Patterns to track the begin and end of a watching matcher.'),
1377
>
properties: {
1378
>
activeOnStart: {
1379
>
type: 'boolean',
1380
>
description: localize('ProblemMatcherSchema.watching.activeOnStart', 'If set to true the watcher starts in active mode. This is the same as outputting a line that matches beginsPattern when the task starts.')
1381
>
},
1382
>
beginsPattern: {
1383
>
oneOf: [
1384
>
{
1385
>
type: 'string'
1386
>
},
1387
>
Schemas.WatchingPattern
1388
>
],
1389
>
description: localize('ProblemMatcherSchema.watching.beginsPattern', 'If matched in the output the start of a watching task is signaled.')
1390
>
},
1391
>
endsPattern: {
1392
>
oneOf: [
1393
>
{
1394
>
type: 'string'
1395
>
},
1396
>
Schemas.WatchingPattern
1397
>
],
1398
>
description: localize('ProblemMatcherSchema.watching.endsPattern', 'If matched in the output the end of a watching task is signaled.')
1399
>
}
1400
>
}
1401
>
}
1402
>
}
1403
>
};
1404
>
1405
>
export const LegacyProblemMatcher: IJSONSchema = Objects.deepClone(ProblemMatcher);
1406
>
LegacyProblemMatcher.properties = Objects.deepClone(LegacyProblemMatcher.properties) || {};
1407
>
LegacyProblemMatcher.properties['watchedTaskBeginsRegExp'] = {
1408
>
type: 'string',
1409
>
deprecationMessage: localize('LegacyProblemMatcherSchema.watchedBegin.deprecated', 'This property is deprecated. Use the watching property instead.'),
1410
>
description: localize('LegacyProblemMatcherSchema.watchedBegin', 'A regular expression signaling that a watched tasks begins executing triggered through file watching.')
1411
>
};
1412
>
LegacyProblemMatcher.properties['watchedTaskEndsRegExp'] = {
1413
>
type: 'string',
1414
>
deprecationMessage: localize('LegacyProblemMatcherSchema.watchedEnd.deprecated', 'This property is deprecated. Use the watching property instead.'),
1415
>
description: localize('LegacyProblemMatcherSchema.watchedEnd', 'A regular expression signaling that a watched tasks ends executing.')
1416
>
};
1417
>
1418
>
export const NamedProblemMatcher: IJSONSchema = Objects.deepClone(ProblemMatcher);
1419
>
NamedProblemMatcher.properties = Objects.deepClone(NamedProblemMatcher.properties) || {};
1420
>
NamedProblemMatcher.properties.name = {
1421
>
type: 'string',
1422
>
description: localize('NamedProblemMatcherSchema.name', 'The name of the problem matcher used to refer to it.')
1423
>
};
1424
>
NamedProblemMatcher.properties.label = {
1425
>
type: 'string',
1426
>
description: localize('NamedProblemMatcherSchema.label', 'A human readable label of the problem matcher.')
1427
>
};
1428
>
}
1429
>
1430
>
const problemPatternExtPoint = ExtensionsRegistry.registerExtensionPoint<Config.NamedProblemPatterns>({
1431
>
extensionPoint: 'problemPatterns',
1432
>
jsonSchema: {
1433
>
description: localize('ProblemPatternExtPoint', 'Contributes problem patterns'),
1434
>
type: 'array',
1435
>
items: {
1436
>
anyOf: [
1437
>
Schemas.NamedProblemPattern,
1438
>
Schemas.NamedMultiLineProblemPattern
1439
>
]
1440
>
}
1441
>
}
1442
>
});
1443
>
1444
>
export interface IProblemPatternRegistry {
1445
>
onReady(): Promise<void>;
1446
>
1447
>
get(key: string): IProblemPattern | MultiLineProblemPattern;
1448
>
}
1449
>
1450
>
class ProblemPatternRegistryImpl implements IProblemPatternRegistry {
1451
>
1452
>
private patterns: IStringDictionary<Types.SingleOrMany<IProblemPattern>>;
1453
>
private readyPromise: Promise<void>;
1454
>
1455
>
constructor() {
1456
>
this.patterns = Object.create(null);
1457
>
this.fillDefaults();
1458
>
this.readyPromise = new Promise<void>((resolve, reject) => {
1459
>
problemPatternExtPoint.setHandler((extensions, delta) => {
1460
// We get all statically know extension during startup in one batch
1461
try {