{"id":12803,"library":"apex-parser","title":"Salesforce Apex Language Parser","description":"apex-parser is a JavaScript parser specifically designed for the Salesforce Apex language, including support for Apex Triggers, and inline SOQL (Salesforce Object Query Language) and SOSL (Salesforce Object Search Language) queries. Built upon an ANTLR4 grammar, it provides a low-level parse tree representation of Apex code. The current stable version is 2.17.0, with regular updates addressing bug fixes, new Apex/SOQL/SOSL features, and dependency updates. Unlike higher-level tools, this library focuses solely on parsing, offering the raw parse tree for further analysis by downstream tools, rather than providing built-in semantic analysis. A key differentiator is its correct handling of Apex's case-insensitivity through a custom input stream. It is available as an NPM module for Node.js environments and a Maven package for JVMs.","status":"active","version":"2.17.0","language":"javascript","source_language":"en","source_url":"https://github.com/nawforce/apex-parser","tags":["javascript"],"install":[{"cmd":"npm install apex-parser","lang":"bash","label":"npm"},{"cmd":"yarn add apex-parser","lang":"bash","label":"yarn"},{"cmd":"pnpm add apex-parser","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Primary lexer class for tokenizing Apex code. The library ships with TypeScript definitions and is typically consumed via ESM imports.","wrong":"const ApexLexer = require('apex-parser').ApexLexer;","symbol":"ApexLexer","correct":"import { ApexLexer } from 'apex-parser';"},{"note":"Main parser class to construct the Abstract Syntax Tree (AST) from a token stream.","wrong":"const ApexParser = require('apex-parser').ApexParser;","symbol":"ApexParser","correct":"import { ApexParser } from 'apex-parser';"},{"note":"Essential for correct parsing as Apex is a case-insensitive language. This stream wraps your input string.","wrong":"const CaseInsensitiveInputStream = require('apex-parser').CaseInsensitiveInputStream;","symbol":"CaseInsensitiveInputStream","correct":"import { CaseInsensitiveInputStream } from 'apex-parser';"},{"note":"It is recommended to import `CommonTokenStream` (and `ParseTreeWalker`) directly from `apex-parser` rather than `antlr4ts` to ensure version compatibility.","wrong":"import { CommonTokenStream } from 'antlr4ts';","symbol":"CommonTokenStream","correct":"import { CommonTokenStream } from 'apex-parser';"}],"quickstart":{"code":"import { ApexLexer, CaseInsensitiveInputStream, CommonTokenStream, ApexParser } from 'apex-parser';\n\nfunction parseApexCode(code: string): any {\n  const lexer = new ApexLexer(new CaseInsensitiveInputStream(code));\n  const tokens = new CommonTokenStream(lexer);\n  const parser = new ApexParser(tokens);\n  \n  // Optionally add error listeners for more robust error handling\n  // parser.removeErrorListeners();\n  // parser.addErrorListener(new MyErrorListener());\n\n  // The root context for a class file is compilationUnit()\n  const context = parser.compilationUnit();\n  \n  console.log('Successfully parsed Apex code.');\n  // You can traverse the parse tree from the 'context' object.\n  // Example: Printing the tree structure (simplified, for illustration)\n  // console.log(context.toStringTree(parser.ruleNames));\n  \n  return context;\n}\n\nconst apexClassCode = `\npublic class MyExampleClass {\n    public void myMethod(String param) {\n        // Example SOQL query\n        List<Account> accounts = [SELECT Id, Name FROM Account WHERE Name = :param];\n        System.debug('Accounts found: ' + accounts.size());\n    }\n}\n`;\n\nconst parseTree = parseApexCode(apexClassCode);\n// In a real application, you would now use ANTLR4 visitors or listeners\n// to traverse 'parseTree' and extract information or perform analysis.\nconsole.log(`Root context type: ${parseTree.constructor.name}`);","lang":"typescript","description":"Demonstrates how to initialize the Apex Lexer and Parser, feed it Apex code, and obtain the root parse tree context for further traversal."},"warnings":[{"fix":"Ensure your code correctly interprets character positions based on Unicode code points if upgrading from older versions. Test any existing tools that consume character offsets.","message":"The internal handling of character positions for Unicode code points changed. Prior to 2.12.0 (JVM) and 2.14.0 (Node), `ANTLRInputStream` resulted in UTF-16 character positions. After these versions, switching to `CharStream` aligns character positions with Unicode code points. This might affect tools relying on precise character offsets.","severity":"breaking","affected_versions":">=2.12.0"},{"fix":"Always wrap your input string with `new CaseInsensitiveInputStream(yourCodeString)` before passing it to the lexer.","message":"Apex and its embedded languages (SOQL/SOSL) are case-insensitive. Failing to use `CaseInsensitiveInputStream` will lead to incorrect parsing results as the parser expects a case-insensitive stream.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Change `import { CommonTokenStream } from 'antlr4ts';` to `import { CommonTokenStream } from 'apex-parser';`.","message":"To avoid version conflicts with the underlying `antlr4ts` library, it is strongly recommended to import shared ANTLR components like `CommonTokenStream` and `ParseTreeWalker` directly from `apex-parser` rather than importing them from `antlr4ts`.","severity":"gotcha","affected_versions":">=2.9.1"},{"fix":"Consult the `SOSLParserTest` examples or the grammar for specific rules to use when parsing SOSL FIND queries in different contexts.","message":"SOSL FIND clauses use different quoting characters when embedded within Apex (single quotes `'`) versus when used in the API format (braces `{}`). There are alternative parser rules (e.g., `soslLiteralAlt`) available to handle these differences.","severity":"gotcha","affected_versions":">=2.7.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Wrap your input string in `new CaseInsensitiveInputStream(yourApexCode)` before creating the lexer.","cause":"The input stream provided to the lexer/parser is case-sensitive, but Apex is a case-insensitive language.","error":"Error: MismatchedTokenException: expecting 'class' got 'CLASS'"},{"fix":"Instead of `import { CommonTokenStream } from 'antlr4ts';`, use `import { CommonTokenStream } from 'apex-parser';`.","cause":"A version mismatch between `antlr4ts` installed directly in your project and the version `apex-parser` expects internally.","error":"TypeError: Cannot read properties of undefined (reading 'CommonTokenStream') when importing from 'antlr4ts'"},{"fix":"Ensure your Node.js environment supports ES modules (Node.js >=12, with `.mjs` or `type: \"module\"` in `package.json`), or switch to CommonJS `require()` syntax: `const { ApexLexer } = require('apex-parser');`.","cause":"Attempting to use ES module `import` syntax in a CommonJS-only environment (e.g., older Node.js versions or misconfigured bundlers).","error":"SyntaxError: Unexpected token 'export' or 'import'"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null}