Skip to content

Commit

Permalink
fix(parser): fixed lgtm warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
KFlash committed Jul 28, 2019
1 parent a1f41a5 commit 558ba1f
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 218 deletions.
157 changes: 86 additions & 71 deletions src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const enum PropertyKind {
export const enum BindingKind {
None = 0,
ArgumentList = 1 << 0,
EmptyBinding = 1 << 1,
Empty = 1 << 1,
Variable = 1 << 2,
Let = 1 << 3,
Const = 1 << 4,
Expand Down Expand Up @@ -325,7 +325,7 @@ export function reinterpretToPattern(state: ParserState, node: any): void {
export function validateBindingIdentifier(
parser: ParserState,
context: Context,
type: BindingKind,
kind: BindingKind,
t: Token,
skipEvalArgCheck: 0 | 1
): void {
Expand Down Expand Up @@ -356,7 +356,7 @@ export function validateBindingIdentifier(
// The BoundNames of LexicalDeclaration and ForDeclaration must not
// contain 'let'. (CatchParameter is the only lexical binding form
// without this restriction.)
if (type & (BindingKind.Let | BindingKind.Const) && t === Token.LetKeyword) {
if (kind & (BindingKind.Let | BindingKind.Const) && t === Token.LetKeyword) {
report(parser, Errors.InvalidLetConstBinding);
}

Expand Down Expand Up @@ -493,12 +493,26 @@ export function isEqualTagName(elementName: any): any {
}
}

export function createArrowScope(parser: ParserState, context: Context, value: string) {

/**
* Create a parsing scope for arrow head, and add lexical binding
*
* @param parser Parser state
* @param context Context masks
* @param value Binding name to be declared
*/
export function createArrowHeadParsingScope(parser: ParserState, context: Context, value: string): ScopeState {
const scope = addChildScope(createScope(), ScopeKind.ArrowParams);
addBlockName(parser, context, scope, value, BindingKind.ArgumentList, BindingOrigin.Other);
return scope;
}

/**
* Record duplicate binding errors that may occur in a arrow head or function parameters
*
* @param parser Parser state
* @param type Errors type
*/
export function recordScopeError(parser: ParserState, type: Errors): ScopeError {
const { index, line, column } = parser;
return {
Expand All @@ -523,9 +537,9 @@ export function createScope(): ScopeState {
* Inherit scope
*
* @param scope Parser object
* @param type Scope type
* @param type Scope kind
*/
export function addChildScope(parent: any, type: ScopeKind): ScopeState {
export function addChildScope(parent: ScopeState | undefined, type: ScopeKind): ScopeState {
return {
parent,
type,
Expand All @@ -548,20 +562,75 @@ export function addVarOrBlock(
context: Context,
scope: ScopeState,
name: string,
type: BindingKind,
kind: BindingKind,
origin: BindingOrigin
) {
if (type & BindingKind.Variable) {
addVarName(parser, context, scope, name, type);
if (kind & BindingKind.Variable) {
addVarName(parser, context, scope, name, kind);
} else {
addBlockName(parser, context, scope, name, type, BindingOrigin.Other);
addBlockName(parser, context, scope, name, kind, BindingOrigin.Other);
}
if (origin & BindingOrigin.Export) {
updateExportsList(parser, parser.tokenValue);
addBindingToExports(parser, parser.tokenValue);
updateExportsList(parser, name);
addBindingToExports(parser, name);
}
}

/**
* Adds block scoped binding
*
* @param parser Parser state
* @param context Context masks
* @param scope Scope state
* @param name Binding name
* @param type Binding kind
* @param origin Binding Origin
*/
export function addBlockName(
parser: ParserState,
context: Context,
scope: any,
name: string,
kind: BindingKind,
origin: BindingOrigin
) {
const value = (scope as any)['#' + name];

if (value && (value & BindingKind.Empty) === 0) {
if (kind & BindingKind.ArgumentList) {
scope.scopeError = recordScopeError(parser, Errors.Unexpected);
} else if (
context & Context.OptionsWebCompat &&
value & BindingKind.FunctionLexical &&
origin & BindingOrigin.BlockStatement
) {
} else {
report(parser, Errors.DuplicateBinding, name);
}
}

if (
scope.type & ScopeKind.FunctionBody &&
((scope as any).parent['#' + name] && ((scope as any).parent['#' + name] & BindingKind.Empty) === 0)
) {
report(parser, Errors.DuplicateBinding, name);
}

if (scope.type & ScopeKind.ArrowParams && value && (value & BindingKind.Empty) === 0) {
if (kind & BindingKind.ArgumentList) {
scope.scopeError = recordScopeError(parser, Errors.Unexpected);
}
}

if (scope.type & ScopeKind.CatchBlock) {
if ((scope as any).parent['#' + name] & BindingKind.CatchNoPatternOrPattern)
report(parser, Errors.ShadowedCatchClause, name);
}

(scope as any)['#' + name] = kind;
}


/**
* Adds a variable binding
*
Expand All @@ -576,7 +645,7 @@ export function addVarName(
context: Context,
scope: ScopeState,
name: string,
type: BindingKind
kind: BindingKind
): void {
let currentScope: any = scope;

Expand All @@ -587,15 +656,15 @@ export function addVarName(
if (
context & Context.OptionsWebCompat &&
(context & Context.Strict) === 0 &&
((type & BindingKind.FunctionStatement && value & BindingKind.LexicalOrFunction) ||
(value & BindingKind.FunctionStatement && type & BindingKind.LexicalOrFunction))
((kind & BindingKind.FunctionStatement && value & BindingKind.LexicalOrFunction) ||
(value & BindingKind.FunctionStatement && kind & BindingKind.LexicalOrFunction))
) {
} else {
report(parser, Errors.DuplicateBinding, name);
}
}
if (currentScope === scope) {
if (value & BindingKind.ArgumentList && type & BindingKind.ArgumentList) {
if (value & BindingKind.ArgumentList && kind & BindingKind.ArgumentList) {
currentScope.scopeError = recordScopeError(parser, Errors.Unexpected);
}
}
Expand All @@ -609,66 +678,12 @@ export function addVarName(
}
}

currentScope['#' + name] = type;
currentScope['#' + name] = kind;

currentScope = currentScope.parent;
}
}

/**
* Adds block scoped binding
*
* @param parser Parser state
* @param context Context masks
* @param scope Scope state
* @param name Binding name
* @param type Binding kind
* @param origin Binding Origin
*/
export function addBlockName(
parser: ParserState,
context: Context,
scope: any,
name: string,
type: BindingKind,
origin: BindingOrigin
) {
const value = (scope as any)['#' + name];

if (value && (value & BindingKind.EmptyBinding) === 0) {
if (type & BindingKind.ArgumentList) {
scope.scopeError = recordScopeError(parser, Errors.Unexpected);
} else if (
context & Context.OptionsWebCompat &&
value & BindingKind.FunctionLexical &&
origin & BindingOrigin.BlockStatement
) {
} else {
report(parser, Errors.DuplicateBinding, name);
}
}

if (
scope.type & ScopeKind.FunctionBody &&
((scope as any).parent['#' + name] && ((scope as any).parent['#' + name] & BindingKind.EmptyBinding) === 0)
) {
report(parser, Errors.DuplicateBinding, name);
}

if (scope.type & ScopeKind.ArrowParams && value && (value & BindingKind.EmptyBinding) === 0) {
if (type & BindingKind.ArgumentList) {
scope.scopeError = recordScopeError(parser, Errors.Unexpected);
}
}

if (scope.type & ScopeKind.CatchBlock) {
if ((scope as any).parent['#' + name] & BindingKind.CatchNoPatternOrPattern)
report(parser, Errors.ShadowedCatchClause, name);
}

(scope as any)['#' + name] = type;
}

/**
* Appends a name to the `ExportedNames` of the `ExportsList`, and checks
* for duplicates
Expand Down

0 comments on commit 558ba1f

Please sign in to comment.