You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Mar 25, 2021. It is now read-only.
This is not a bug, this is a suggestion that may give us some performance).
After encountering a bug in typescript and doing some digging around I realized that in most of the rules (if not all of them) we use a form of node.getStart(). This triggers the following calls:
Note that we never provide the source file so we are then calling ts.getTokenPosOfNode(this) which has this implementation:
functiongetTokenPosOfNode(node,sourceFile,includeJsDocComment){// With nodes that have no width (i.e. 'Missing' nodes), we actually *don't*// want to skip trivia because this will launch us forward to the next token.if(nodeIsMissing(node)){returnnode.pos;}if(isJSDocNode(node)){returnts.skipTrivia((sourceFile||getSourceFileOfNode(node)).text,node.pos,/*stopAfterLineBreak*/false,/*stopAtComments*/true);}if(includeJsDocComment&&node.jsDocComments&&node.jsDocComments.length>0){returngetTokenPosOfNode(node.jsDocComments[0]);}// For a syntax list, it is possible that one of its children has JSDocComment nodes, while// the syntax list itself considers them as normal trivia. Therefore if we simply skip// trivia for the list, we may have skipped the JSDocComment as well. So we should process its// first child to determine the actual position of its first token.if(node.kind===286/* SyntaxList */&&node._children.length>0){returngetTokenPosOfNode(node._children[0],sourceFile,includeJsDocComment);}returnts.skipTrivia((sourceFile||getSourceFileOfNode(node)).text,node.pos);}
The key here is the last return statement: (sourceFile || getSourceFileOfNode(node)).text, since we are not providing the sourceFile this means that we call this bad boy all the time:
Which means that if we have a node and we call node.getStart(), we do not get the start of the node for free, in fact, this will be very costly for nodes that are very deeply nested.
Please see the following comment in the issue I reported in typescript:
In all of those calls we avoid having to traverse the tree up to the root node because we are providing it. There are a few places where they do not provide the source file but it seems that most typescript developers are aware that they need to pass it.
Due to this, I ask that a wrapper be added to the RuleWalker and advise tslint rule developers to use it for performance:
exportclassRuleWalkerextendsSyntaxWalker{privatelimit: number;privateposition: number;privateoptions: any[];privatefailures: RuleFailure[];privatedisabledIntervals: IDisabledInterval[];privateruleName: string;constructor(privatesourceFile: ts.SourceFile,options: IOptions){super();this.position=0;this.failures=[];this.options=options.ruleArguments;this.limit=this.sourceFile.getFullWidth();this.disabledIntervals=options.disabledIntervals;this.ruleName=options.ruleName;}publicgetSourceFile(): ts.SourceFile{returnthis.sourceFile;}// new method which provides the source file so that typescript// can stop calling getSourceFileOfNodepublicgetStart(node: ts.Node){returnnode.getStart(this.sourceFile);}
This additional method would be welcome especially for rules that use getStart a lot.
In the same spirit perhaps we should consider doing something about other methods that take in the source file:
This is not a bug, this is a suggestion that may give us some performance).
After encountering a bug in typescript and doing some digging around I realized that in most of the rules (if not all of them) we use a form of
node.getStart()
. This triggers the following calls:Note that we never provide the source file so we are then calling
ts.getTokenPosOfNode(this)
which has this implementation:The key here is the last return statement:
(sourceFile || getSourceFileOfNode(node)).text
, since we are not providing the sourceFile this means that we call this bad boy all the time:Which means that if we have a node and we call
node.getStart()
, we do not get the start of the node for free, in fact, this will be very costly for nodes that are very deeply nested.Please see the following comment in the issue I reported in typescript:
microsoft/TypeScript#12053 (comment)
In particular, the problem about not storing the source file in the node:
If you look at the typescript source code and search for
.getStart(
you will find lines like thefollowing:
In all of those calls we avoid having to traverse the tree up to the root node because we are providing it. There are a few places where they do not provide the source file but it seems that most typescript developers are aware that they need to pass it.
Due to this, I ask that a wrapper be added to the
RuleWalker
and advise tslint rule developers to use it for performance:This additional method would be welcome especially for rules that use
getStart
a lot.In the same spirit perhaps we should consider doing something about other methods that take in the source file:
The text was updated successfully, but these errors were encountered: