diff --git a/build-tools/api_check_plugin/src/api_check_plugin.js b/build-tools/api_check_plugin/src/api_check_plugin.js index d2e3c5658433346f234bdf4009ed4bc9843c0f45..ae1768c23d211e6eafe8698d79288122dce89c41 100644 --- a/build-tools/api_check_plugin/src/api_check_plugin.js +++ b/build-tools/api_check_plugin/src/api_check_plugin.js @@ -87,6 +87,8 @@ function checkAllNode(node, sourcefile, fileName) { checkDeprecated(node, sourcefile, fileName); // check permission checkPermission(node, sourcefile, fileName); + // check event subscription + checkEventSubscription(node, sourcefile, fileName); if (commentNodeWhiteList.includes(node.kind)) { checkJSDoc(node, sourcefile, fileName); diff --git a/build-tools/api_check_plugin/src/check_eventSubscription.js b/build-tools/api_check_plugin/src/check_eventSubscription.js index e591d80c59557de2d71150d7fc04d2b6621934ae..da6206c218f34ca568972068bfa60caafa087dd4 100644 --- a/build-tools/api_check_plugin/src/check_eventSubscription.js +++ b/build-tools/api_check_plugin/src/check_eventSubscription.js @@ -18,17 +18,22 @@ const { addAPICheckErrorLogs } = require('./compile_info'); const { checkSmallHump } = require('./check_hump'); const ts = requireTypescriptModule(); -// check if two sets are equal -function areSetsEqual(set1, set2) { - if (set1.size !== set2.size) { - return false; +// check if on and off functions show in pair +function checkOnAndOffAppearInPair(node, sourcefile, fileName, onEventAllNames, onEventCheckNames, offEventAllNames, offEventCheckNames) { + for (const value of onEventCheckNames) { + if (!offEventAllNames.has(value)) { + const checkErrorResult = 'The on and off event subscription methods do not appear in pair.'; + addAPICheckErrorLogs(node, sourcefile, fileName, ErrorType.API_PAIR_ERRORS, checkErrorResult, LogType.LOG_API, + ErrorLevel.MIDDLE); + } } - for (const value of set1) { - if (!set2.has(value)) { - return false; + for (const value of offEventCheckNames) { + if (!onEventAllNames.has(value)) { + const checkErrorResult = 'The on and off event subscription methods do not appear in pair.'; + addAPICheckErrorLogs(node, sourcefile, fileName, ErrorType.API_PAIR_ERRORS, checkErrorResult, LogType.LOG_API, + ErrorLevel.MIDDLE); } } - return true; } // check the api version @@ -89,26 +94,35 @@ function checkOffFunctions(nodes, sourcefile, fileName) { } // handle event subscription node -function handleVariousEventSubscriptionAPI(childNode, childNodeName, sourcefile, fileName, onEventNames, offEventNames, offEventNodes) { +function handleVariousEventSubscriptionAPI(childNode, childNodeName, sourcefile, fileName, onEventAllNames, onEventCheckNames, + offEventAllNames, offEventCheckNames, offEventNodes) { // judge the event subscription api type if (childNodeName === 'on') { - checkTheFirstParameter(childNode, sourcefile, fileName, childNodeName); - // if the function is 'on' + let eventName = ''; + // store the event name if (childNode.parameters[0].type.kind === ts.SyntaxKind.LiteralType) { - onEventNames.add(childNode.parameters[0].type.literal.text); + eventName = childNode.parameters[0].type.literal.text; + onEventAllNames.add(eventName); } else if (childNode.parameters[0].type.kind === ts.SyntaxKind.StringKeyword) { - onEventNames.add("string"); + eventName = 'string'; + onEventAllNames.add(eventName); + } + // check the version + if (!checkVersionNeedCheck(childNode)) { + return; + } else if (eventName !== '') { + onEventCheckNames.add(eventName); } - } else if (childNodeName === 'off') { checkTheFirstParameter(childNode, sourcefile, fileName, childNodeName); + } else if (childNodeName === 'off') { let eventName = ''; - // the function is 'off' + // store the event name if (childNode.parameters[0].type.kind === ts.SyntaxKind.LiteralType) { eventName = childNode.parameters[0].type.literal.text; - offEventNames.add(eventName); + offEventAllNames.add(eventName); } else if (childNode.parameters[0].type.kind === ts.SyntaxKind.StringKeyword) { eventName = 'string'; - offEventNames.add("string"); + offEventAllNames.add(eventName); } // store the off function node based on their names if (!offEventNodes.get(eventName)) { @@ -118,7 +132,18 @@ function handleVariousEventSubscriptionAPI(childNode, childNodeName, sourcefile, curNodes.push(childNode); offEventNodes.set(eventName, curNodes); } + // check the version + if (!checkVersionNeedCheck(childNode)) { + return; + } else if (eventName !== '') { + offEventCheckNames.add(eventName); + } + checkTheFirstParameter(childNode, sourcefile, fileName, childNodeName); } else if (childNodeName === 'once' || childNodeName === 'emit') { + // check the version + if (!checkVersionNeedCheck(childNode)) { + return; + } checkTheFirstParameter(childNode, sourcefile, fileName, childNodeName); } } @@ -127,8 +152,10 @@ function checkEventSubscription(node, sourcefile, fileName) { // if the node is namespace or interface if ((ts.isInterfaceDeclaration(node)) || ts.isModuleBlock(node) || ts.isModuleDeclaration(node) || ts.isClassDeclaration(node) || node === sourcefile) { - const onEventNames = new Set(); - const offEventNames = new Set(); + const onEventAllNames = new Set(); + const onEventCheckNames = new Set(); + const offEventAllNames = new Set(); + const offEventCheckNames = new Set(); const offEventNodes = new Map(); let childNodes = node.members; if (ts.isModuleDeclaration(node)) { @@ -141,27 +168,20 @@ function checkEventSubscription(node, sourcefile, fileName) { // if the node is method or function if (ts.isFunctionDeclaration(childNode) || ts.isMethodDeclaration(childNode) || ts.isMethodSignature(childNode)) { // if the version needed to be check - if (!checkVersionNeedCheck(childNode)) { - return; - } let childNodeName = ''; if (childNode.name && ts.isIdentifier(childNode.name)) { childNodeName = childNode.name.getText(); } - handleVariousEventSubscriptionAPI(childNode, childNodeName, sourcefile, fileName, onEventNames, offEventNames, offEventNodes); + handleVariousEventSubscriptionAPI(childNode, childNodeName, sourcefile, fileName, onEventAllNames, onEventCheckNames, offEventAllNames, + offEventCheckNames, offEventNodes); } }); // check the callback parameter of off function is optional - for (let event of offEventNames) { + for (let event of offEventCheckNames) { checkOffFunctions(offEventNodes.get(event), sourcefile, fileName); } - // check if the on and off functions of one event shows in pair - if (!areSetsEqual(onEventNames, offEventNames)) { - const checkErrorResult = 'The on and off event subscription methods do not appear in pair.'; - addAPICheckErrorLogs(node, sourcefile, fileName, ErrorType.API_PAIR_ERRORS, checkErrorResult, LogType.LOG_API, - ErrorLevel.MIDDLE); - } + checkOnAndOffAppearInPair(node, sourcefile, fileName, onEventAllNames, onEventCheckNames, offEventAllNames, offEventCheckNames) } } exports.checkEventSubscription = checkEventSubscription; \ No newline at end of file