* charcodes@0.1.0 * Add hasFlowComment to tokenizer/state * Fix babel-types flow errors * Add isIterator to tokenizer/state * Remove unnecessary argument from flow/readToken * Add annotation to tokenizer/isIterator * Fix reference to generated index.js.flow * Add workaround in babel-template expression formatter * Fix tsEatThenParseType return type * Fix inconsistency with ParseSubscript state * Add workaround for flow handling error with tagged template in optional chain * Add flow workaround in expectPlugin inside tokenizer
204 lines
5.5 KiB
JavaScript
204 lines
5.5 KiB
JavaScript
// @flow
|
|
|
|
import type { Options } from "../options";
|
|
import * as N from "../types";
|
|
import { Position } from "../util/location";
|
|
|
|
import { types as ct, type TokContext } from "./context";
|
|
import type { Token } from "./index";
|
|
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.potentialArrowAt = -1;
|
|
|
|
this.noArrowAt = [];
|
|
this.noArrowParamsConversionAt = [];
|
|
|
|
// eslint-disable-next-line max-len
|
|
this.inMethod = this.inFunction = this.inParameters = this.maybeInArrowParameters = this.inGenerator = this.inAsync = this.inPropertyName = this.inType = this.inClassProperty = this.noAnonFunctionType = this.hasFlowComment = this.isIterator = false;
|
|
|
|
this.classLevel = 0;
|
|
|
|
this.labels = [];
|
|
|
|
this.decoratorStack = [[]];
|
|
|
|
this.yieldInPossibleArrowParameters = null;
|
|
|
|
this.tokens = [];
|
|
|
|
this.comments = [];
|
|
|
|
this.trailingComments = [];
|
|
this.leadingComments = [];
|
|
this.commentStack = [];
|
|
// $FlowIgnore
|
|
this.commentPreviousNode = null;
|
|
|
|
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;
|
|
|
|
// Used to signify the start of a potential arrow function
|
|
potentialArrowAt: number;
|
|
|
|
// 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[];
|
|
|
|
// 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[];
|
|
|
|
// 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;
|
|
inType: boolean;
|
|
noAnonFunctionType: boolean;
|
|
inPropertyName: boolean;
|
|
inClassProperty: boolean;
|
|
hasFlowComment: boolean;
|
|
isIterator: boolean;
|
|
|
|
// Check whether we are in a (nested) class or not.
|
|
classLevel: number;
|
|
|
|
// Labels in scope.
|
|
labels: Array<{ kind: ?("loop" | "switch"), 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>>;
|
|
|
|
// The first yield expression inside parenthesized expressions and arrow
|
|
// function parameters. It is used to disallow yield in arrow function
|
|
// parameters.
|
|
yieldInPossibleArrowParameters: ?N.YieldExpression;
|
|
|
|
// Token store.
|
|
tokens: Array<Token | N.Comment>;
|
|
|
|
// Comment store.
|
|
comments: Array<N.Comment>;
|
|
|
|
// Comment attachment store
|
|
trailingComments: Array<N.Comment>;
|
|
leadingComments: Array<N.Comment>;
|
|
commentStack: Array<{
|
|
start: number,
|
|
leadingComments: ?Array<N.Comment>,
|
|
trailingComments: ?Array<N.Comment>,
|
|
}>;
|
|
commentPreviousNode: N.Node;
|
|
|
|
// The current position of the tokenizer in the input.
|
|
pos: number;
|
|
lineStart: number;
|
|
curLine: number;
|
|
|
|
// Properties of the current token:
|
|
// Its type
|
|
type: TokenType;
|
|
|
|
// For tokens that include more information than their type, the value
|
|
value: any;
|
|
|
|
// 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;
|
|
|
|
// Position information for the previous token
|
|
lastTokEndLoc: Position;
|
|
lastTokStartLoc: Position;
|
|
lastTokStart: number;
|
|
lastTokEnd: number;
|
|
|
|
// 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;
|
|
|
|
// 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;
|
|
|
|
// TODO
|
|
containsOctal: boolean;
|
|
octalPosition: ?number;
|
|
|
|
// Names of exports store. `default` is stored as a name for both
|
|
// `export default foo;` and `export { foo as default };`.
|
|
exportedIdentifiers: Array<string>;
|
|
|
|
invalidTemplateEscapePosition: ?number;
|
|
|
|
curPosition(): Position {
|
|
return new Position(this.curLine, this.pos - this.lineStart);
|
|
}
|
|
|
|
clone(skipArrays?: boolean): State {
|
|
const state = new State();
|
|
Object.keys(this).forEach(key => {
|
|
// $FlowIgnore
|
|
let val = this[key];
|
|
|
|
if ((!skipArrays || key === "context") && Array.isArray(val)) {
|
|
val = val.slice();
|
|
}
|
|
|
|
// $FlowIgnore
|
|
state[key] = val;
|
|
});
|
|
return state;
|
|
}
|
|
}
|