summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRowan Goemans <RB.Goemans@student.han.nl>2018-01-01 20:19:58 +0100
committerChristoph Schlosser <christophschlosser@users.noreply.github.com>2018-02-20 22:02:22 +0100
commitd9cef62f8778fcdc39d26802d5d7457c97e9dfc0 (patch)
tree56a66694227f4529319208cec317ed7aa08c91a4 /src
parent31f6517aa5d8d3ccdd0b39880337c000943d08c1 (diff)
downloaddoxdocgen-d9cef62f8778fcdc39d26802d5d7457c97e9dfc0.tar.gz
-- Finished all parameter tests.
-- Added support for all C++ string literals.
Diffstat (limited to 'src')
-rw-r--r--src/Lang/Cpp/CppParser.ts58
-rw-r--r--src/test/CppTests/Config.tests.ts1
-rw-r--r--src/test/CppTests/Parameters.test.ts235
-rw-r--r--src/test/CppTests/ReturnTypes.test.ts53
4 files changed, 336 insertions, 11 deletions
diff --git a/src/Lang/Cpp/CppParser.ts b/src/Lang/Cpp/CppParser.ts
index 27abc8a..fcbdbe0 100644
--- a/src/Lang/Cpp/CppParser.ts
+++ b/src/Lang/Cpp/CppParser.ts
@@ -60,7 +60,53 @@ export default class CppParser implements ICodeParser {
this.lexerVocabulary = {
ArraySubscript: (x: string): string => (x.match("^\\[[^\\[]*?\\]") || [])[0],
Arrow: (x: string): string => (x.match("^->") || [])[0],
- Assignment: (x: string): string => (x.match("^=") || [])[0],
+ Assignment: (x: string): string => {
+ if (!x.match("^=")) {
+ return undefined;
+ }
+
+ const nesters: Map<string, string> = new Map<string, string>([
+ ["<", ">"], ["(", ")"], ["{", "}"], ["[", "]"],
+ ]);
+
+ for (let i = 0; i < x.length; i++) {
+ const v = nesters.get(x[i]);
+ if (v !== undefined) {
+ const startEndOffset: number[] = this.GetSubExprStartEnd(x, i, x[i], v);
+ if (startEndOffset[1] === 0) {
+ return undefined;
+ }
+ i = startEndOffset[1] - 1;
+ } else if (x[i] === "\"" || x[i] === "'") {
+ // Check if raw literal. Since those may have unescaped characters
+ // but require ()
+ if (x[i - 1] !== "R") {
+ // Skip to next end of the string or char literal.
+ let found: boolean = false;
+ for (let j = i + 1; j < x.length; j++) {
+ if (x[j] === x[i] && x[j - 1] !== "\\") {
+ found = true;
+ i = j;
+ break;
+ }
+ }
+ if (!found) {
+ return undefined;
+ }
+ } else {
+ const startEndOffset: number[] = this.GetSubExprStartEnd(x, i, "(", ")");
+ if (startEndOffset[1] === 0) {
+ return undefined;
+ }
+ i = startEndOffset[1];
+ }
+ } else if (x[i] === "," || x[i] === ")") {
+ return x.slice(0, i);
+ }
+ }
+
+ return x;
+ },
Attribute: (x: string): string => {
const attribute: string = (x.match("^\\[\\[[^\\[]*?\\]\\]") || [])[0];
if (attribute !== undefined) {
@@ -113,11 +159,6 @@ export default class CppParser implements ICodeParser {
Pointer: (x: string): string => (x.match("^\\*") || [])[0],
Reference: (x: string): string => (x.match("^&") || [])[0],
Symbol: (x: string): string => {
- // Handle access specifiers since they aren't really symbols.
- if (x.startsWith("public:") || x.startsWith("protected:") || x.startsWith("private:")) {
- return undefined;
- }
-
// Handle specifiers
const specifierFound: number = this.attributes
.findIndex((n: string) => x.startsWith(n) === true);
@@ -134,18 +175,19 @@ export default class CppParser implements ICodeParser {
// Special case group up the fundamental types with the modifiers.
// tslint:disable-next-line:max-line-length
- let reMatch: string = (x.match("^(unsigned|signed|short|long|int|char|double)(\\s+(unsigned|signed|short|long|int|char|double))+(?!a-z|A-Z|:|_)") || [])[0];
+ let reMatch: string = (x.match("^(unsigned|signed|short|long|int|char|double)(\\s+(unsigned|signed|short|long|int|char|double))+(?!a-z|A-Z|:|_|\\d)") || [])[0];
if (reMatch !== undefined) {
return reMatch.trim();
}
// Regex to handle a part of all symbols and includes all symbol special cases.
// This is run in a loop because template parts of a symbol can't be parsed using regex.
+ // Also check if it doesn't start with a number since those are always literals
// tslint:disable-next-line:max-line-length
const symbolRegex: string = "^([a-z|A-Z|:|_|~|\\d]*operator\\s*(\"\"_[a-z|A-Z|_|\\d]+|>>=|<<=|->\\*|\\+=|-=|\\*=|\\/=|%=|\\^=|&=|\\|=|<<|>>|==|!=|<=|->|>=|&&|\\|\\||\\+\\+|--|\\+|-|\\*|\\/|%|\\^|&|\||~|!|=|<|>|,|\\[\\s*\\]|\\(\\s*\\)|(new|delete)\\s*(\\[\\s*\\]){0,1}){0,1}|[a-z|A-Z|:|_|~|\\d]+)";
reMatch = (x.match(symbolRegex) || [])[0];
- if (reMatch === undefined) {
+ if (reMatch === undefined || x.match(/^\d/)) {
return undefined;
}
diff --git a/src/test/CppTests/Config.tests.ts b/src/test/CppTests/Config.tests.ts
index 3d5fc0a..0143341 100644
--- a/src/test/CppTests/Config.tests.ts
+++ b/src/test/CppTests/Config.tests.ts
@@ -16,5 +16,4 @@ suite("C++ - Configuration Tests", () => {
const testSetup: TestSetup = new TestSetup("void foo();");
// Tests
-
});
diff --git a/src/test/CppTests/Parameters.test.ts b/src/test/CppTests/Parameters.test.ts
index 02d3773..8505826 100644
--- a/src/test/CppTests/Parameters.test.ts
+++ b/src/test/CppTests/Parameters.test.ts
@@ -17,4 +17,239 @@ suite("C++ - Parameters Tests", () => {
const testSetup: TestSetup = new TestSetup("void foo();");
// Tests
+ test("No parameters", () => {
+ const result = testSetup.SetLine("void foo();").GetResult();
+ assert.equal("/**\n * @brief \n * \n */", result);
+ });
+
+ test("Single parameter", () => {
+ const result = testSetup.SetLine("void foo(int a);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a \n */", result);
+ });
+
+ test("Multiple parameters", () => {
+ const result = testSetup.SetLine("void foo(int a, int b, int c);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a \n * @param b \n * @param c \n */", result);
+ });
+
+ test("Parameters with numbers in them", () => {
+ const result = testSetup.SetLine("void foo(int a1, int b23);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b23 \n */", result);
+ });
+
+ test("Reference parameter", () => {
+ const result = testSetup.SetLine("void foo(int& a);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a \n */", result);
+ });
+
+ test("Pointer parameter", () => {
+ const result = testSetup.SetLine("void foo(int* a);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a \n */", result);
+ });
+
+ test("Const parameter", () => {
+ let result = testSetup.SetLine("void foo(const int a1);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n */", result);
+
+ result = testSetup.SetLine("void foo(int const a1);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n */", result);
+ });
+
+ test("Struct parameter", () => {
+ const result = testSetup.SetLine("void foo(int a1, int b23);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b23 \n */", result);
+ });
+
+ test("Template parameter", () => {
+ const result = testSetup.SetLine("void foo(Matrix<T, N, M> mat);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param mat \n */", result);
+ });
+
+ test("Const parameter with const pointer to const pointer", () => {
+ let result = testSetup.SetLine("void foo(const int * const * const a1);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n */", result);
+
+ result = testSetup.SetLine("void foo(int const * const * const a1);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n */", result);
+ });
+
+ test("Fundamental return type with modifiers", () => {
+ let result = testSetup.SetLine("void foo(unsigned int a);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a \n */", result);
+
+ result = testSetup.SetLine("void foo(unsigned short int a);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a \n */", result);
+
+ result = testSetup.SetLine("void foo(signed short a);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a \n */", result);
+
+ result = testSetup.SetLine("void foo(long a);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a \n */", result);
+
+ result = testSetup.SetLine("void foo(unsigned long long int a);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a \n */", result);
+
+ result = testSetup.SetLine("void foo(signed a);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a \n */", result);
+
+ result = testSetup.SetLine("void foo(unsigned a);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a \n */", result);
+
+ result = testSetup.SetLine("void foo(unsigned char a);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a \n */", result);
+
+ result = testSetup.SetLine("void foo(long double a);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a \n */", result);
+
+ result = testSetup.SetLine("void foo(long unsigned unsigned_a);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param unsigned_a \n */", result);
+ });
+
+ test("Parameter type in namespace", () => {
+ const result = testSetup.SetLine("void foo(MyNamespace::Foo a1);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n */", result);
+ });
+
+ test("Parameter template type in namespace", () => {
+ const result = testSetup.SetLine("void foo(Math::Matrix<A, B, C> mat);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param mat \n */", result);
+ });
+
+ test("Parameter template type within templated namespace", () => {
+ const result = testSetup.SetLine("void foo(Matrix<A, B, C>::Matrix<A, B, C> mat);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param mat \n */", result);
+ });
+
+ test("Parameter type in nested namespacee", () => {
+ const result = testSetup.SetLine("void foo( Math::LA::Matrix<A, B, C> mat);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param mat \n */", result);
+ });
+
+ test("Parameter with default char literal", () => {
+ let result = testSetup.SetLine("void foo(char a1 = 'a', int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(char a1 = u'b', int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(char a1 = u8'b', int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(char a1 = U'a', int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(char a1 = l',', int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(int a1 = 'ab', int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+ });
+
+ test("Parameter with default string literal", () => {
+ let result = testSetup.SetLine("void foo(std::string a1 = \"bar\", int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(std::string a1 = u\"bar, test\", int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(std::string a1 = u8\"bar\", int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(std::string a1 = U\"bar\", int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(std::string a1 = l\"bar\", int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(std::string a1 = R\"(bar\\t\\\")\", int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+ });
+
+ test("Parameter with default integer literal", () => {
+ let result = testSetup.SetLine("void foo(int a1 = 1337, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(int a1 = 01337, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(int a1 = 1337, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(int a1 = 0x0FAB, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(int a1 = 0X0FAB, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(std::uint8_t a1 = 0b110011, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(std::byte a1 = 0B11111, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(long a1 = 1337l, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(long long a1 = 1337ll, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(unsigned long long a1 = 1337ull, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(long a1 = 1337L, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(long long a1 = 1337LL, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(unsigned long long a1 = 1337ULL, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+ });
+
+ test("Parameter with default floating point literal", () => {
+ let result = testSetup.SetLine("void foo(double a1 = 1e10, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(double a1 = 1., int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(double a1 = .1, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(double a1 = 0.1e-1, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(float a1 = 1.0f, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(float a1 = 1.0F, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(long double a1 = 1.0lf, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(long double a1 = 1.0LF, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(double a1 = 0xa.bp10, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+
+ result = testSetup.SetLine("void foo(double a1 = 0xa.bp10l, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+ });
+
+ test("Parameter with default compound literal", () => {
+ const result = testSetup.SetLine("void foo(struct Bar a1 = {2, 3}, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+ });
+
+ test("Parameter with default template function call", () => {
+ const result = testSetup.SetLine("void foo(struct Bar a1 = test::baz<3, 2, 5>(23), int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+ });
+
+ test("Parameter with default user defined literal.", () => {
+ const result = testSetup.SetLine("void foo(double a1 = 0xa.bp10l_deg_test, int b);").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @param a1 \n * @param b \n */", result);
+ });
});
diff --git a/src/test/CppTests/ReturnTypes.test.ts b/src/test/CppTests/ReturnTypes.test.ts
index 1a59878..caefa48 100644
--- a/src/test/CppTests/ReturnTypes.test.ts
+++ b/src/test/CppTests/ReturnTypes.test.ts
@@ -62,12 +62,26 @@ suite("C++ - Return type Tests", () => {
assert.equal("/**\n * @brief \n * \n * @return struct Bar* \n */", result);
});
- test("Return type with keywords and noexcept", () => {
+ test("Return type with keywords", () => {
+ const result = testSetup.SetLine("static constexpr inline Bar* const foo() "
+ + "const;").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @return constexpr Bar* const \n */", result);
+ });
+
+ test("Return type struct with keywords", () => {
const result = testSetup.SetLine("static constexpr inline struct Bar* foo() "
- + "const noexcept(false);").GetResult();
+ + "const;").GetResult();
assert.equal("/**\n * @brief \n * \n * @return constexpr struct Bar* \n */", result);
});
+ test("Const with const pointer to const pointer return type", () => {
+ let result = testSetup.SetLine("const int* const* const foo();").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @return const int* const* const \n */", result);
+
+ result = testSetup.SetLine("int const* const* const foo();").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @return int const* const* const \n */", result);
+ });
+
test("Fundamental return type with modifiers", () => {
let result = testSetup.SetLine("unsigned int foo();").GetResult();
assert.equal("/**\n * @brief \n * \n * @return unsigned int \n */", result);
@@ -99,4 +113,39 @@ suite("C++ - Return type Tests", () => {
result = testSetup.SetLine("long unsigned unsigned_foo();").GetResult();
assert.equal("/**\n * @brief \n * \n * @return long unsigned \n */", result);
});
+
+ test("Function in namespace", () => {
+ const result = testSetup.SetLine("int MyClass::foo();").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @return int \n */", result);
+ });
+
+ test("Return Type in namespace", () => {
+ const result = testSetup.SetLine("MyNamespace::Foo CreateFoo();").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @return MyNamespace::Foo \n */", result);
+ });
+
+ test("Template return type", () => {
+ const result = testSetup.SetLine("Matrix<A, B, C> foo();").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @return Matrix<A, B, C> \n */", result);
+ });
+
+ test("Template return type within templated namespace", () => {
+ const result = testSetup.SetLine("Matrix<A, B, C>::Matrix<A, B, C> foo();").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @return Matrix<A, B, C>::Matrix<A, B, C> \n */", result);
+ });
+
+ test("Function in templated namespace", () => {
+ const result = testSetup.SetLine("int Matrix<A, B, C>::foo();").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @return int \n */", result);
+ });
+
+ test("Function with nested namespacee", () => {
+ const result = testSetup.SetLine("int Math::LA::Matrix<A, B, C>::foo();").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @return int \n */", result);
+ });
+
+ test("Return Type in nested namespace", () => {
+ const result = testSetup.SetLine("Math::LA::Matrix<A, B, C> foo();").GetResult();
+ assert.equal("/**\n * @brief \n * \n * @return Math::LA::Matrix<A, B, C> \n */", result);
+ });
});