Skip to content

Commit f07edd4

Browse files
committed
Upgrade Flow to 0.153.0
https://github.com/facebook/flow/releases/tag/v0.153.0 Most of the fixes are related to the ban on method unbinding. In other areas I've fixed or improved cases of our object types being wonky, particularly in the expand2 code. I've tried to isolate cases where we use a "VarArgsClass" from cases where we use a plain object to avoid conflicts there.
1 parent 4afce85 commit f07edd4

19 files changed

+145
-84
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
"eslint-plugin-react": "7.20.6",
8181
"eslint-plugin-react-hooks": "4.1.2",
8282
"file-url": "2.0.2",
83-
"flow-bin": "0.152.0",
83+
"flow-bin": "0.153.0",
8484
"gettext-parser": "3.1.0",
8585
"http-proxy": "1.18.1",
8686
"jsdom": "13.2.0",

root/layout/components/ExternalLinks.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,8 @@ const ExternalLinks = ({
144144
));
145145

146146
// We ensure official sites are listed above blogs, and blogs above others
147-
links.push.apply(links, blogLinks);
148-
links.push.apply(links, uniqueOtherLinks.map(({id, ...props}) => (
147+
links.push(...blogLinks);
148+
links.push(...uniqueOtherLinks.map(({id, ...props}) => (
149149
<ExternalLink key={id} {...props} />
150150
)));
151151

root/server/gettext.js

+19-8
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,26 @@ exports.loadDomain = function (domain /*: string */) {
5252
};
5353

5454
exports.jedInstance = jedInstance;
55+
5556
exports.dgettext = (
56-
jedInstance.dgettext.bind(jedInstance)
57-
/*: ((string, string) => string) */
58-
);
57+
domain/*: string */,
58+
key/*: string */,
59+
)/*: string */ => jedInstance.dgettext(domain, key);
60+
5961
exports.dngettext = (
60-
jedInstance.dngettext.bind(jedInstance)
61-
/*: ((string, string, string, number) => string) */
62+
domain/*: string */,
63+
singularKey/*: string */,
64+
pluralKey/*: string */,
65+
value/*: number */,
66+
)/*: string */ => jedInstance.dngettext(
67+
domain,
68+
singularKey,
69+
pluralKey,
70+
value,
6271
);
72+
6373
exports.dpgettext = (
64-
jedInstance.dpgettext.bind(jedInstance)
65-
/*: ((string, string, string) => string) */
66-
);
74+
domain/*: string */,
75+
context/*: string */,
76+
key/*: string */,
77+
)/*: string */ => jedInstance.dpgettext(domain, context, key);

root/static/scripts/common/components/TagEditor.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ export const MainTagEditor = (hydrate<TagEditorProps>(
554554
</p>
555555
)}
556556
<p>
557-
<a href="#" onClick={this.showAllTags.bind(this)}>
557+
<a href="#" onClick={(event) => this.showAllTags(event)}>
558558
{l('Show all tags.')}
559559
</a>
560560
</p>
@@ -568,7 +568,10 @@ export const MainTagEditor = (hydrate<TagEditorProps>(
568568
</p>
569569
{this.props.$c.user?.has_confirmed_email_address ? (
570570
<p>
571-
<a href="#" onClick={this.hideNegativeTags.bind(this)}>
571+
<a
572+
href="#"
573+
onClick={(event) => this.hideNegativeTags(event)}
574+
>
572575
{l(
573576
`Hide tags with a score of zero or below,
574577
and tags that you’ve downvoted.`,
@@ -577,7 +580,10 @@ export const MainTagEditor = (hydrate<TagEditorProps>(
577580
</p>
578581
) : (
579582
<p>
580-
<a href="#" onClick={this.hideNegativeTags.bind(this)}>
583+
<a
584+
href="#"
585+
onClick={(event) => this.hideNegativeTags(event)}
586+
>
581587
{l('Hide tags with a score of zero or below.')}
582588
</a>
583589
</p>

root/static/scripts/common/i18n/expand2.js

+25-23
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,15 @@ export function gotMatch(x: mixed): boolean %checks {
3232
}
3333

3434
export type VarArgsObject<+T> = {
35-
__proto__: empty,
3635
+[arg: string]: T,
37-
...
3836
};
3937

40-
export class VarArgs<+T, +U = T> {
38+
export interface VarArgsClass<+T> {
39+
get(name: string): T,
40+
has(name: string): boolean,
41+
}
42+
43+
export class VarArgs<+T, +U = T> implements VarArgsClass<T | U> {
4144
+data: VarArgsObject<T>;
4245

4346
constructor(data: VarArgsObject<T>) {
@@ -53,9 +56,10 @@ export class VarArgs<+T, +U = T> {
5356
}
5457
}
5558

56-
export type Parser<+T, -V> = (VarArgs<V>) => T;
59+
export type Parser<+T, -V> = (VarArgsClass<V>) => T;
5760

5861
const EMPTY_OBJECT = Object.freeze({});
62+
const EMPTY_VARARGS = new VarArgs(EMPTY_OBJECT);
5963

6064
type State = {
6165
/*
@@ -140,7 +144,7 @@ export function saveMatch<T, V>(cb: Parser<T, V>): Parser<T, V> {
140144

141145
export function parseContinuous<T, U, V>(
142146
parsers: $ReadOnlyArray<Parser<T | NO_MATCH, V>>,
143-
args: VarArgs<V>,
147+
args: VarArgsClass<V>,
144148
matchCallback: (U | NO_MATCH, T) => U,
145149
defaultValue: U,
146150
): U {
@@ -178,7 +182,7 @@ function concatStringMatch(
178182

179183
export function parseContinuousString<V>(
180184
parsers: $ReadOnlyArray<Parser<string | NO_MATCH, V>>,
181-
args: VarArgs<V>,
185+
args: VarArgsClass<V>,
182186
): string {
183187
return parseContinuous<string, string, V>(
184188
parsers,
@@ -202,16 +206,18 @@ export const createTextContentParser = <+T, V>(
202206
const varSubst = /^\{([0-9A-z_]+)\}/;
203207
export const createVarSubstParser = <T, V>(
204208
argFilter: (V) => T,
205-
): Parser<T | string | NO_MATCH, V> => saveMatch(function (args: VarArgs<V>) {
206-
const name = accept(varSubst);
207-
if (typeof name !== 'string') {
208-
return NO_MATCH_VALUE;
209-
}
210-
if (args.has(name)) {
211-
return argFilter(args.get(name));
212-
}
213-
return state.match;
214-
});
209+
): Parser<T | string | NO_MATCH, V> => saveMatch(
210+
function (args: VarArgsClass<V>) {
211+
const name = accept(varSubst);
212+
if (typeof name !== 'string') {
213+
return NO_MATCH_VALUE;
214+
}
215+
if (args.has(name)) {
216+
return argFilter(args.get(name));
217+
}
218+
return state.match;
219+
},
220+
);
215221

216222
export const parseStringVarSubst: Parser<string | NO_MATCH, mixed> =
217223
createVarSubstParser<string, mixed>(getString);
@@ -271,9 +277,9 @@ export const createCondSubstParser = <T, V>(
271277
* and input arg values.
272278
*/
273279
export default function expand<+T, V>(
274-
rootParser: (VarArgs<V>) => T,
280+
rootParser: (VarArgsClass<V>) => T,
275281
source: ?string,
276-
args: ?(VarArgsObject<V> | VarArgs<V>),
282+
args: ?VarArgsClass<V>,
277283
): T | string {
278284
if (!source) {
279285
return '';
@@ -292,13 +298,9 @@ export default function expand<+T, V>(
292298
state.running = true;
293299
state.source = source;
294300

295-
if (!(args instanceof VarArgs)) {
296-
args = new VarArgs<V>(args ?? EMPTY_OBJECT);
297-
}
298-
299301
let result;
300302
try {
301-
result = rootParser(args);
303+
result = rootParser(args ?? EMPTY_VARARGS);
302304

303305
if (state.remainder) {
304306
throw error('unexpected token');

root/static/scripts/common/i18n/expand2html.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99

1010
import * as ReactDOMServer from 'react-dom/server';
1111

12+
import type {VarArgsObject} from './expand2';
1213
import expand2react from './expand2react';
1314

1415
export default function expand2html(
1516
source: string,
16-
args?: ?{+[arg: string]: Expand2ReactInput},
17+
args?: ?VarArgsObject<Expand2ReactInput>,
1718
): string {
1819
return ReactDOMServer.renderToStaticMarkup(
1920
expand2react(source, args),

root/static/scripts/common/i18n/expand2react.js

+18-6
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ import expand, {
3131
saveMatch,
3232
state,
3333
substEnd,
34+
VarArgs,
3435
type NO_MATCH,
3536
type Parser,
36-
type VarArgs,
37+
type VarArgsObject,
38+
type VarArgsClass,
3739
} from './expand2';
3840

3941
type Input = Expand2ReactInput;
@@ -181,7 +183,7 @@ function concatArrayMatch<T: MatchUpperBoundT>(
181183

182184
function parseContinuousArray<T: MatchUpperBoundT, V>(
183185
parsers: $ReadOnlyArray<Parser<Array<T> | T | NO_MATCH, V>>,
184-
args: VarArgs<V>,
186+
args: VarArgsClass<V>,
185187
): Array<T> {
186188
return parseContinuous<Array<T> | T, Array<T>, V>(
187189
parsers,
@@ -363,7 +365,17 @@ const parseRoot = args => parseContinuousArray(rootParsers, args);
363365
*/
364366
export default function expand2react(
365367
source: string,
366-
args?: ?{+[arg: string]: Input, ...},
368+
args?: ?VarArgsObject<Input>,
369+
): Output {
370+
return expand2reactWithVarArgsInstance(
371+
source,
372+
args ? new VarArgs(args) : null,
373+
);
374+
}
375+
376+
export function expand2reactWithVarArgsInstance(
377+
source: string,
378+
args?: ?VarArgsClass<Input>,
367379
): Output {
368380
const result = expand<$ReadOnlyArray<Output>, Input>(
369381
parseRoot,
@@ -382,18 +394,18 @@ export default function expand2react(
382394

383395
export const l = (
384396
key: string,
385-
args?: ?{+[arg: string]: Input, ...},
397+
args?: ?VarArgsObject<Input>,
386398
): Output => expand2react(lActual(key), args);
387399

388400
export const ln = (
389401
skey: string,
390402
pkey: string,
391403
val: number,
392-
args?: ?{+[arg: string]: Input, ...},
404+
args?: ?VarArgsObject<Input>,
393405
): Output => expand2react(lnActual(skey, pkey, val), args);
394406

395407
export const lp = (
396408
key: string,
397409
context: string,
398-
args?: ?{+[arg: string]: Input, ...},
410+
args?: ?VarArgsObject<Input>,
399411
): Output => expand2react(lpActual(key, context), args);

root/static/scripts/common/i18n/expand2text.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ import expand, {
1313
parseContinuousString,
1414
parseStringVarSubst,
1515
state,
16+
VarArgs,
17+
type VarArgsObject,
18+
type VarArgsClass,
1619
} from './expand2';
1720
import {
1821
l as lActual,
@@ -80,25 +83,32 @@ function parseRoot(args) {
8083
*/
8184
export default function expand2text(
8285
source: string,
83-
args: {+[arg: string]: StrOrNum, ...},
86+
args: VarArgsObject<StrOrNum>,
87+
): string {
88+
return expand2textWithVarArgsClass(source, new VarArgs(args));
89+
}
90+
91+
export function expand2textWithVarArgsClass(
92+
source: string,
93+
args: VarArgsClass<StrOrNum>,
8494
): string {
8595
return expand<string, StrOrNum>(parseRoot, source, args);
8696
}
8797

8898
export const l = (
8999
key: string,
90-
args: {+[arg: string]: StrOrNum, ...},
100+
args: VarArgsObject<StrOrNum>,
91101
): string => expand2text(lActual(key), args);
92102

93103
export const ln = (
94104
skey: string,
95105
pkey: string,
96106
val: number,
97-
args: {+[arg: string]: StrOrNum, ...},
107+
args: VarArgsObject<StrOrNum>,
98108
): string => expand2text(lnActual(skey, pkey, val), args);
99109

100110
export const lp = (
101111
key: string,
102112
context: string,
103-
args: {+[arg: string]: StrOrNum, ...},
113+
args: VarArgsObject<StrOrNum>,
104114
): string => expand2text(lpActual(key, context), args);

root/static/scripts/common/linkedEntities.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ export type LinkedEntitiesT = {
9797
};
9898
*/
9999

100+
// $FlowIgnore[method-unbinding]
101+
const hasOwnProperty = Object.prototype.hasOwnProperty;
102+
100103
const EMPTY_OBJECT = Object.freeze({});
101104

102105
const linkedEntities/*: LinkedEntitiesT */ = Object.create(Object.seal({
@@ -121,7 +124,7 @@ const linkedEntities/*: LinkedEntitiesT */ = Object.create(Object.seal({
121124
mergeLinkedEntities(update/*: ?$Shape<LinkedEntitiesT> */) {
122125
if (update) {
123126
for (const [type, entities] of Object.entries(update)) {
124-
if (Object.prototype.hasOwnProperty.call(linkedEntities, type)) {
127+
if (hasOwnProperty.call(linkedEntities, type)) {
125128
Object.assign(linkedEntities[type], entities);
126129
} else {
127130
linkedEntities[type] = entities;

root/static/scripts/common/utility/cloneDeep.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ function cloneArrayDeep/*:: <+T> */(
5050
* This module is imported by our Webpack config file, so don't use
5151
* `hasOwnProp` here. It's not available!
5252
*/
53+
// $FlowIgnore[method-unbinding]
5354
const hasOwnProperty = Object.prototype.hasOwnProperty;
5455

5556
function _cloneObjectDeep/*:: <+T: {...}> */(
5657
object/*: T */,
5758
seen/*: WeakMap<any, any> */,
5859
)/*: T */ {
59-
const clone/*: any */ = {};
60-
Object.setPrototypeOf(clone, Object.getPrototypeOf(object));
60+
const clone/*: any */ = Object.create(Object.getPrototypeOf(object));
6161
seen.set(object, clone);
6262
for (const key in object) {
6363
if (hasOwnProperty.call(object, key)) {

root/static/scripts/common/utility/deepEqual.js

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
/* eslint-disable import/no-commonjs */
1414

1515
const objectPrototype = Object.prototype;
16+
// $FlowIgnore[method-unbinding]
1617
const hasOwnProperty = objectPrototype.hasOwnProperty;
1718

1819
function deepEqual(

root/static/scripts/common/utility/hasOwnProp.js

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* later version: http://www.gnu.org/licenses/gpl-2.0.txt
88
*/
99

10+
// $FlowIgnore[method-unbinding]
1011
const objectHasOwnProperty = Object.prototype.hasOwnProperty;
1112

1213
export default function hasOwnProp(

root/static/scripts/common/utility/parseCookie.js

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
const {parse} = require('cookie');
1818

19+
// $FlowIgnore[method-unbinding]
1920
const hasOwnProperty = Object.prototype.hasOwnProperty;
2021

2122
function parseCookie(

root/static/scripts/edit/components/edit/RelationshipDiff.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ import relationshipDateText
1414
import {INSERT, DELETE} from '../../utility/editDiff';
1515
import DescriptiveLink from '../../../common/components/DescriptiveLink';
1616
import commaList from '../../../common/i18n/commaList';
17-
import expand2react, {hooks as expand2reactHooks}
18-
from '../../../common/i18n/expand2react';
17+
import {
18+
expand2reactWithVarArgsInstance,
19+
hooks as expand2reactHooks,
20+
} from '../../../common/i18n/expand2react';
1921
import linkedEntities from '../../../common/linkedEntities';
2022
import {keyBy} from '../../../common/utility/arrays';
2123
import bracketed from '../../../common/utility/bracketed';
@@ -66,7 +68,7 @@ const RelationshipDiff = ({
6668

6769
return display;
6870
},
69-
expand: expand2react,
71+
expand: expand2reactWithVarArgsInstance,
7072
};
7173

7274
const oldLinkType = linkedEntities.link_type[oldRelationship.linkTypeID];

0 commit comments

Comments
 (0)