Fix up flow errors (#7227)

* 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
This commit is contained in:
Brian Ng 2018-02-25 20:12:33 -06:00 committed by Logan Smyth
parent 6f3be3a543
commit 8823e4247e
12 changed files with 36 additions and 21 deletions

View File

@ -13,8 +13,8 @@ codemods/*/src
[libs] [libs]
lib/file.js lib/file.js
lib/parser.js lib/parser.js
lib/packages/babel-types/lib/index.js.flow
lib/third-party-libs.js.flow lib/third-party-libs.js.flow
packages/babel-types/lib/index.js.flow
[options] [options]
include_warnings=true include_warnings=true

View File

@ -26,7 +26,7 @@
"bundle-collapser": "^1.2.1", "bundle-collapser": "^1.2.1",
"chai": "^4.1.0", "chai": "^4.1.0",
"chalk": "^2.0.0", "chalk": "^2.0.0",
"charcodes": "0.0.10", "charcodes": "0.1.0",
"derequire": "^2.0.2", "derequire": "^2.0.2",
"eslint": "^4.5.0", "eslint": "^4.5.0",
"eslint-config-babel": "^7.0.2", "eslint-config-babel": "^7.0.2",

View File

@ -12,7 +12,7 @@ function makeStatementFormatter<T>(
return { return {
// We need to prepend a ";" to force statement parsing so that // We need to prepend a ";" to force statement parsing so that
// ExpressionStatement strings won't be parsed as directives. // ExpressionStatement strings won't be parsed as directives.
// Alonside that, we also prepend a comment so that when a syntax error // Alongside that, we also prepend a comment so that when a syntax error
// is encountered, the user will be less likely to get confused about // is encountered, the user will be less likely to get confused about
// where the random semicolon came from. // where the random semicolon came from.
code: str => `/* @babel/template */;\n${str}`, code: str => `/* @babel/template */;\n${str}`,
@ -54,16 +54,17 @@ export const statement: Formatter<BabelNodeStatement> = makeStatementFormatter(
export const expression: Formatter<BabelNodeExpression> = { export const expression: Formatter<BabelNodeExpression> = {
code: str => `(\n${str}\n)`, code: str => `(\n${str}\n)`,
validate: (ast: BabelNodeFile) => { validate: ({ program }) => {
const { program } = ast;
if (program.body.length > 1) { if (program.body.length > 1) {
throw new Error("Found multiple statements but wanted one"); throw new Error("Found multiple statements but wanted one");
} }
// $FlowFixMe
const expression = program.body[0].expression; const expression = program.body[0].expression;
if (expression.start === 0) { if (expression.start === 0) {
throw new Error("Parse result included parens."); throw new Error("Parse result included parens.");
} }
}, },
// $FlowFixMe
unwrap: ast => ast.program.body[0].expression, unwrap: ast => ast.program.body[0].expression,
}; };

View File

@ -21,10 +21,10 @@ function getType(val) {
} }
// TODO: Import and use Node instead of any // TODO: Import and use Node instead of any
opaque type Validator = (any, string, any) => void; type Validator = (any, string, any) => void;
type FieldOptions = { type FieldOptions = {
default?: boolean, default?: any,
optional?: boolean, optional?: boolean,
validate?: Validator, validate?: Validator,
}; };

View File

@ -24,7 +24,7 @@
}, },
"devDependencies": { "devDependencies": {
"@babel/helper-fixtures": "7.0.0-beta.40", "@babel/helper-fixtures": "7.0.0-beta.40",
"charcodes": "0.0.10", "charcodes": "0.1.0",
"unicode-10.0.0": "^0.7.4" "unicode-10.0.0": "^0.7.4"
}, },
"bin": { "bin": {

View File

@ -426,7 +426,10 @@ export default class ExpressionParser extends LValParser {
startLoc: Position, startLoc: Position,
noCalls?: ?boolean, noCalls?: ?boolean,
): N.Expression { ): N.Expression {
const state = { stop: false }; const state = {
optionalChainMember: false,
stop: false,
};
do { do {
base = this.parseSubscript(base, startPos, startLoc, noCalls, state); base = this.parseSubscript(base, startPos, startLoc, noCalls, state);
} while (!state.stop); } while (!state.stop);
@ -439,7 +442,7 @@ export default class ExpressionParser extends LValParser {
startPos: number, startPos: number,
startLoc: Position, startLoc: Position,
noCalls: ?boolean, noCalls: ?boolean,
state: { stop: boolean, optionalChainMember?: boolean }, state: N.ParseSubscriptState,
): N.Expression { ): N.Expression {
if (!noCalls && this.eat(tt.doubleColon)) { if (!noCalls && this.eat(tt.doubleColon)) {
const node = this.startNodeAt(startPos, startLoc); const node = this.startNodeAt(startPos, startLoc);
@ -554,14 +557,13 @@ export default class ExpressionParser extends LValParser {
const node = this.startNodeAt(startPos, startLoc); const node = this.startNodeAt(startPos, startLoc);
node.tag = base; node.tag = base;
node.quasi = this.parseTemplate(true); node.quasi = this.parseTemplate(true);
if (!state.optionalChainMember) { if (state.optionalChainMember) {
return this.finishNode(node, "TaggedTemplateExpression");
} else {
this.raise( this.raise(
startPos, startPos,
"Tagged Template Literals are not allowed in optionalChain", "Tagged Template Literals are not allowed in optionalChain",
); );
} }
return this.finishNode(node, "TaggedTemplateExpression");
} else { } else {
state.stop = true; state.stop = true;
return base; return base;

View File

@ -1632,7 +1632,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
return this.finishOp(tt.relational, 1); return this.finishOp(tt.relational, 1);
} else if (isIteratorStart(code, next)) { } else if (isIteratorStart(code, next)) {
this.state.isIterator = true; this.state.isIterator = true;
return super.readWord(code); return super.readWord();
} else { } else {
return super.readToken(code); return super.readToken(code);
} }

View File

@ -886,7 +886,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
} }
} }
tsEatThenParseType(token: TokenType): N.TsType | undefined { tsEatThenParseType(token: TokenType): N.TsType | typeof undefined {
return !this.match(token) ? undefined : this.tsNextThenParseType(); return !this.match(token) ? undefined : this.tsNextThenParseType();
} }
@ -1326,7 +1326,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
startPos: number, startPos: number,
startLoc: Position, startLoc: Position,
noCalls: ?boolean, noCalls: ?boolean,
state: { stop: boolean }, state: N.ParseSubscriptState,
): N.Expression { ): N.Expression {
if (!this.hasPrecedingLineBreak() && this.eat(tt.bang)) { if (!this.hasPrecedingLineBreak() && this.eat(tt.bang)) {
const nonNullExpression: N.TsNonNullExpression = this.startNodeAt( const nonNullExpression: N.TsNonNullExpression = this.startNodeAt(

View File

@ -467,6 +467,7 @@ export default class Tokenizer extends LocationParser {
const assign = const assign =
this.input.charCodeAt(this.state.pos + 2) === charCodes.equalsTo; this.input.charCodeAt(this.state.pos + 2) === charCodes.equalsTo;
if (assign) { if (assign) {
// $FlowFixMe
this.expectPlugin("logicalAssignment"); this.expectPlugin("logicalAssignment");
} }
this.finishOp( this.finishOp(
@ -1280,7 +1281,7 @@ export default class Tokenizer extends LocationParser {
return word + this.input.slice(chunkStart, this.state.pos); return word + this.input.slice(chunkStart, this.state.pos);
} }
isIterator(word): boolean { isIterator(word: string): boolean {
return word === "@@iterator" || word === "@@asyncIterator"; return word === "@@iterator" || word === "@@asyncIterator";
} }

View File

@ -21,7 +21,7 @@ export default class State {
this.noArrowParamsConversionAt = []; this.noArrowParamsConversionAt = [];
// eslint-disable-next-line max-len // 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 = false; 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.classLevel = 0;
@ -98,6 +98,8 @@ export default class State {
noAnonFunctionType: boolean; noAnonFunctionType: boolean;
inPropertyName: boolean; inPropertyName: boolean;
inClassProperty: boolean; inClassProperty: boolean;
hasFlowComment: boolean;
isIterator: boolean;
// Check whether we are in a (nested) class or not. // Check whether we are in a (nested) class or not.
classLevel: number; classLevel: number;

View File

@ -1315,3 +1315,12 @@ export type TsNonNullExpression = NodeBase & {
type: "TSNonNullExpression", type: "TSNonNullExpression",
expression: Expression, expression: Expression,
}; };
// ================
// Other
// ================
export type ParseSubscriptState = {
optionalChainMember: boolean,
stop: boolean,
};

View File

@ -1671,9 +1671,9 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0:
escape-string-regexp "^1.0.5" escape-string-regexp "^1.0.5"
supports-color "^4.0.0" supports-color "^4.0.0"
charcodes@0.0.10: charcodes@0.1.0:
version "0.0.10" version "0.1.0"
resolved "https://registry.yarnpkg.com/charcodes/-/charcodes-0.0.10.tgz#98d67a7a1e17ce154d1faafd01e72e9a6cff54f5" resolved "https://registry.yarnpkg.com/charcodes/-/charcodes-0.1.0.tgz#61f8c244fc7f94f186fe74f31078901a3ed7928e"
chardet@^0.4.0: chardet@^0.4.0:
version "0.4.2" version "0.4.2"