0.5.1 • Published 8 months ago

libclangjs v0.5.1

Weekly downloads
-
License
-
Repository
github
Last release
8 months ago

Release libclangjs

Quickstart

1. Install the package from NPM

$ npm install libclangjs

2.a. Usage with NodeJS

Add the Code you want to analyze using clang

// main.cpp in the root of your project, alongside the package.json
class TestClass {
public:
  TestClass();
  ~TestClass();
};

Analyze the code using clang

import init from "libclangjs/node.js"; // The NodeJS version of libclang uses the CommonJS module format

const cwd = "/home/web_user";

init().then(clang => {
  clang.FS.mount(clang.NODEFS, { root: "." }, cwd); // Share the current directory with libclang
  const index = clang.createIndex(1, 1);
  const tu = clang.parseTranslationUnit(index, `${cwd}/main.cpp`, null, null, 0);
  const cursor = clang.getTranslationUnitCursor(tu);

  clang.visitChildren(cursor, (c, p) => {
    console.log(clang.getCursorKindSpelling(clang.getCursorKind(c)), clang.getCursorSpelling(c), clang.getPresumedLocation(clang.getCursorLocation(c)));
    return clang.CXChildVisitResult.Recurse;
  });

  clang.PThread.terminateAllThreads();
});

2.b. Usage with the browser

const code =
`class TestClass {
public:
  TestClass();
  ~TestClass();
};
`;

// ...

import init from "libclangjs/web"; // The web version of libclang uses the ESM module format

const cwd = "/home/web_user";
init().then(clang => {
  clang.FS.writeFile(`${cwd}/main.cpp`, code); // Create a source file in the memory file system (sharing is not possible, here)
  const index = clang.createIndex(1, 1);
  const tu = clang.parseTranslationUnit(index, `${cwd}/main.cpp`, null, null, 0);
  const cursor = clang.getTranslationUnitCursor(tu);

  clang.visitChildren(cursor, (c, p) => {
    console.log(clang.getCursorKindSpelling(clang.getCursorKind(c)), clang.getCursorSpelling(c), clang.getPresumedLocation(clang.getCursorLocation(c)));
    return clang.CXChildVisitResult.Recurse;
  });

  clang.PThread.terminateAllThreads();
});

Libclang uses multi-threading for maximum performance, which requires the use of a SharedArrayBuffer, which is a well supported feature in modern browsers. Enabling this feature requires setting the Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp headers on the top level document, as described here. An example config for NextJS would look like this:

// next.config.js
const nextConfig = {
  headers: async () => [{
    source: "/:path*",
    headers: [{
      key: "Cross-Origin-Opener-Policy",
      value: "same-origin",
    }, {
      key: "Cross-Origin-Embedder-Policy",
      value: "require-corp",
    }],
  }],
}

module.exports = nextConfig

3. Output

ClassDecl TestClass { filename: '/home/web_user/main.cpp', line: 1, column: 7 }
CXXAccessSpecifier  { filename: '/home/web_user/main.cpp', line: 2, column: 1 }
CXXConstructor TestClass { filename: '/home/web_user/main.cpp', line: 3, column: 3 }
CXXDestructor ~TestClass { filename: '/home/web_user/main.cpp', line: 4, column: 3 }

The execution will take several seconds to complete. A big part of that time is taken by the call to init. Subsequent function calls should run fast - but so far no benchmarking against the native version has been done.

Extending / Integrating with other C/C++ code

Check out Libclangjs-cmake on NPM and this test for an example on how this can be achieved.

Contribution and release workflow

This project ist using Changesets for publishing and managing versions.

  1. Create a new branch / PR with the desired canges
  2. After the changes are made, run pnpm changeset and answer the questionnaire. Commit the results.
0.5.1

8 months ago

0.5.0

9 months ago

0.4.0

10 months ago

0.3.2

1 year ago

0.3.1

1 year ago

0.3.0

1 year ago

0.2.5

1 year ago

0.2.4

1 year ago

0.2.3

1 year ago

0.2.2

1 year ago

0.2.1

1 year ago

0.2.0

1 year ago

0.1.8

1 year ago

0.1.7

1 year ago

0.1.6

1 year ago

0.1.5

1 year ago

0.1.4

1 year ago

0.1.3

1 year ago

0.1.2

1 year ago

0.1.1

1 year ago

0.1.0

1 year ago