mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-02 18:11:04 +08:00
Fix optional params in bridges function types
This fixes a bug where parameters in Closure functions weren't given the right combo of non-nullable plus optional tokens. Fixed: 1126338 Change-Id: I2be2db38bec3dbf278a4bff208dc057447c6ed81 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2401016 Commit-Queue: Simon Zünd <szuend@chromium.org> Reviewed-by: Simon Zünd <szuend@chromium.org> Auto-Submit: Jack Franklin <jacktfranklin@chromium.org>
This commit is contained in:
committed by
Commit Bot
parent
91dfe934c7
commit
cfd5020c0c
@@ -17,7 +17,7 @@ import './ComputedStyleProperty.js';
|
||||
* inherited:boolean,
|
||||
* traceable:boolean,
|
||||
* expanded:boolean,
|
||||
* onNavigateToSource:function(Event):void,
|
||||
* onNavigateToSource:function(!Event=):void,
|
||||
* }}
|
||||
*/
|
||||
// @ts-ignore we export this for Closure not TS
|
||||
|
||||
@@ -14,7 +14,7 @@ import './ComputedStyleTrace.js';
|
||||
* @typedef {{
|
||||
* selector:string,
|
||||
* active:boolean,
|
||||
* onNavigateToSource:function(Event):void,
|
||||
* onNavigateToSource:function(!Event=):void,
|
||||
* }}
|
||||
*/
|
||||
// @ts-ignore we export this for Closure not TS
|
||||
|
||||
@@ -92,7 +92,7 @@ const createTraceElement = (node, property, isPropertyOverloaded, matchedStyles,
|
||||
trace.data = {
|
||||
selector: rule ? rule.selectorText() : 'element.style',
|
||||
active: !isPropertyOverloaded,
|
||||
onNavigateToSource: /** @type {function(?Event):void} */ (navigateToSource.bind(null, property)),
|
||||
onNavigateToSource: /** @type {function(!Event=):void} */ (navigateToSource.bind(null, property)),
|
||||
};
|
||||
|
||||
return trace;
|
||||
@@ -376,7 +376,7 @@ export class ComputedStyleWidget extends UI.ThrottledWidget.ThrottledWidget {
|
||||
const propertyElement = createPropertyElement(node, propertyName, propertyValue);
|
||||
|
||||
const trace = propertyTraces.get(propertyName);
|
||||
/** @type {function(?Event):void} */
|
||||
/** @type {function(!Event=):void} */
|
||||
let navigate = () => {};
|
||||
if (trace) {
|
||||
const traceContainer = document.createElement('div');
|
||||
@@ -390,7 +390,7 @@ export class ComputedStyleWidget extends UI.ThrottledWidget.ThrottledWidget {
|
||||
'contextmenu',
|
||||
this._handleContextMenuEvent.bind(
|
||||
this, /** @type {!SDK.CSSMatchedStyles.CSSMatchedStyles} */ (matchedStyles), activeProperty));
|
||||
navigate = /** @type {function(?Event):void} */ (navigateToSource.bind(this, activeProperty));
|
||||
navigate = /** @type {function(!Event=):void} */ (navigateToSource.bind(this, activeProperty));
|
||||
propertyElement.appendChild(traceContainer);
|
||||
propertyElement.addEventListener('traces-toggled', this._onTracesToggled.bind(this));
|
||||
}
|
||||
@@ -467,7 +467,7 @@ export class ComputedStyleWidget extends UI.ThrottledWidget.ThrottledWidget {
|
||||
const propertyElement = createPropertyElement(node, propertyName, propertyValue);
|
||||
|
||||
const trace = propertyTraces.get(propertyName);
|
||||
/** @type {function(?Event):void} */
|
||||
/** @type {function(!Event=):void} */
|
||||
let navigate = () => {};
|
||||
if (trace) {
|
||||
const traceContainer = document.createElement('div');
|
||||
@@ -478,7 +478,7 @@ export class ComputedStyleWidget extends UI.ThrottledWidget.ThrottledWidget {
|
||||
'contextmenu',
|
||||
this._handleContextMenuEvent.bind(
|
||||
this, /** @type {!SDK.CSSMatchedStyles.CSSMatchedStyles} */ (matchedStyles), activeProperty));
|
||||
navigate = /** @type {function(?Event):void} */ (navigateToSource.bind(this, activeProperty));
|
||||
navigate = /** @type {function(!Event=):void} */ (navigateToSource.bind(this, activeProperty));
|
||||
propertyElement.appendChild(traceContainer);
|
||||
propertyElement.addEventListener('traces-toggled', this._onTracesToggled.bind(this));
|
||||
}
|
||||
|
||||
@@ -128,7 +128,22 @@ export const valueForTypeNode = (node: ts.TypeNode, isFunctionParam: boolean = f
|
||||
if (!param.type) {
|
||||
return '';
|
||||
}
|
||||
return valueForTypeNode(param.type);
|
||||
|
||||
const valueForParam = valueForTypeNode(param.type, true);
|
||||
|
||||
if (nodeIsPrimitive(param.type)) {
|
||||
// A primitive never has a ! at the start, but does have a = at the end if it's optional.
|
||||
return param.questionToken ? `${valueForParam}=` : valueForParam;
|
||||
}
|
||||
|
||||
// If it's not a primitive, it's a type ref and needs a
|
||||
// non-nullable ! at the start and a = at the end if
|
||||
// it's optional.
|
||||
return [
|
||||
'!',
|
||||
valueForTypeNode(param.type, true),
|
||||
param.questionToken ? '=' : '',
|
||||
].join('');
|
||||
})
|
||||
.join(', ');
|
||||
|
||||
|
||||
@@ -237,5 +237,39 @@ describe('valueForTypeNode', () => {
|
||||
const node = ts.createFunctionTypeNode([], [stringParam], returnUnionNode);
|
||||
assert.strictEqual(valueForTypeNode(node), 'function(string):(string|undefined)');
|
||||
});
|
||||
|
||||
it('correctly deals with optional type reference parameters', () => {
|
||||
const stringNode = createNode(ts.SyntaxKind.StringKeyword);
|
||||
const typeReferenceNode = ts.createTypeReferenceNode(ts.createIdentifier('ExampleInterface'), []);
|
||||
const functionParam = ts.createParameter(
|
||||
[], [], undefined, ts.createIdentifier('foo'), ts.createToken(ts.SyntaxKind.QuestionToken),
|
||||
typeReferenceNode);
|
||||
|
||||
// function(foo?: ExampleInterface):string
|
||||
const node = ts.createFunctionTypeNode([], [functionParam], stringNode);
|
||||
assert.strictEqual(valueForTypeNode(node), 'function(!ExampleInterface=):string');
|
||||
});
|
||||
|
||||
it('correctly deals with required type reference parameters', () => {
|
||||
const stringNode = createNode(ts.SyntaxKind.StringKeyword);
|
||||
const typeReferenceNode = ts.createTypeReferenceNode(ts.createIdentifier('ExampleInterface'), []);
|
||||
const functionParam =
|
||||
ts.createParameter([], [], undefined, ts.createIdentifier('foo'), undefined, typeReferenceNode);
|
||||
|
||||
// function(foo: ExampleInterface):string
|
||||
const node = ts.createFunctionTypeNode([], [functionParam], stringNode);
|
||||
assert.strictEqual(valueForTypeNode(node), 'function(!ExampleInterface):string');
|
||||
});
|
||||
|
||||
it('correctly deals with optional primitive parameters', () => {
|
||||
const returnTypeNode = createNode(ts.SyntaxKind.StringKeyword);
|
||||
const stringParam = ts.createParameter(
|
||||
[], [], undefined, ts.createIdentifier('foo'), ts.createToken(ts.SyntaxKind.QuestionToken),
|
||||
createNode(ts.SyntaxKind.StringKeyword));
|
||||
const node = ts.createFunctionTypeNode([], [stringParam], returnTypeNode);
|
||||
|
||||
// function(foo?: string):string
|
||||
assert.strictEqual(valueForTypeNode(node), 'function(string=):string');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user