Skip to content

Commit

Permalink
refactor: replace lodash with native ES2015 functions
Browse files Browse the repository at this point in the history
  • Loading branch information
joliss committed Oct 22, 2022
1 parent 7ffce99 commit b2d13ae
Show file tree
Hide file tree
Showing 49 changed files with 805 additions and 1,085 deletions.
2 changes: 0 additions & 2 deletions packages/chevrotain/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,9 @@
"@chevrotain/gast": "10.3.0",
"@chevrotain/types": "10.3.0",
"@chevrotain/utils": "10.3.0",
"lodash": "4.17.21",
"regexp-to-ast": "0.5.0"
},
"devDependencies": {
"@types/lodash": "4.14.184",
"error-stack-parser": "2.1.4",
"esbuild": "0.15.5",
"gen-esm-wrapper": "1.1.3",
Expand Down
31 changes: 10 additions & 21 deletions packages/chevrotain/src/parse/cst/cst_visitor.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
import isEmpty from "lodash/isEmpty"
import compact from "lodash/compact"
import isArray from "lodash/isArray"
import map from "lodash/map"
import forEach from "lodash/forEach"
import filter from "lodash/filter"
import keys from "lodash/keys"
import isFunction from "lodash/isFunction"
import isUndefined from "lodash/isUndefined"
import { defineNameProp } from "../../lang/lang_extensions"
import { CstNode, ICstVisitor } from "@chevrotain/types"

export function defaultVisit<IN>(ctx: any, param: IN): void {
const childrenNames = keys(ctx)
const childrenNames = Object.keys(ctx)
const childrenNamesLength = childrenNames.length
for (let i = 0; i < childrenNamesLength; i++) {
const currChildName = childrenNames[i]
Expand Down Expand Up @@ -44,14 +35,14 @@ export function createBaseSemanticVisitorConstructor(
const semanticProto = {
visit: function (cstNode: CstNode | CstNode[], param: any) {
// enables writing more concise visitor methods when CstNode has only a single child
if (isArray(cstNode)) {
if (Array.isArray(cstNode)) {
// A CST Node's children dictionary can never have empty arrays as values
// If a key is defined there will be at least one element in the corresponding value array.
cstNode = cstNode[0]
}

// enables passing optional CstNodes concisely.
if (isUndefined(cstNode)) {
if (cstNode === undefined) {
return undefined
}

Expand All @@ -60,9 +51,8 @@ export function createBaseSemanticVisitorConstructor(

validateVisitor: function () {
const semanticDefinitionErrors = validateVisitor(this, ruleNames)
if (!isEmpty(semanticDefinitionErrors)) {
const errorMessages = map(
semanticDefinitionErrors,
if (semanticDefinitionErrors.length > 0) {
const errorMessages = semanticDefinitionErrors.map(
(currDefError) => currDefError.msg
)
throw Error(
Expand Down Expand Up @@ -96,7 +86,7 @@ export function createBaseVisitorConstructorWithDefaults(
defineNameProp(derivedConstructor, grammarName + "BaseSemanticsWithDefaults")

const withDefaultsProto = Object.create(baseConstructor.prototype)
forEach(ruleNames, (ruleName) => {
ruleNames.forEach((ruleName) => {
withDefaultsProto[ruleName] = defaultVisit
})

Expand Down Expand Up @@ -130,12 +120,11 @@ export function validateMissingCstMethods(
visitorInstance: ICstVisitor<unknown, unknown>,
ruleNames: string[]
): IVisitorDefinitionError[] {
const missingRuleNames = filter(ruleNames, (currRuleName) => {
return isFunction((visitorInstance as any)[currRuleName]) === false
const missingRuleNames = ruleNames.filter((currRuleName) => {
return typeof (visitorInstance as any)[currRuleName] !== "function"
})

const errors: IVisitorDefinitionError[] = map(
missingRuleNames,
const errors: IVisitorDefinitionError[] = missingRuleNames.map(
(currRuleName) => {
return {
msg: `Missing visitor method: <${currRuleName}> on ${<any>(
Expand All @@ -147,5 +136,5 @@ export function validateMissingCstMethods(
}
)

return compact<IVisitorDefinitionError>(errors)
return errors.filter((err) => !!err)
}
48 changes: 20 additions & 28 deletions packages/chevrotain/src/parse/errors_public.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { hasTokenLabel, tokenLabel } from "../scan/tokens_public"
import first from "lodash/first"
import map from "lodash/map"
import reduce from "lodash/reduce"
import { Alternation, NonTerminal, Rule, Terminal } from "@chevrotain/gast"
import { getProductionDslName } from "@chevrotain/gast"
import {
Expand Down Expand Up @@ -39,26 +36,23 @@ export const defaultParserErrorProvider: IParserErrorMessageProvider = {
}): string {
const errPrefix = "Expecting: "
// TODO: issue: No Viable Alternative Error may have incomplete details. #502
const actualText = first(actual)!.image
const actualText = actual[0]!.image
const errSuffix = "\nbut found: '" + actualText + "'"

if (customUserDescription) {
return errPrefix + customUserDescription + errSuffix
} else {
const allLookAheadPaths = reduce(
expectedPathsPerAlt,
const allLookAheadPaths = expectedPathsPerAlt.reduce(
(result, currAltPaths) => result.concat(currAltPaths),
[] as TokenType[][]
)
const nextValidTokenSequences = map(
allLookAheadPaths,
const nextValidTokenSequences = allLookAheadPaths.map(
(currPath) =>
`[${map(currPath, (currTokenType) => tokenLabel(currTokenType)).join(
", "
)}]`
`[${currPath
.map((currTokenType) => tokenLabel(currTokenType))
.join(", ")}]`
)
const nextValidSequenceItems = map(
nextValidTokenSequences,
const nextValidSequenceItems = nextValidTokenSequences.map(
(itemMsg, idx) => ` ${idx + 1}. ${itemMsg}`
)
const calculatedDescription = `one of these possible Token sequences:\n${nextValidSequenceItems.join(
Expand All @@ -77,18 +71,17 @@ export const defaultParserErrorProvider: IParserErrorMessageProvider = {
}): string {
const errPrefix = "Expecting: "
// TODO: issue: No Viable Alternative Error may have incomplete details. #502
const actualText = first(actual)!.image
const actualText = actual[0]!.image
const errSuffix = "\nbut found: '" + actualText + "'"

if (customUserDescription) {
return errPrefix + customUserDescription + errSuffix
} else {
const nextValidTokenSequences = map(
expectedIterationPaths,
const nextValidTokenSequences = expectedIterationPaths.map(
(currPath) =>
`[${map(currPath, (currTokenType) => tokenLabel(currTokenType)).join(
","
)}]`
`[${currPath
.map((currTokenType) => tokenLabel(currTokenType))
.join(",")}]`
)
const calculatedDescription =
`expecting at least one iteration which starts with one of these possible Token sequences::\n ` +
Expand Down Expand Up @@ -137,7 +130,7 @@ export const defaultGrammarValidatorErrorProvider: IGrammarValidatorErrorMessage
}

const topLevelName = topLevelRule.name
const duplicateProd = first(duplicateProds)!
const duplicateProd = duplicateProds[0]!
const index = duplicateProd.idx
const dslName = getProductionDslName(duplicateProd)
const extraArgument = getExtraProductionArgument(duplicateProd)
Expand Down Expand Up @@ -176,9 +169,9 @@ export const defaultGrammarValidatorErrorProvider: IGrammarValidatorErrorMessage
ambiguityIndices: number[]
alternation: Alternation
}): string {
const pathMsg = map(options.prefixPath, (currTok) =>
tokenLabel(currTok)
).join(", ")
const pathMsg = options.prefixPath
.map((currTok) => tokenLabel(currTok))
.join(", ")
const occurrence =
options.alternation.idx === 0 ? "" : options.alternation.idx
const errMsg =
Expand All @@ -199,9 +192,9 @@ export const defaultGrammarValidatorErrorProvider: IGrammarValidatorErrorMessage
ambiguityIndices: number[]
alternation: Alternation
}): string {
const pathMsg = map(options.prefixPath, (currtok) =>
tokenLabel(currtok)
).join(", ")
const pathMsg = options.prefixPath
.map((currtok) => tokenLabel(currtok))
.join(", ")
const occurrence =
options.alternation.idx === 0 ? "" : options.alternation.idx
let currMessage =
Expand Down Expand Up @@ -277,8 +270,7 @@ export const defaultGrammarValidatorErrorProvider: IGrammarValidatorErrorMessage
leftRecursionPath: Rule[]
}): string {
const ruleName = options.topLevelRule.name
const pathNames = map(
options.leftRecursionPath,
const pathNames = options.leftRecursionPath.map(
(currRule) => currRule.name
)
const leftRecursivePath = `${ruleName} --> ${pathNames
Expand Down
3 changes: 1 addition & 2 deletions packages/chevrotain/src/parse/exceptions_public.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import includes from "lodash/includes"
import {
IToken,
IRecognitionException,
Expand All @@ -22,7 +21,7 @@ Object.freeze(RECOGNITION_EXCEPTION_NAMES)
// hacks to bypass no support for custom Errors in javascript/typescript
export function isRecognitionException(error: Error) {
// can't do instanceof on hacked custom js exceptions
return includes(RECOGNITION_EXCEPTION_NAMES, error.name)
return RECOGNITION_EXCEPTION_NAMES.indexOf(error.name) !== -1
}

abstract class RecognitionException
Expand Down
Loading

0 comments on commit b2d13ae

Please sign in to comment.