Skip to content

Commit

Permalink
Remove usage of _.isEmpty
Browse files Browse the repository at this point in the history
relates to #68
  • Loading branch information
Shahar Soel committed Jan 2, 2016
1 parent 79a4cf2 commit 0087635
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 16 deletions.
2 changes: 2 additions & 0 deletions build/chevrotain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
/// <reference path="../libs/lodash.d.ts" />

// production code
/// <reference path="../src/utils/utils.ts" />
// TODO: move lang --> utils ?
/// <reference path="../src/lang/lang_extensions.ts" />
/// <reference path="../src/scan/tokens_public.ts" />
/// <reference path="../src/scan/lexer_public.ts" />
Expand Down
4 changes: 2 additions & 2 deletions src/parse/gast_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ namespace chevrotain.gastBuilder {
let parenthesisStack = [1]

let i = -1
while (!(_.isEmpty(parenthesisStack)) && i + start < text.length) {
while (!(utils.isEmpty(parenthesisStack)) && i + start < text.length) {
i++
let nextChar = text.charAt(start + i)
if (nextChar === opening) {
Expand All @@ -354,7 +354,7 @@ namespace chevrotain.gastBuilder {
}

// valid termination of the search loop
if (_.isEmpty(parenthesisStack)) {
if (utils.isEmpty(parenthesisStack)) {
return i + start
}
else {
Expand Down
6 changes: 3 additions & 3 deletions src/parse/grammar/checks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ namespace chevrotain.checks {
path:gast.Rule[] = []):IParserDefinitionError[] {
let errors = []
let nextNonTerminals = getFirstNoneTerminal(currRule.definition)
if (_.isEmpty(nextNonTerminals)) {
if (utils.isEmpty(nextNonTerminals)) {
return []
}
else {
Expand Down Expand Up @@ -185,7 +185,7 @@ namespace chevrotain.checks {

export function getFirstNoneTerminal(definition:gast.IProduction[]):gast.Rule[] {
let result = []
if (_.isEmpty(definition)) {
if (utils.isEmpty(definition)) {
return result
}
let firstProd = _.first(definition)
Expand Down Expand Up @@ -246,7 +246,7 @@ namespace chevrotain.checks {
let errors = _.reduce(ors, (errors, currOr) => {
let exceptLast = _.dropRight(currOr.definition)
let currErrors = _.map(exceptLast, (currAlternative:IProduction, currAltIdx) => {
if (_.isEmpty(first.first(currAlternative))) {
if (utils.isEmpty(first.first(currAlternative))) {
return {
message: `Ambiguous empty alternative: <${currAltIdx + 1}>` +
` in <OR${currOr.occurrenceInParent}> inside <${topLevelRule.name}> Rule.\n` +
Expand Down
2 changes: 1 addition & 1 deletion src/parse/grammar/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ namespace chevrotain.interpreter {

updateExpectedNext():void {
// need to consume the Terminal
if (_.isEmpty(this.ruleStack)) {
if (utils.isEmpty(this.ruleStack)) {
// must reset nextProductionXXX to avoid walking down another Top Level production while what we are
// really seeking is the last Terminal...
this.nextProductionName = ""
Expand Down
4 changes: 2 additions & 2 deletions src/parse/grammar/lookahead.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ namespace chevrotain.lookahead {
checkForOrAmbiguities(alternativesTokens, orOccurrence, ruleGrammar)
}

let hasLastAnEmptyAlt = _.isEmpty(_.last(alternativesTokens))
let hasLastAnEmptyAlt = utils.isEmpty(_.last(alternativesTokens))
if (hasLastAnEmptyAlt) {
let lastIdx = alternativesTokens.length - 1
/**
Expand Down Expand Up @@ -87,7 +87,7 @@ namespace chevrotain.lookahead {
ruleGrammar:gast.Rule):void {
let altsAmbiguityErrors = checkAlternativesAmbiguities(alternativesTokens)

if (!_.isEmpty(altsAmbiguityErrors)) {
if (!utils.isEmpty(altsAmbiguityErrors)) {
let errorMessages = _.map(altsAmbiguityErrors, (currAmbiguity) => {
return `Ambiguous alternatives: <${currAmbiguity.alts.join(" ,")}> in <OR${orOccurrence}> inside <${ruleGrammar.name}> ` +
`Rule, <${tokenName(currAmbiguity.token)}> may appears as the first Terminal in all these alternatives.\n`
Expand Down
10 changes: 5 additions & 5 deletions src/parse/parser_public.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,18 +168,18 @@ namespace chevrotain {
cache.CLASS_TO_SELF_ANALYSIS_DONE.put(className, true)
let validationErrors = checks.validateGrammar(grammarProductions.values())
definitionErrors.push.apply(definitionErrors, validationErrors) // mutability for the win?
if (!_.isEmpty(definitionErrors) && !Parser.DEFER_DEFINITION_ERRORS_HANDLING) {
if (!utils.isEmpty(definitionErrors) && !Parser.DEFER_DEFINITION_ERRORS_HANDLING) {
defErrorsMsgs = _.map(definitionErrors, defError => defError.message)
throw new Error(`Parser Definition Errors detected\n: ${defErrorsMsgs.join("\n-------------------------------\n")}`)
}
if (_.isEmpty(definitionErrors)) { // this analysis may fail if the grammar is not perfectly valid
if (utils.isEmpty(definitionErrors)) { // this analysis may fail if the grammar is not perfectly valid
let allFollows = follows.computeAllProdsFollows(grammarProductions.values())
cache.setResyncFollowsForClass(className, allFollows)
}
}

// reThrow the validation errors each time an erroneous parser is instantiated
if (!_.isEmpty(cache.CLASS_TO_DEFINITION_ERRORS.get(className)) && !Parser.DEFER_DEFINITION_ERRORS_HANDLING) {
if (!utils.isEmpty(cache.CLASS_TO_DEFINITION_ERRORS.get(className)) && !Parser.DEFER_DEFINITION_ERRORS_HANDLING) {
defErrorsMsgs = _.map(cache.CLASS_TO_DEFINITION_ERRORS.get(className), defError => defError.message)
throw new Error(`Parser Definition Errors detected\n: ${defErrorsMsgs.join("\n-------------------------------\n")}`)
}
Expand Down Expand Up @@ -283,7 +283,7 @@ namespace chevrotain {
}

protected isBackTracking():boolean {
return !(_.isEmpty(this.isBackTrackingStack))
return !(utils.isEmpty(this.isBackTrackingStack))
}

protected SAVE_ERROR(error:exceptions.IRecognitionException):IRecognitionException {
Expand Down Expand Up @@ -1178,7 +1178,7 @@ namespace chevrotain {
}

// must know the possible following tokens to perform single token insertion
if (_.isEmpty(follows)) {
if (utils.isEmpty(follows)) {
return false
}

Expand Down
6 changes: 3 additions & 3 deletions src/scan/lexer_public.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ namespace chevrotain {
*/
constructor(protected tokenClasses:TokenConstructor[], deferDefinitionErrorsHandling:boolean = false) {
this.lexerDefinitionErrors = validatePatterns(tokenClasses)
if (!_.isEmpty(this.lexerDefinitionErrors) && !deferDefinitionErrorsHandling) {
if (!utils.isEmpty(this.lexerDefinitionErrors) && !deferDefinitionErrorsHandling) {
let allErrMessages = _.map(this.lexerDefinitionErrors, (error) => {
return error.message
})
Expand All @@ -121,7 +121,7 @@ namespace chevrotain {
// If definition errors were encountered, the analysis phase may fail unexpectedly/
// Considering a lexer with definition errors may never be used, there is no point
// to performing the analysis anyhow...
if (_.isEmpty(this.lexerDefinitionErrors)) {
if (utils.isEmpty(this.lexerDefinitionErrors)) {
let analyzeResult = analyzeTokenClasses(tokenClasses)
this.allPatterns = analyzeResult.allPatterns
this.patternIdxToClass = analyzeResult.patternIdxToClass
Expand Down Expand Up @@ -151,7 +151,7 @@ namespace chevrotain {
let column = 1
let groups:any = _.clone(this.emptyGroups)

if (!_.isEmpty(this.lexerDefinitionErrors)) {
if (!utils.isEmpty(this.lexerDefinitionErrors)) {
let allErrMessages = _.map(this.lexerDefinitionErrors, (error) => {
return error.message
})
Expand Down
16 changes: 16 additions & 0 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
Utils using lodash style API. (not necessarily 100% compliant) for functional and other utils.
These utils should replace usage of lodash in the production code base. not because they are any better...
but for the purpose of being a dependency free library.
The hotspots in the code are already written in imperative style for performance reasons.
so writing several dozen utils which may be slower than the original lodash, does not matter as much
considering they will not be invoked in hotspots...
*/

namespace utils {

export function isEmpty(arr:any[]) {
return arr.length === 0
}
}

0 comments on commit 0087635

Please sign in to comment.