Skip to content

Commit

Permalink
feat: [cxx-parser] Add resolveNodeByName (#48)
Browse files Browse the repository at this point in the history
  • Loading branch information
littleGnAl authored Jan 8, 2024
1 parent c08bdcf commit e86dee9
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 18 deletions.
136 changes: 136 additions & 0 deletions cxx-parser/__tests__/unit_test/cxx_parser_ext.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,43 @@ describe('ParseResult', () => {
expect(node).toBe(clazz);
});

it('can find Clazz with duplicated name, but different namespace', () => {
let parseResult = new ParseResult();

const clazz1 = new Clazz();
clazz1.name = 'MyClass';
clazz1.namespaces = ['A', 'B'];

const clazz2 = new Clazz();
clazz2.name = 'MyClass';
clazz2.namespaces = ['A', 'B', 'C'];

parseResult.nodes = [
{
nodes: [clazz1, clazz2],
},
];

{
const simpleType = new SimpleType();
simpleType.kind = SimpleTypeKind.pointer_t;
simpleType.name = 'A::B::MyClass';
simpleType.source = 'MyClass*';
const node = parseResult.resolveNodeByType(simpleType);
expect(node).toBe(clazz1);
}

// Can find the second A::B::C::MyClass
{
const simpleType = new SimpleType();
simpleType.kind = SimpleTypeKind.pointer_t;
simpleType.name = 'A::B::C::MyClass';
simpleType.source = 'MyClass*';
const node = parseResult.resolveNodeByType(simpleType);
expect(node).toBe(clazz2);
}
});

it('can find Struct when the SimpleType ref to a struct', () => {
let parseResult = new ParseResult();
const simpleType = new SimpleType();
Expand Down Expand Up @@ -163,4 +200,103 @@ describe('ParseResult', () => {
expect(returnType).toBe(simpleType);
});
});

describe('resolveNodeByName', () => {
it('can find Clazz with name', () => {
let parseResult = new ParseResult();

const clazz = new Clazz();
clazz.name = 'MyClass';
clazz.namespaces = ['A', 'B'];

parseResult.nodes = [
{
nodes: [clazz],
},
];

const node = parseResult.resolveNodeByName('A::B::MyClass');
expect(node).toBe(clazz);
});

it('can find Clazz with duplicated name, but different namespace', () => {
let parseResult = new ParseResult();

const clazz1 = new Clazz();
clazz1.name = 'MyClass';
clazz1.namespaces = ['A', 'B'];

const clazz2 = new Clazz();
clazz2.name = 'MyClass';
clazz2.namespaces = ['A', 'B', 'C'];

parseResult.nodes = [
{
nodes: [clazz1, clazz2],
},
];

{
const node = parseResult.resolveNodeByName('A::B::MyClass');
expect(node).toBe(clazz1);
}

// Can find the second A::B::C::MyClass
{
const node = parseResult.resolveNodeByName('A::B::C::MyClass');
expect(node).toBe(clazz2);
}
});

it('can find Struct with name', () => {
let parseResult = new ParseResult();

const struct = new Struct();
struct.name = 'MyStruct';
struct.namespaces = ['A', 'B'];

parseResult.nodes = [
{
nodes: [struct],
},
];

const node = parseResult.resolveNodeByName('A::B::MyStruct');
expect(node).toBe(struct);
});

it('can find Enum with name', () => {
let parseResult = new ParseResult();

const enumz = new Enumz();
enumz.name = 'MyEnum';
enumz.namespaces = ['A', 'B'];

parseResult.nodes = [
{
nodes: [enumz],
},
];

const node = parseResult.resolveNodeByName('A::B::MyEnum');
expect(node).toBe(enumz);
});

it('can not find a node by name', () => {
let parseResult = new ParseResult();

const clazz = new Clazz();
clazz.name = 'MyClass';
clazz.namespaces = ['A', 'B'];

parseResult.nodes = [
{
nodes: [clazz],
},
];

const returnType = parseResult.resolveNodeByName('unknow');
expect(returnType).toBeUndefined();
});
});
});
44 changes: 26 additions & 18 deletions cxx-parser/src/cxx_parser_ext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ declare module '@agoraio-extensions/terra-core' {
* @returns The resolved `CXXTerraNode`.
*/
resolveNodeByType(type: SimpleType): CXXTerraNode;

/**
* Resolves a `CXXTerraNode` based on the given node's name. If none is found, the undefined is returned.
*
* @param name - The node's name to resolve.
* @returns The resolved `CXXTerraNode`.
*/
resolveNodeByName(name: string): CXXTerraNode | undefined;
}
}

Expand Down Expand Up @@ -118,13 +126,6 @@ ParseResult.prototype.findEnumz = function (
ParseResult.prototype.resolveNodeByType = function (
type: SimpleType
): CXXTerraNode {
function _match(ns: string, namespace_string: string): boolean {
return (
ns == namespace_string ||
namespace_string == '' ||
ns.includes(namespace_string)
);
}
let name = type.name;
if (name.length === 0) {
return type;
Expand All @@ -142,26 +143,33 @@ ParseResult.prototype.resolveNodeByType = function (
name = type.template_arguments[0];
}

const namespaceInString = name.getNamespace();
const nameWithoutNS = name.trimNamespace();
return this.resolveNodeByName(name) ?? type;
};

ParseResult.prototype.resolveNodeByName = function (
name: string
): CXXTerraNode | undefined {
for (const f of this.nodes) {
let cxxFile = f as CXXFile;
for (const node of cxxFile.nodes) {
if (node.name === nameWithoutNS) {
let ns = node.namespaces.join('::');
let found = _match(ns, namespaceInString);
if (!found && node.parent_name) {
ns = [...node.namespaces, node.parent_name].join('::');
found = _match(ns, namespaceInString);
}
if (
name == node.fullName ||
(node.fullName.includes(name) && name.trimNamespace() == node.name)
) {
return node;
}

if (found) {
if (node.parent_name) {
let tmp = [...node.namespaces, node.parent_name, node.name].join('::');
if (
name == tmp ||
(tmp.includes(name) && name.trimNamespace() == node.name)
) {
return node;
}
}
}
}

return type;
return undefined;
};

0 comments on commit e86dee9

Please sign in to comment.