-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
C++: Improved class name detection (#2348)
- Loading branch information
1 parent
b609333
commit e3fe904
Showing
5 changed files
with
286 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,59 @@ | ||
Prism.languages.cpp = Prism.languages.extend('c', { | ||
'class-name': { | ||
pattern: /(\b(?:class|enum|struct)\s+)(?!class|enum|struct)\w+/, | ||
lookbehind: true | ||
}, | ||
'keyword': /\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|constinit|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/, | ||
'number': { | ||
pattern: /(?:\b0b[01']+|\b0x(?:[\da-f']+\.?[\da-f']*|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+\.?[\d']*|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]*/i, | ||
greedy: true | ||
}, | ||
'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/, | ||
'boolean': /\b(?:true|false)\b/ | ||
}); | ||
(function (Prism) { | ||
|
||
Prism.languages.insertBefore('cpp', 'string', { | ||
'raw-string': { | ||
pattern: /R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/, | ||
alias: 'string', | ||
greedy: true | ||
} | ||
}); | ||
var keyword = /\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|constinit|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/; | ||
|
||
Prism.languages.cpp = Prism.languages.extend('c', { | ||
'class-name': [ | ||
{ | ||
pattern: RegExp(/(\b(?:class|enum|struct|typename)\s+)(?!<keyword>)\w+/.source | ||
.replace(/<keyword>/g, function () { return keyword.source; })), | ||
lookbehind: true | ||
}, | ||
// This is intended to capture the class name of method implementations like: | ||
// void foo::bar() const {} | ||
// However! The `foo` in the above example could also be a namespace, so we only capture the class name if | ||
// it starts with an uppercase letter. This approximation should give decent results. | ||
/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/, | ||
// This will capture the class name before destructors like: | ||
// Foo::~Foo() {} | ||
/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i, | ||
{ | ||
// This also intends to capture the class name of method implementations but here the class has template | ||
// parameters, so it can't be a namespace (until C++ adds generic namespaces). | ||
pattern: /\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/, | ||
inside: null // see below | ||
} | ||
], | ||
'keyword': keyword, | ||
'number': { | ||
pattern: /(?:\b0b[01']+|\b0x(?:[\da-f']+\.?[\da-f']*|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+\.?[\d']*|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]*/i, | ||
greedy: true | ||
}, | ||
'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/, | ||
'boolean': /\b(?:true|false)\b/ | ||
}); | ||
|
||
Prism.languages.insertBefore('cpp', 'string', { | ||
'raw-string': { | ||
pattern: /R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/, | ||
alias: 'string', | ||
greedy: true | ||
} | ||
}); | ||
|
||
Prism.languages.insertBefore('cpp', 'class-name', { | ||
// the base clause is an optional list of parent classes | ||
// https://en.cppreference.com/w/cpp/language/class | ||
'base-clause': { | ||
pattern: /(\b(?:class|struct)\s+\w+\s*:\s*)(?:[^;{}"'])+?(?=\s*[;{])/, | ||
lookbehind: true, | ||
greedy: true, | ||
inside: Prism.languages.extend('cpp', {}) | ||
} | ||
}); | ||
Prism.languages.insertBefore('inside', 'operator', { | ||
// All untokenized words that are not namespaces should be class names | ||
'class-name': /\b[a-z_]\w*\b(?!\s*::)/i | ||
}, Prism.languages.cpp['base-clause']); | ||
|
||
}(Prism)); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
struct Base {}; | ||
struct Derived : Base {}; | ||
struct Derived : private Base; | ||
class X : public virtual B {}; | ||
class Y : virtual public B {}; | ||
class Y : virtual baz::B {}; | ||
class Z : public B<foo::T>; | ||
struct AA : X, Y, foo::bar::Z {}; | ||
|
||
class service : private Transport // comment | ||
{}; | ||
|
||
---------------------------------------------------- | ||
|
||
[ | ||
["keyword", "struct"], | ||
["class-name", "Base"], | ||
["punctuation", "{"], | ||
["punctuation", "}"], | ||
["punctuation", ";"], | ||
["keyword", "struct"], | ||
["class-name", "Derived"], | ||
["operator", ":"], | ||
["base-clause", [ | ||
["class-name", "Base"] | ||
]], | ||
["punctuation", "{"], | ||
["punctuation", "}"], | ||
["punctuation", ";"], | ||
["keyword", "struct"], | ||
["class-name", "Derived"], | ||
["operator", ":"], | ||
["base-clause", [ | ||
["keyword", "private"], | ||
["class-name", "Base"] | ||
]], | ||
["punctuation", ";"], | ||
["keyword", "class"], | ||
["class-name", "X"], | ||
["operator", ":"], | ||
["base-clause", [ | ||
["keyword", "public"], | ||
["keyword", "virtual"], | ||
["class-name", "B"] | ||
]], | ||
["punctuation", "{"], | ||
["punctuation", "}"], | ||
["punctuation", ";"], | ||
["keyword", "class"], | ||
["class-name", "Y"], | ||
["operator", ":"], | ||
["base-clause", [ | ||
["keyword", "virtual"], | ||
["keyword", "public"], | ||
["class-name", "B"] | ||
]], | ||
["punctuation", "{"], | ||
["punctuation", "}"], | ||
["punctuation", ";"], | ||
["keyword", "class"], | ||
["class-name", "Y"], | ||
["operator", ":"], | ||
["base-clause", [ | ||
["keyword", "virtual"], | ||
" baz", | ||
["operator", "::"], | ||
["class-name", "B"] | ||
]], | ||
["punctuation", "{"], | ||
["punctuation", "}"], | ||
["punctuation", ";"], | ||
["keyword", "class"], | ||
["class-name", "Z"], | ||
["operator", ":"], | ||
["base-clause", [ | ||
["keyword", "public"], | ||
["class-name", "B"], | ||
["operator", "<"], | ||
"foo", | ||
["operator", "::"], | ||
["class-name", "T"], | ||
["operator", ">"] | ||
]], | ||
["punctuation", ";"], | ||
["keyword", "struct"], | ||
["class-name", "AA"], | ||
["operator", ":"], | ||
["base-clause", [ | ||
["class-name", "X"], | ||
["punctuation", ","], | ||
["class-name", "Y"], | ||
["punctuation", ","], | ||
" foo", | ||
["operator", "::"], | ||
"bar", | ||
["operator", "::"], | ||
["class-name", "Z"] | ||
]], | ||
["punctuation", "{"], | ||
["punctuation", "}"], | ||
["punctuation", ";"], | ||
["keyword", "class"], | ||
["class-name", "service"], | ||
["operator", ":"], | ||
["base-clause", [ | ||
["keyword", "private"], | ||
["class-name", "Transport"], | ||
["comment", "// comment"] | ||
]], | ||
["punctuation", "{"], | ||
["punctuation", "}"], | ||
["punctuation", ";"] | ||
] | ||
|
||
---------------------------------------------------- | ||
|
||
Checks for the base clauses of classes and structs. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
class MainWindow : public QMainWindow | ||
{ | ||
Q_OBJECT | ||
|
||
private slots: | ||
void changeWindowTitle(); | ||
}; | ||
void MainWindow::changeWindowTitle() | ||
{ | ||
setWindowTitle(plainTextEdit->currentFile.split("/").last() + " - Notepanda"); | ||
} | ||
|
||
---------------------------------------------------- | ||
|
||
[ | ||
["keyword", "class"], | ||
["class-name", "MainWindow"], | ||
["operator", ":"], | ||
["base-clause", [ | ||
["keyword", "public"], | ||
["class-name", "QMainWindow"] | ||
]], | ||
|
||
["punctuation", "{"], | ||
|
||
"\n Q_OBJECT\n\n ", | ||
|
||
["keyword", "private"], | ||
" slots", | ||
["operator", ":"], | ||
|
||
["keyword", "void"], | ||
["function", "changeWindowTitle"], | ||
["punctuation", "("], | ||
["punctuation", ")"], | ||
["punctuation", ";"], | ||
|
||
["punctuation", "}"], | ||
["punctuation", ";"], | ||
|
||
["keyword", "void"], | ||
["class-name", "MainWindow"], | ||
["operator", "::"], | ||
["function", "changeWindowTitle"], | ||
["punctuation", "("], | ||
["punctuation", ")"], | ||
|
||
["punctuation", "{"], | ||
|
||
["function", "setWindowTitle"], | ||
["punctuation", "("], | ||
"plainTextEdit", | ||
["operator", "->"], | ||
"currentFile", | ||
["punctuation", "."], | ||
["function", "split"], | ||
["punctuation", "("], | ||
["string", "\"/\""], | ||
["punctuation", ")"], | ||
["punctuation", "."], | ||
["function", "last"], | ||
["punctuation", "("], | ||
["punctuation", ")"], | ||
["operator", "+"], | ||
["string", "\" - Notepanda\""], | ||
["punctuation", ")"], | ||
["punctuation", ";"], | ||
|
||
["punctuation", "}"] | ||
] | ||
|
||
---------------------------------------------------- |