mirror of https://github.com/gorhill/uBlock.git
Simplify linter error counting by using line events
This commit is contained in:
parent
9b5ed5ca86
commit
09265ef57c
|
@ -79,9 +79,6 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
|
||||||
const raw = astParser.getNodeString(currentWalkerNode);
|
const raw = astParser.getNodeString(currentWalkerNode);
|
||||||
const not = raw.startsWith('!');
|
const not = raw.startsWith('!');
|
||||||
const token = not ? raw.slice(1) : raw;
|
const token = not ? raw.slice(1) : raw;
|
||||||
if ( preparseDirectiveTokens.has(token) === false ) {
|
|
||||||
return 'error strong';
|
|
||||||
}
|
|
||||||
return not === preparseDirectiveTokens.get(token)
|
return not === preparseDirectiveTokens.get(token)
|
||||||
? 'negative strong'
|
? 'negative strong'
|
||||||
: 'positive strong';
|
: 'positive strong';
|
||||||
|
@ -671,38 +668,9 @@ CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => {
|
||||||
nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'),
|
nativeCssHas: vAPI.webextFlavor.env.includes('native_css_has'),
|
||||||
});
|
});
|
||||||
|
|
||||||
let errorCount = 0;
|
|
||||||
let markedsetStart = 0;
|
|
||||||
let markedsetTimer;
|
|
||||||
|
|
||||||
const processMarkedsetAsync = doc => {
|
|
||||||
if ( markedsetTimer !== undefined ) { return; }
|
|
||||||
markedsetTimer = self.requestIdleCallback(deadline => {
|
|
||||||
markedsetTimer = undefined;
|
|
||||||
processMarkedset(doc, deadline);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const processMarkedset = (doc, deadline) => {
|
|
||||||
const lineCount = doc.lineCount();
|
|
||||||
doc.eachLine(markedsetStart, lineCount, lineHandle => {
|
|
||||||
const line = markedsetStart++;
|
|
||||||
const markers = lineHandle.gutterMarkers || null;
|
|
||||||
if ( markers && markers['CodeMirror-lintgutter'] ) {
|
|
||||||
errorCount += 1;
|
|
||||||
}
|
|
||||||
if ( (line & 0x0F) === 0 && deadline.timeRemaining() === 0 ) {
|
|
||||||
processMarkedsetAsync(doc);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ( markedsetStart === lineCount ) {
|
|
||||||
CodeMirror.signal(doc.getEditor(), 'linterDone', { errorCount });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const changeset = [];
|
const changeset = [];
|
||||||
let changesetTimer;
|
let changesetTimer;
|
||||||
|
let errorCount = 0;
|
||||||
|
|
||||||
const addChange = (doc, change) => {
|
const addChange = (doc, change) => {
|
||||||
changeset.push(change);
|
changeset.push(change);
|
||||||
|
@ -711,10 +679,6 @@ CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => {
|
||||||
|
|
||||||
const processChangesetAsync = doc => {
|
const processChangesetAsync = doc => {
|
||||||
if ( changesetTimer !== undefined ) { return; }
|
if ( changesetTimer !== undefined ) { return; }
|
||||||
if ( markedsetTimer ) {
|
|
||||||
self.cancelIdleCallback(markedsetTimer);
|
|
||||||
markedsetTimer = undefined;
|
|
||||||
}
|
|
||||||
changesetTimer = self.requestIdleCallback(deadline => {
|
changesetTimer = self.requestIdleCallback(deadline => {
|
||||||
changesetTimer = undefined;
|
changesetTimer = undefined;
|
||||||
processChangeset(doc, deadline);
|
processChangeset(doc, deadline);
|
||||||
|
@ -722,28 +686,27 @@ CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const extractError = ( ) => {
|
const extractError = ( ) => {
|
||||||
if ( astParser.isComment() ) { return; }
|
|
||||||
if ( astParser.isFilter() === false ) { return; }
|
|
||||||
if ( astParser.hasError() === false ) { return; }
|
if ( astParser.hasError() === false ) { return; }
|
||||||
let error = 'Invalid filter';
|
const error = 'Invalid filter';
|
||||||
|
switch ( astParser.astError ) {
|
||||||
|
case sfp.AST_ERROR_REGEX:
|
||||||
|
return `${error}: Bad regular expression`;
|
||||||
|
case sfp.AST_ERROR_PATTERN:
|
||||||
|
return `${error}: Bad pattern`;
|
||||||
|
case sfp.AST_ERROR_DOMAIN_NAME:
|
||||||
|
return `${error}: Bad domain name`;
|
||||||
|
case sfp.AST_ERROR_OPTION_DUPLICATE:
|
||||||
|
return `${error}: Duplicate filter option`;
|
||||||
|
case sfp.AST_ERROR_OPTION_UNKNOWN:
|
||||||
|
return `${error}: Unsupported filter option`;
|
||||||
|
case sfp.AST_ERROR_IF_TOKEN_UNKNOWN:
|
||||||
|
return `${error}: Unknown preparsing token`;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
if ( astParser.isCosmeticFilter() && astParser.result.error ) {
|
if ( astParser.isCosmeticFilter() && astParser.result.error ) {
|
||||||
return `${error}: ${astParser.result.error}`;
|
return `${error}: ${astParser.result.error}`;
|
||||||
}
|
}
|
||||||
if ( astParser.astError === sfp.AST_ERROR_REGEX ) {
|
|
||||||
return `${error}: Bad regular expression`;
|
|
||||||
}
|
|
||||||
if ( astParser.astError === sfp.AST_ERROR_PATTERN ) {
|
|
||||||
return `${error}: Bad pattern`;
|
|
||||||
}
|
|
||||||
if ( astParser.astError === sfp.AST_ERROR_DOMAIN_NAME ) {
|
|
||||||
return `${error}: Bad domain name`;
|
|
||||||
}
|
|
||||||
if ( astParser.astError === sfp.AST_ERROR_OPTION_DUPLICATE ) {
|
|
||||||
return `${error}: Duplicate filter option`;
|
|
||||||
}
|
|
||||||
if ( astParser.astError === sfp.AST_ERROR_OPTION_UNKNOWN ) {
|
|
||||||
return `${error}: Unsupported filter option`;
|
|
||||||
}
|
|
||||||
return error;
|
return error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -764,12 +727,23 @@ CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => {
|
||||||
|
|
||||||
const makeMarker = (doc, lineHandle, marker, error) => {
|
const makeMarker = (doc, lineHandle, marker, error) => {
|
||||||
if ( marker === undefined ) {
|
if ( marker === undefined ) {
|
||||||
marker = markerTemplate.cloneNode(true);
|
marker = addMarker(doc, lineHandle);
|
||||||
doc.setGutterMarker(lineHandle, 'CodeMirror-lintgutter', marker);
|
|
||||||
}
|
}
|
||||||
marker.children[0].textContent = error;
|
marker.children[0].textContent = error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const addMarker = (doc, lineHandle) => {
|
||||||
|
const marker = markerTemplate.cloneNode(true);
|
||||||
|
doc.setGutterMarker(lineHandle, 'CodeMirror-lintgutter', marker);
|
||||||
|
lineHandle.on('delete', deleteMarker);
|
||||||
|
errorCount += 1;
|
||||||
|
return marker;
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteMarker = ( ) => {
|
||||||
|
errorCount -= 1;
|
||||||
|
};
|
||||||
|
|
||||||
const processChange = (doc, deadline, change) => {
|
const processChange = (doc, deadline, change) => {
|
||||||
let { from, to } = change;
|
let { from, to } = change;
|
||||||
doc.eachLine(from, to, lineHandle => {
|
doc.eachLine(from, to, lineHandle => {
|
||||||
|
@ -804,9 +778,7 @@ CodeMirror.registerHelper('fold', 'ubo-static-filtering', (( ) => {
|
||||||
if ( changeset.length !== 0 ) {
|
if ( changeset.length !== 0 ) {
|
||||||
return processChangesetAsync(doc);
|
return processChangesetAsync(doc);
|
||||||
}
|
}
|
||||||
errorCount = 0;
|
CodeMirror.signal(doc.getEditor(), 'linterDone', { errorCount });
|
||||||
markedsetStart = 0;
|
|
||||||
processMarkedsetAsync(doc);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CodeMirror.defineInitHook(cm => {
|
CodeMirror.defineInitHook(cm => {
|
||||||
|
|
|
@ -76,6 +76,7 @@ export const AST_TYPE_EXTENDED_COSMETIC = iota++;
|
||||||
export const AST_TYPE_EXTENDED_SCRIPTLET = iota++;
|
export const AST_TYPE_EXTENDED_SCRIPTLET = iota++;
|
||||||
export const AST_TYPE_EXTENDED_HTML = iota++;
|
export const AST_TYPE_EXTENDED_HTML = iota++;
|
||||||
export const AST_TYPE_EXTENDED_RESPONSEHEADER = iota++;
|
export const AST_TYPE_EXTENDED_RESPONSEHEADER = iota++;
|
||||||
|
export const AST_TYPE_COMMENT_PREPARSER = iota++;
|
||||||
|
|
||||||
iota = 0;
|
iota = 0;
|
||||||
export const AST_FLAG_UNSUPPORTED = 1 << iota++;
|
export const AST_FLAG_UNSUPPORTED = 1 << iota++;
|
||||||
|
@ -97,6 +98,7 @@ export const AST_ERROR_PATTERN = 1 << iota++;
|
||||||
export const AST_ERROR_DOMAIN_NAME = 1 << iota++;
|
export const AST_ERROR_DOMAIN_NAME = 1 << iota++;
|
||||||
export const AST_ERROR_OPTION_DUPLICATE = 1 << iota++;
|
export const AST_ERROR_OPTION_DUPLICATE = 1 << iota++;
|
||||||
export const AST_ERROR_OPTION_UNKNOWN = 1 << iota++;
|
export const AST_ERROR_OPTION_UNKNOWN = 1 << iota++;
|
||||||
|
export const AST_ERROR_IF_TOKEN_UNKNOWN = 1 << iota++;
|
||||||
|
|
||||||
iota = 0;
|
iota = 0;
|
||||||
const NODE_RIGHT_INDEX = iota++;
|
const NODE_RIGHT_INDEX = iota++;
|
||||||
|
@ -553,6 +555,34 @@ export const removableHTTPHeaders = new Set([
|
||||||
'set-cookie',
|
'set-cookie',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
export const preparserIfTokens = new Set([
|
||||||
|
'ext_ublock',
|
||||||
|
'ext_ubol',
|
||||||
|
'ext_devbuild',
|
||||||
|
'env_chromium',
|
||||||
|
'env_edge',
|
||||||
|
'env_firefox',
|
||||||
|
'env_legacy',
|
||||||
|
'env_mobile',
|
||||||
|
'env_mv3',
|
||||||
|
'env_safari',
|
||||||
|
'cap_html_filtering',
|
||||||
|
'cap_user_stylesheet',
|
||||||
|
'false',
|
||||||
|
'ext_abp',
|
||||||
|
'adguard',
|
||||||
|
'adguard_app_android',
|
||||||
|
'adguard_app_ios',
|
||||||
|
'adguard_app_mac',
|
||||||
|
'adguard_app_windows',
|
||||||
|
'adguard_ext_android_cb',
|
||||||
|
'adguard_ext_chromium',
|
||||||
|
'adguard_ext_edge',
|
||||||
|
'adguard_ext_firefox',
|
||||||
|
'adguard_ext_opera',
|
||||||
|
'adguard_ext_safari',
|
||||||
|
]);
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
const exCharCodeAt = (s, i) => {
|
const exCharCodeAt = (s, i) => {
|
||||||
|
@ -1049,6 +1079,7 @@ export class AstFilterParser {
|
||||||
parseComment(parent) {
|
parseComment(parent) {
|
||||||
const parentStr = this.getNodeString(parent);
|
const parentStr = this.getNodeString(parent);
|
||||||
if ( this.rePreparseDirectiveAny.test(parentStr) ) {
|
if ( this.rePreparseDirectiveAny.test(parentStr) ) {
|
||||||
|
this.astTypeFlavor = AST_TYPE_COMMENT_PREPARSER;
|
||||||
return this.parsePreparseDirective(parent, parentStr);
|
return this.parsePreparseDirective(parent, parentStr);
|
||||||
}
|
}
|
||||||
if ( this.reURL.test(parentStr) === false ) { return 0; }
|
if ( this.reURL.test(parentStr) === false ) { return 0; }
|
||||||
|
@ -1078,14 +1109,22 @@ export class AstFilterParser {
|
||||||
directiveEnd
|
directiveEnd
|
||||||
);
|
);
|
||||||
if ( directiveEnd !== parentEnd ) {
|
if ( directiveEnd !== parentEnd ) {
|
||||||
const next = this.allocTypedNode(
|
const type = s.startsWith('!#if ')
|
||||||
s .startsWith('!#if ')
|
? NODE_TYPE_PREPARSE_DIRECTIVE_IF_VALUE
|
||||||
? NODE_TYPE_PREPARSE_DIRECTIVE_IF_VALUE
|
: NODE_TYPE_PREPARSE_DIRECTIVE_VALUE;
|
||||||
: NODE_TYPE_PREPARSE_DIRECTIVE_VALUE,
|
const next = this.allocTypedNode(type, directiveEnd, parentEnd);
|
||||||
directiveEnd,
|
|
||||||
parentEnd
|
|
||||||
);
|
|
||||||
this.linkRight(head, next);
|
this.linkRight(head, next);
|
||||||
|
if ( type === NODE_TYPE_PREPARSE_DIRECTIVE_IF_VALUE ) {
|
||||||
|
const rawToken = this.getNodeString(next).trim();
|
||||||
|
const token = rawToken.charCodeAt(0) === 0x21 /* ! */
|
||||||
|
? rawToken.slice(1)
|
||||||
|
: rawToken;
|
||||||
|
if ( preparserIfTokens.has(token) === false ) {
|
||||||
|
this.addNodeFlags(next, NODE_FLAG_ERROR);
|
||||||
|
this.addFlags(AST_FLAG_HAS_ERROR);
|
||||||
|
this.astError = AST_ERROR_IF_TOKEN_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue