LSP: fix DocumentFilter glob matcher

The following pattern were not interpreted by
QRegularExpression::wildcardToRegularExpression.
* - `**` to match any number of path segments, including none
* - `{}` to group sub patterns into an OR expression.

Task-number: QTCREATORBUG-25766
Change-Id: If7cafef4bf625690fc7dff8ac6461351fef79505
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2021-06-15 11:14:27 +02:00
parent d23cf2cced
commit 9289ec491b
2 changed files with 30 additions and 9 deletions

View File

@@ -326,19 +326,26 @@ bool Range::overlaps(const Range &range) const
return end() > range.start() && start() < range.end();
}
QString expressionForGlob(QString globPattern)
{
const QString anySubDir("qtc_anysubdir_id");
globPattern.replace("**/", anySubDir);
QString regexp = QRegularExpression::wildcardToRegularExpression(globPattern);
regexp.replace(anySubDir,"(.*[/\\\\])*");
regexp.replace("\\{", "(");
regexp.replace("\\}", ")");
regexp.replace(",", "|");
return regexp;
}
bool DocumentFilter::applies(const Utils::FilePath &fileName, const Utils::MimeType &mimeType) const
{
if (Utils::optional<QString> _scheme = scheme()) {
if (_scheme.value() == fileName.toString())
return true;
}
if (Utils::optional<QString> _pattern = pattern()) {
QRegularExpression::PatternOption option = QRegularExpression::NoPatternOption;
if (Utils::HostOsInfo::fileNameCaseSensitivity() == Qt::CaseInsensitive)
if (fileName.caseSensitivity() == Qt::CaseInsensitive)
option = QRegularExpression::CaseInsensitiveOption;
QRegularExpression regexp(QRegularExpression::wildcardToRegularExpression(_pattern.value()),
option);
if (regexp.match(fileName.toString()).hasMatch())
const QRegularExpression regexp(expressionForGlob(_pattern.value()), option);
if (regexp.isValid() && regexp.match(fileName.toString()).hasMatch())
return true;
}
if (Utils::optional<QString> _lang = language()) {

View File

@@ -377,7 +377,21 @@ public:
void setScheme(const QString &scheme) { insert(schemeKey, scheme); }
void clearScheme() { remove(schemeKey); }
// A glob pattern, like `*.{ts,js}`.
/**
* A glob pattern, like `*.{ts,js}`.
*
* Glob patterns can have the following syntax:
* - `*` to match one or more characters in a path segment
* - `?` to match on one character in a path segment
* - `**` to match any number of path segments, including none
* - `{}` to group sub patterns into an OR expression. (e.g. `**/*.{ts,js}`
* matches all TypeScript and JavaScript files)
* - `[]` to declare a range of characters to match in a path segment
* (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
* - `[!...]` to negate a range of characters to match in a path segment
* (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but
* not `example.0`)
*/
Utils::optional<QString> pattern() const { return optionalValue<QString>(patternKey); }
void setPattern(const QString &pattern) { insert(patternKey, pattern); }
void clearPattern() { remove(patternKey); }