Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge declaration and init of props in parser's state #9312

Merged
merged 2 commits into from
Jan 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
205 changes: 79 additions & 126 deletions packages/babel-parser/src/tokenizer/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,216 +6,169 @@ import { Position } from "../util/location";

import { types as ct, type TokContext } from "./context";
import type { Token } from "./index";
import { types as tt, type TokenType, type TopicContextState } from "./types";
import { types as tt, type TokenType } from "./types";

export default class State {
init(options: Options, input: string): void {
this.strict =
options.strictMode === false ? false : options.sourceType === "module";

this.input = input;

this.commaAfterSpreadAt = -1;
type TopicContextState = {
// When a topic binding has been currently established,
// then this is 1. Otherwise, it is 0. This is forwards compatible
// with a future plugin for multiple lexical topics.
maxNumOfResolvableTopics: number,

this.potentialArrowAt = -1;
// When a topic binding has been currently established, and if that binding
// has been used as a topic reference `#`, then this is 0. Otherwise, it is
// `null`. This is forwards compatible with a future plugin for multiple
// lexical topics.
maxTopicIndex: null | 0,
};

this.noArrowAt = [];
this.noArrowParamsConversionAt = [];

this.inMethod = false;
this.inFunction = false;
this.inParameters = false;
this.maybeInArrowParameters = false;
this.inGenerator = false;
this.inAsync = false;
this.inPipeline = false;
this.inPropertyName = false;
this.inType = false;
this.inClassProperty = false;
this.noAnonFunctionType = false;
this.hasFlowComment = false;
this.isIterator = false;

// Used by smartPipelines.
this.topicContext = {
maxNumOfResolvableTopics: 0,
maxTopicIndex: null,
};

this.classLevel = 0;

this.labels = [];

this.decoratorStack = [[]];
export default class State {
strict: boolean;
input: string;

this.yieldOrAwaitInPossibleArrowParameters = null;
curLine: number;

this.tokens = [];
// And, if locations are used, the {line, column} object
// corresponding to those offsets
startLoc: Position;
endLoc: Position;

this.comments = [];
init(options: Options, input: string): void {
this.strict =
options.strictMode === false ? false : options.sourceType === "module";

this.trailingComments = [];
this.leadingComments = [];
this.commentStack = [];
// $FlowIgnore
this.commentPreviousNode = null;
this.input = input;

this.pos = this.lineStart = 0;
this.curLine = options.startLine;

this.type = tt.eof;
this.value = null;
this.start = this.end = this.pos;
this.startLoc = this.endLoc = this.curPosition();

// $FlowIgnore
this.lastTokEndLoc = this.lastTokStartLoc = null;
this.lastTokStart = this.lastTokEnd = this.pos;

this.context = [ct.braceStatement];
this.exprAllowed = true;

this.containsEsc = this.containsOctal = false;
this.octalPosition = null;

this.invalidTemplateEscapePosition = null;

this.exportedIdentifiers = [];
}

// TODO
strict: boolean;

// TODO
input: string;

// A comma after "...a" is only allowed in spread, but not in rest.
// Since we parse destructuring patterns as array/object literals
// and then convert them, we need to track it.
commaAfterSpreadAt: number;

// Used to signify the start of a potential arrow function
potentialArrowAt: number;
potentialArrowAt: number = -1;

// Used to signify the start of an expression which looks like a
// typed arrow function, but it isn't
// e.g. a ? (b) : c => d
// ^
noArrowAt: number[];
noArrowAt: number[] = [];

// Used to signify the start of an expression whose params, if it looks like
// an arrow function, shouldn't be converted to assignable nodes.
// This is used to defer the validation of typed arrow functions inside
// conditional expressions.
// e.g. a ? (b) : c => d
// ^
noArrowParamsConversionAt: number[];
noArrowParamsConversionAt: number[] = [];

// A comma after "...a" is only allowed in spread, but not in rest.
// Since we parse destructuring patterns as array/object literals
// and then convert them, we need to track it.
commaAfterSpreadAt: number = -1;

// Flags to track whether we are in a function, a generator.
inFunction: boolean;
inParameters: boolean;
maybeInArrowParameters: boolean;
inGenerator: boolean;
inMethod: boolean | N.MethodKind;
inAsync: boolean;
inPipeline: boolean;
inType: boolean;
noAnonFunctionType: boolean;
inPropertyName: boolean;
inClassProperty: boolean;
hasFlowComment: boolean;
isIterator: boolean;
inFunction: boolean = false;
inParameters: boolean = false;
maybeInArrowParameters: boolean = false;
inGenerator: boolean = false;
inMethod: boolean | N.MethodKind = false;
inAsync: boolean = false;
inPipeline: boolean = false;
inType: boolean = false;
noAnonFunctionType: boolean = false;
inPropertyName: boolean = false;
inClassProperty: boolean = false;
hasFlowComment: boolean = false;
isIterator: boolean = false;

// For the smartPipelines plugin:
topicContext: TopicContextState;
topicContext: TopicContextState = {
maxNumOfResolvableTopics: 0,
maxTopicIndex: null,
};

// Check whether we are in a (nested) class or not.
classLevel: number;
classLevel: number = 0;

// Labels in scope.
labels: Array<{
kind: ?("loop" | "switch"),
name?: ?string,
statementStart?: number,
}>;
}> = [];

// Leading decorators. Last element of the stack represents the decorators in current context.
// Supports nesting of decorators, e.g. @foo(@bar class inner {}) class outer {}
// where @foo belongs to the outer class and @bar to the inner
decoratorStack: Array<Array<N.Decorator>>;
decoratorStack: Array<Array<N.Decorator>> = [[]];

// The first yield or await expression inside parenthesized expressions
// and arrow function parameters. It is used to disallow yield and await in
// arrow function parameters.
yieldOrAwaitInPossibleArrowParameters:
| N.YieldExpression
| N.AwaitExpression
| null;
| null = null;

// Token store.
tokens: Array<Token | N.Comment>;
tokens: Array<Token | N.Comment> = [];

// Comment store.
comments: Array<N.Comment>;
comments: Array<N.Comment> = [];

// Comment attachment store
trailingComments: Array<N.Comment>;
leadingComments: Array<N.Comment>;
trailingComments: Array<N.Comment> = [];
leadingComments: Array<N.Comment> = [];
commentStack: Array<{
start: number,
leadingComments: ?Array<N.Comment>,
trailingComments: ?Array<N.Comment>,
type: string,
}>;
commentPreviousNode: N.Node;
}> = [];
// $FlowIgnore this is initialized when the parser starts.
commentPreviousNode: N.Node = null;

// The current position of the tokenizer in the input.
pos: number;
lineStart: number;
curLine: number;
pos: number = 0;
lineStart: number = 0;

// Properties of the current token:
// Its type
type: TokenType;
type: TokenType = tt.eof;

// For tokens that include more information than their type, the value
value: any;
value: any = null;

// Its start and end offset
start: number;
end: number;

// And, if locations are used, the {line, column} object
// corresponding to those offsets
startLoc: Position;
endLoc: Position;
start: number = 0;
end: number = 0;

// Position information for the previous token
lastTokEndLoc: Position;
lastTokStartLoc: Position;
lastTokStart: number;
lastTokEnd: number;
// $FlowIgnore this is initialized when generating the second token.
lastTokEndLoc: Position = null;
// $FlowIgnore this is initialized when generating the second token.
lastTokStartLoc: Position = null;
lastTokStart: number = 0;
lastTokEnd: number = 0;

// The context stack is used to superficially track syntactic
// context to predict whether a regular expression is allowed in a
// given position.
context: Array<TokContext>;
exprAllowed: boolean;
context: Array<TokContext> = [ct.braceStatement];
exprAllowed: boolean = true;

// Used to signal to callers of `readWord1` whether the word
// contained any escape sequences. This is needed because words with
// escape sequences must not be interpreted as keywords.
containsEsc: boolean;
containsEsc: boolean = false;

// TODO
containsOctal: boolean;
octalPosition: ?number;
containsOctal: boolean = false;
octalPosition: ?number = null;

// Names of exports store. `default` is stored as a name for both
// `export default foo;` and `export { foo as default };`.
exportedIdentifiers: Array<string>;
exportedIdentifiers: Array<string> = [];

invalidTemplateEscapePosition: ?number;
invalidTemplateEscapePosition: ?number = null;

curPosition(): Position {
return new Position(this.curLine, this.pos - this.lineStart);
Expand Down
14 changes: 0 additions & 14 deletions packages/babel-parser/src/tokenizer/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,17 +198,3 @@ export const keywords = {
Object.keys(keywords).forEach(name => {
types["_" + name] = keywords[name];
});

// A type for the smartPipelines plugin.
export type TopicContextState = {
// When a topic binding has been currently established,
// then this is 1. Otherwise, it is 0. This is forwards compatible
// with a future plugin for multiple lexical topics.
maxNumOfResolvableTopics: number,

// When a topic binding has been currently established, and if that binding
// has been used as a topic reference `#`, then this is 0. Otherwise, it is
// `null`. This is forwards compatible with a future plugin for multiple
// lexical topics.
maxTopicIndex: null | 0,
};