-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix very slow regexp #87
Conversation
b5c3daa
to
95acb27
Compare
@formulahendry I did a very slight change to fix this 'infinite' running regex, (just the meaning is slightly different, but it's necessary to avoid the exponential backtracking that comes with some hints from: http://www.rexegg.com/regex-explosive-quantifiers.html Could you merge it? |
@formulahendry Can you check it please? |
Yet the PR has hundreds of lines changed with formatting stuff and merge problems. You might have more luck getting this merged if you changed a small amount of code... 😄 |
d72e74a
to
a6de765
Compare
right, done Can @formulahendry see this? also single or double quotes? there is a mix of them in the sources |
9dab3ae
to
7ca2272
Compare
I think I'll make a quick cron script that gently ping @formulahendry every week, to hopefully merge this |
@@ -78,13 +78,30 @@ | |||
}, | |||
"auto-close-tag.excludedTags": { | |||
"type": "array", | |||
"default": ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
npm i
has reformatted it
package.json
Outdated
"description": "Set the tag list that would not be auto closed.", | ||
"scope": "resource" | ||
}, | ||
"auto-close-tag.SublimeText3Mode": { | ||
"type": "boolean", | ||
"default": false, | ||
"default": true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'd not change the default setting if we could not make sure most of users want this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want this!
src/getCloseTag.ts
Outdated
@@ -0,0 +1,27 @@ | |||
export default function getCloseTag(text: string, excludedTags: string[]): string { | |||
const regex = /<(\/?[a-zA-Z][a-zA-Z0-9:\-_.]*)(?:\s+[^<>]?[^\s/<>=]*)*\s?>/g; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<abc key=value>
would not work correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah yes indeed it's broken, need to add many more tests, thanks for noticing
// original regex:
'lol <a href="/ok"></a><abc key="value"> </'.match(/<(\/?[a-zA-Z][a-zA-Z0-9:\-_.]*)(?:\s+[^<>]*?[^\s/<>=]+?)*?\s?>/g)
["<a href="/ok">", "</a>", "<abc key="value">"]
// with my change:
'lol <a href="/ok"></a><abc key="value"> </'.match(/<(\/?[a-zA-Z][a-zA-Z0-9:\-_.]*)(?:\s+[^<>]?[^\s/<>=]*)*\s?>/g)
["</a>"]
src/getCloseTag.ts
Outdated
@@ -0,0 +1,27 @@ | |||
export default function getCloseTag(text: string, excludedTags: string[]): string { | |||
const regex = /<(\/?[a-zA-Z][a-zA-Z0-9:\-_.]*)(?:\s+[^<>]*?[^\s/<>=]*)*\s?>/g; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'<abc =>
should not get close tag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The biggest concern is that: although this may improve the performance, but might break several kinds of scenario,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(?:\s+[^<>]*?[^\s/<>=]*)*
would make [^\s/<>=]*
useless
(?:\s+[^<>]*?[^\s/<>=]*)*
is similar to (?:\s+[^<>]*?)*
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the advices
<abc =>
is a tag with an empty attribute key and value? or something else?
currently I hit again the slowness issue in the last test case, I think I'll try a different approach than the big regex, and search backward with smaller regexes and a loop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
arrow function shouldn't trigger auto-close: #5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
search backward would be great idea! 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh you meant '<abc =>'
like in a string? (or a comment, ..). Honestly I don't think this extension can be perfect, with jsx expressions we'd need to parse them to be 100% correct, and it's not even possible when we are in an unfinished one. So we might need to accept false-positiives like <foo><bar x=1 y={'<lol'} ></
that gives lol
currently
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't mind if a few rare edge cases are broken, if that means the performance issues are fixed. Performance a big concern for this extension.
(I just wish we could add a timeout to regexps so they will fail if they take too long!)
(Or is it really a regexp problem? I wonder if a time check inside the while
might be able to break out of problematic loops.)
test/getCloseTag.test.ts
Outdated
@@ -0,0 +1,61 @@ | |||
import { readFileSync } from "fs"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to enable test code running, similar to https://github.com/formulahendry/vscode-auto-rename-tag/blob/3141e782cadbb121b8c0fbf13683a88374e6a1b1/package.json#L54
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also need to follow the test structure: https://github.com/formulahendry/vscode-auto-close-tag/blob/master/test/extension.test.ts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will try to add tests, (code-runner would need tests too, if I figure it, I'd update that project too)
Ok, so I made a new approach by searching tags backward, it's not 100% robust, we can try to imrpove it more, like the current one anyway (jsx expressions can be very tricky), but no more performance issues at least it's tested like the pointers you showed and run in CI |
This has helped me a bit, thank you, but also your code wasn't catering for excludedTags, and I think this does the job. `const TAG_RE = /<(/?[a-zA-Z][a-zA-Z0-9:_.-])(?![\s\S]</?[a-zA-Z])/; function getCloseTag(text: string, excludedTags: string[]): string { |
Sorry guys I can't maintain this PR anymore, please go ahead with a new PR |
@caub curious, are you using different tools or just not this extension anymore ? I've built in some of this functionality into our internal tools to avoid devs having to use this extension. |
I went back to sublime-text |
@caub we took this route a few times in the past, curious what languages you're working with? we're writing CFML and I've made some headway using your code, its not perfect but it works ok. |
@garethedwards-tass you can definitely make progress, try to make you own PR and the maintainer may merge it I'm only working on JS (node+react), so sublimetext support things decently |
No description provided.