eslint-plugin-reliability 4.1.8 → 4.1.9
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-reliability",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.9",
|
|
4
4
|
"description": "ESLint plugin for runtime reliability — enforces error handling, network timeouts, null checks, and safe type narrowing.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
package/src/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.configs=exports.plugin=exports.rules=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");exports.rules={get"no-unhandled-promise"(){return require("./rules/error-handling/no-unhandled-promise").noUnhandledPromise},get"no-silent-errors"(){return require("./rules/error-handling/no-silent-errors").noSilentErrors},get"no-missing-error-context"(){return require("./rules/error-handling/no-missing-error-context").noMissingErrorContext},get"error-message"(){return require("./rules/error-handling/error-message").errorMessage},get"no-missing-null-checks"(){return require("./rules/reliability/no-missing-null-checks").noMissingNullChecks},get"no-unsafe-type-narrowing"(){return require("./rules/reliability/no-unsafe-type-narrowing").noUnsafeTypeNarrowing},get"require-network-timeout"(){return require("./rules/reliability/require-network-timeout").requireNetworkTimeout},get"no-await-in-loop"(){return require("./rules/reliability/no-await-in-loop").noAwaitInLoop},get"no-jsdoc-terminator-in-example"(){return require("./rules/reliability/no-jsdoc-terminator-in-example").noJsdocTerminatorInExample},get"error-handling/no-unhandled-promise"(){return require("./rules/error-handling/no-unhandled-promise").noUnhandledPromise},get"error-handling/no-silent-errors"(){return require("./rules/error-handling/no-silent-errors").noSilentErrors},get"error-handling/no-missing-error-context"(){return require("./rules/error-handling/no-missing-error-context").noMissingErrorContext},get"error-handling/error-message"(){return require("./rules/error-handling/error-message").errorMessage},get"reliability/no-missing-null-checks"(){return require("./rules/reliability/no-missing-null-checks").noMissingNullChecks},get"reliability/no-unsafe-type-narrowing"(){return require("./rules/reliability/no-unsafe-type-narrowing").noUnsafeTypeNarrowing},get"reliability/require-network-timeout"(){return require("./rules/reliability/require-network-timeout").requireNetworkTimeout},get"reliability/no-await-in-loop"(){return require("./rules/reliability/no-await-in-loop").noAwaitInLoop},get"reliability/no-jsdoc-terminator-in-example"(){return require("./rules/reliability/no-jsdoc-terminator-in-example").noJsdocTerminatorInExample}};(0,eslint_devkit_1.withCanonicalDocsUrls)("plugin-reliability",exports.rules);exports.plugin={meta:{name:"eslint-plugin-reliability",version:"4.1.
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.configs=exports.plugin=exports.rules=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");exports.rules={get"no-unhandled-promise"(){return require("./rules/error-handling/no-unhandled-promise").noUnhandledPromise},get"no-silent-errors"(){return require("./rules/error-handling/no-silent-errors").noSilentErrors},get"no-missing-error-context"(){return require("./rules/error-handling/no-missing-error-context").noMissingErrorContext},get"error-message"(){return require("./rules/error-handling/error-message").errorMessage},get"no-missing-null-checks"(){return require("./rules/reliability/no-missing-null-checks").noMissingNullChecks},get"no-unsafe-type-narrowing"(){return require("./rules/reliability/no-unsafe-type-narrowing").noUnsafeTypeNarrowing},get"require-network-timeout"(){return require("./rules/reliability/require-network-timeout").requireNetworkTimeout},get"no-await-in-loop"(){return require("./rules/reliability/no-await-in-loop").noAwaitInLoop},get"no-jsdoc-terminator-in-example"(){return require("./rules/reliability/no-jsdoc-terminator-in-example").noJsdocTerminatorInExample},get"error-handling/no-unhandled-promise"(){return require("./rules/error-handling/no-unhandled-promise").noUnhandledPromise},get"error-handling/no-silent-errors"(){return require("./rules/error-handling/no-silent-errors").noSilentErrors},get"error-handling/no-missing-error-context"(){return require("./rules/error-handling/no-missing-error-context").noMissingErrorContext},get"error-handling/error-message"(){return require("./rules/error-handling/error-message").errorMessage},get"reliability/no-missing-null-checks"(){return require("./rules/reliability/no-missing-null-checks").noMissingNullChecks},get"reliability/no-unsafe-type-narrowing"(){return require("./rules/reliability/no-unsafe-type-narrowing").noUnsafeTypeNarrowing},get"reliability/require-network-timeout"(){return require("./rules/reliability/require-network-timeout").requireNetworkTimeout},get"reliability/no-await-in-loop"(){return require("./rules/reliability/no-await-in-loop").noAwaitInLoop},get"reliability/no-jsdoc-terminator-in-example"(){return require("./rules/reliability/no-jsdoc-terminator-in-example").noJsdocTerminatorInExample}};(0,eslint_devkit_1.withCanonicalDocsUrls)("plugin-reliability",exports.rules);exports.plugin={meta:{name:"eslint-plugin-reliability",version:"4.1.9"},rules:exports.rules};exports.configs={recommended:{plugins:{reliability:exports.plugin},rules:{"reliability/no-silent-errors":"error","reliability/no-missing-null-checks":"warn","reliability/require-network-timeout":"error"}}};exports.default=exports.plugin;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noSilentErrors=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");function isEmptyCatchBlock(catchClause){const body=catchClause.body;if(!body||body.type!=="BlockStatement"){return true}const statements=body.body;if(statements.length===0){return true}const nonEmptyStatements=statements.filter(stmt=>stmt.type!=="EmptyStatement");return nonEmptyStatements.length===0}function hasExplanatoryComment(catchClause,sourceCode){const comments=sourceCode.getAllComments();const catchStart=catchClause.loc?.start;if(!catchStart||!comments.length){return false}const explanatoryPatterns=[/intentional/i,/expected/i,/ignore/i,/silent/i,/noop/i,/no-op/i,/by design/i,/known issue/i,/legacy/i,/third.?party/i,/framework/i,/library/i,/not implemented/i,/todo/i,/fixme/i];for(const comment of comments){const distance=catchStart.line-comment.loc.end.line;if(distance<0||distance>2)continue;const commentText=comment.value.toLowerCase();if(explanatoryPatterns.some(pattern=>pattern.test(commentText))){return true}}return false}exports.noSilentErrors=(0,eslint_devkit_2.createRule)({name:"no-silent-errors",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-reliability/docs/rules/no-silent-errors.md",description:"Detects empty catch blocks"},hasSuggestions:true,messages:{silentError:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.WARNING,issueName:"Silent error",description:"Empty catch block detected - errors are silently ignored",severity:"MEDIUM",fix:"Add error logging or handling in catch block",documentationLink:"https://rules.sonarsource.com/javascript/RSPEC-1186/"}),addErrorLogging:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Add Error Logging",description:"Add error logging to catch block",severity:"LOW",fix:"catch (error) { console.error(error); }",documentationLink:"https://rules.sonarsource.com/javascript/RSPEC-1186/"}),addErrorHandling:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Add Error Handling",description:"Add error handling to catch block",severity:"LOW",fix:"catch (error) { handleError(error); }",documentationLink:"https://rules.sonarsource.com/javascript/RSPEC-1186/"}),rethrowError:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Rethrow Error",description:"Rethrow error if needed",severity:"LOW",fix:"catch (error) { throw new CustomError(error); }",documentationLink:"https://rules.sonarsource.com/javascript/RSPEC-1186/"})},schema:[{type:"object",properties:{allowWithComment:{type:"boolean",default:false,description:"Allow empty catch if comment explains why"},ignoreInTests:{type:"boolean",default:true,description:"Ignore in test files"}},additionalProperties:false}]},defaultOptions:[{allowWithComment:false,ignoreInTests:true}],create(context,[options={}]){const{allowWithComment=false,ignoreInTests=true}=options||{};const filename=context.filename;const isTestFile=ignoreInTests&&/\.(test|spec)\.(ts|tsx|js|jsx)$/.test(filename);if(isTestFile){return{}}const sourceCode=context.sourceCode;function checkCatchClause(node){if(!isEmptyCatchBlock(node)){return}if(allowWithComment&&hasExplanatoryComment(node,sourceCode)){return}context.report({node,messageId:"silentError",suggest:[{messageId:"addErrorLogging",fix:()=>null},{messageId:"addErrorHandling",fix:()=>null},{messageId:"rethrowError",fix:()=>null}]})}return{CatchClause:checkCatchClause}}});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noSilentErrors=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");function isEmptyCatchBlock(catchClause){const body=catchClause.body;if(!body||body.type!=="BlockStatement"){return true}const statements=body.body;if(statements.length===0){return true}const nonEmptyStatements=statements.filter(stmt=>stmt.type!=="EmptyStatement");return nonEmptyStatements.length===0}function hasExplanatoryComment(catchClause,sourceCode){const comments=sourceCode.getAllComments();const catchStart=catchClause.loc?.start;if(!catchStart||!comments.length){return false}const explanatoryPatterns=[/intentional/i,/expected/i,/ignore/i,/silent/i,/noop/i,/no-op/i,/by design/i,/known issue/i,/legacy/i,/third.?party/i,/framework/i,/library/i,/not implemented/i,/todo/i,/fixme/i];for(const comment of comments){const distance=catchStart.line-comment.loc.end.line;if(distance<0||distance>2)continue;const commentText=comment.value.toLowerCase();if(explanatoryPatterns.some(pattern=>pattern.test(commentText))){return true}}for(const comment of sourceCode.getCommentsInside(catchClause.body)){const commentText=comment.value.toLowerCase();if(explanatoryPatterns.some(pattern=>pattern.test(commentText))){return true}}return false}exports.noSilentErrors=(0,eslint_devkit_2.createRule)({name:"no-silent-errors",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-reliability/docs/rules/no-silent-errors.md",description:"Detects empty catch blocks"},hasSuggestions:true,messages:{silentError:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.WARNING,issueName:"Silent error",description:"Empty catch block detected - errors are silently ignored",severity:"MEDIUM",fix:"Add error logging or handling in catch block",documentationLink:"https://rules.sonarsource.com/javascript/RSPEC-1186/"}),addErrorLogging:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Add Error Logging",description:"Add error logging to catch block",severity:"LOW",fix:"catch (error) { console.error(error); }",documentationLink:"https://rules.sonarsource.com/javascript/RSPEC-1186/"}),addErrorHandling:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Add Error Handling",description:"Add error handling to catch block",severity:"LOW",fix:"catch (error) { handleError(error); }",documentationLink:"https://rules.sonarsource.com/javascript/RSPEC-1186/"}),rethrowError:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Rethrow Error",description:"Rethrow error if needed",severity:"LOW",fix:"catch (error) { throw new CustomError(error); }",documentationLink:"https://rules.sonarsource.com/javascript/RSPEC-1186/"})},schema:[{type:"object",properties:{allowWithComment:{type:"boolean",default:false,description:"Allow empty catch if comment explains why"},ignoreInTests:{type:"boolean",default:true,description:"Ignore in test files"}},additionalProperties:false}]},defaultOptions:[{allowWithComment:false,ignoreInTests:true}],create(context,[options={}]){const{allowWithComment=false,ignoreInTests=true}=options||{};const filename=context.filename;const isTestFile=ignoreInTests&&/\.(test|spec)\.(ts|tsx|js|jsx)$/.test(filename);if(isTestFile){return{}}const sourceCode=context.sourceCode;function checkCatchClause(node){if(!isEmptyCatchBlock(node)){return}if(allowWithComment&&hasExplanatoryComment(node,sourceCode)){return}context.report({node,messageId:"silentError",suggest:[{messageId:"addErrorLogging",fix:()=>null},{messageId:"addErrorHandling",fix:()=>null},{messageId:"rethrowError",fix:()=>null}]})}return{CatchClause:checkCatchClause}}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noAwaitInLoop=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");exports.noAwaitInLoop=(0,eslint_devkit_1.createRule)({name:"no-await-in-loop",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-reliability/docs/rules/no-await-in-loop.md",description:"Disallow await inside loops and suggest appropriate concurrency patterns"},hasSuggestions:false,messages:{awaitInLoop:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.WARNING,issueName:"Sequential Async Loop",description:"Await in loop forces sequential execution",severity:"MEDIUM",fix:"Consider Promise.all() for concurrent execution or extract async logic",documentationLink:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function"}),suggestPromiseAll:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.INFO,issueName:"Use Promise.all",description:"Concurrent execution of independent operations",severity:"LOW",fix:"Promise.all(items.map(async (item) => await process(item)))",documentationLink:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all"}),suggestConcurrent:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.INFO,issueName:"Use Promise.allSettled",description:"Concurrent execution with error handling",severity:"LOW",fix:"Promise.allSettled(items.map(async (item) => await process(item)))",documentationLink:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled"}),considerSequential:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.INFO,issueName:"Sequential Control",description:"Operations require sequential execution",severity:"LOW",fix:"Add concurrency control or extract to async function",documentationLink:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function"}),asyncLoopPattern:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.INFO,issueName:"Async Loop Pattern",description:"Use controlled concurrency library",severity:"LOW",fix:"Consider p-map, p-series, or similar for controlled concurrency",documentationLink:"https://github.com/sindresorhus/p-map"})},schema:[{type:"object",properties:{allowForOf:{type:"boolean",default:false},allowWhile:{type:"boolean",default:false},checkConcurrency:{type:"boolean",default:true}},additionalProperties:false}]},defaultOptions:[{allowForOf:false,allowWhile:false,checkConcurrency:true}],create(context){const[options]=context.options;const{allowForOf=false,allowWhile=false}=options||{};function analyzeLoop(node,loopType){if(loopType==="ForOfStatement"&&allowForOf||loopType==="WhileStatement"&&allowWhile){return}const awaitExpressions=[];const skipProperties=new Set(["parent","tokens","comments","loc","range"]);function findAwaits(currentNode){if(currentNode.type==="AwaitExpression"){awaitExpressions.push(currentNode)}if(currentNode.type
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noAwaitInLoop=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");const LOOP_NODE_TYPES=new Set(["ForStatement","ForInStatement","ForOfStatement","WhileStatement","DoWhileStatement"]);function onceEvaluatedSlot(loop){if(loop.type==="ForOfStatement"||loop.type==="ForInStatement"){return"right"}if(loop.type==="ForStatement"){return"init"}return null}exports.noAwaitInLoop=(0,eslint_devkit_1.createRule)({name:"no-await-in-loop",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-reliability/docs/rules/no-await-in-loop.md",description:"Disallow await inside loops and suggest appropriate concurrency patterns"},hasSuggestions:false,messages:{awaitInLoop:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.WARNING,issueName:"Sequential Async Loop",description:"Await in loop forces sequential execution",severity:"MEDIUM",fix:"Consider Promise.all() for concurrent execution or extract async logic",documentationLink:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function"}),suggestPromiseAll:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.INFO,issueName:"Use Promise.all",description:"Concurrent execution of independent operations",severity:"LOW",fix:"Promise.all(items.map(async (item) => await process(item)))",documentationLink:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all"}),suggestConcurrent:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.INFO,issueName:"Use Promise.allSettled",description:"Concurrent execution with error handling",severity:"LOW",fix:"Promise.allSettled(items.map(async (item) => await process(item)))",documentationLink:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled"}),considerSequential:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.INFO,issueName:"Sequential Control",description:"Operations require sequential execution",severity:"LOW",fix:"Add concurrency control or extract to async function",documentationLink:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function"}),asyncLoopPattern:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.INFO,issueName:"Async Loop Pattern",description:"Use controlled concurrency library",severity:"LOW",fix:"Consider p-map, p-series, or similar for controlled concurrency",documentationLink:"https://github.com/sindresorhus/p-map"})},schema:[{type:"object",properties:{allowForOf:{type:"boolean",default:false},allowWhile:{type:"boolean",default:false},checkConcurrency:{type:"boolean",default:true}},additionalProperties:false}]},defaultOptions:[{allowForOf:false,allowWhile:false,checkConcurrency:true}],create(context){const[options]=context.options;const{allowForOf=false,allowWhile=false}=options||{};function analyzeLoop(node,loopType){if(loopType==="ForOfStatement"&&allowForOf||loopType==="WhileStatement"&&allowWhile){return}const awaitExpressions=[];const skipProperties=new Set(["parent","tokens","comments","loc","range"]);function findAwaits(currentNode,isLoopRoot=false){if(currentNode.type==="AwaitExpression"){awaitExpressions.push(currentNode)}if(currentNode.type==="FunctionDeclaration"||currentNode.type==="FunctionExpression"||currentNode.type==="ArrowFunctionExpression"){return}if(!isLoopRoot&&LOOP_NODE_TYPES.has(currentNode.type)){const slot=onceEvaluatedSlot(currentNode);const head=slot?currentNode[slot]:void 0;if(head&&typeof head==="object"&&"type"in head){findAwaits(head)}return}const skipSlot=isLoopRoot?onceEvaluatedSlot(currentNode):null;for(const key in currentNode){if(skipProperties.has(key))continue;if(skipSlot!==null&&key===skipSlot)continue;const child=currentNode[key];if(Array.isArray(child)){child.forEach(item=>{if(item&&typeof item==="object"&&"type"in item){findAwaits(item)}})}else if(child&&typeof child==="object"&&"type"in child){findAwaits(child)}}}findAwaits(node,true);if(awaitExpressions.length>0){const loopContext=analyzeLoopContext(node,loopType);for(const awaitExpr of awaitExpressions){context.report({node:awaitExpr,messageId:"awaitInLoop",data:{loopType:loopContext.loopType,operations:loopContext.operationCount,suggestion:getSuggestion(loopContext),performance:loopContext.estimatedPerformance}})}}}function analyzeLoopContext(node,loopType){const loopCtx={loopType,operationCount:1,hasDependencies:false,isSequential:true,hasSideEffects:false,estimatedPerformance:"unknown",operations:[],node};const skipProps=new Set(["parent","tokens","comments","loc","range"]);function analyzeOperations(currentNode){if(currentNode.type==="CallExpression"){if(currentNode.callee.type==="Identifier"){loopCtx.operations.push(currentNode.callee.name)}else if(currentNode.callee.type==="MemberExpression"&¤tNode.callee.property.type==="Identifier"){loopCtx.operations.push(currentNode.callee.property.name)}}if(currentNode.type==="AssignmentExpression"||currentNode.type==="UpdateExpression"){loopCtx.hasDependencies=true}if(currentNode.type==="CallExpression"&&(loopCtx.operations.includes("push")||loopCtx.operations.includes("splice")||loopCtx.operations.includes("delete"))){loopCtx.hasSideEffects=true}if(currentNode.type==="AwaitExpression"){loopCtx.operationCount++}for(const key in currentNode){if(skipProps.has(key))continue;const child=currentNode[key];if(Array.isArray(child)){child.forEach(item=>{if(item&&typeof item==="object"&&"type"in item){analyzeOperations(item)}})}else if(child&&typeof child==="object"&&"type"in child){analyzeOperations(child)}}}analyzeOperations(node);if(loopCtx.hasDependencies||loopCtx.hasSideEffects){loopCtx.isSequential=true;loopCtx.estimatedPerformance=`sequential (${loopCtx.operationCount} operations)`}else{loopCtx.isSequential=false;loopCtx.estimatedPerformance=`potential ${loopCtx.operationCount}x speedup with concurrency`}return loopCtx}function getSuggestion(loopCtx){if(loopCtx.isSequential){return"operations may need to be sequential - consider if concurrency is safe"}else{return"operations appear independent - consider Promise.all() for concurrency"}}return{ForStatement(node){analyzeLoop(node,"ForStatement")},ForInStatement(node){analyzeLoop(node,"ForInStatement")},ForOfStatement(node){analyzeLoop(node,"ForOfStatement")},WhileStatement(node){analyzeLoop(node,"WhileStatement")},DoWhileStatement(node){analyzeLoop(node,"DoWhileStatement")}}}});
|