mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-14 19:16:17 -06:00
More tests for super.method call chain, improve vary-by (#35013)
This commit is contained in:
parent
fce728e07f
commit
6c59dc34ac
@ -1412,10 +1412,65 @@ namespace Harness {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
function splitVaryBySettingValue(text: string): string[] | undefined {
|
||||
function splitVaryBySettingValue(text: string, varyBy: string): string[] | undefined {
|
||||
if (!text) return undefined;
|
||||
const entries = text.split(/,/).map(s => s.trim().toLowerCase()).filter(s => s.length > 0);
|
||||
return entries && entries.length > 1 ? entries : undefined;
|
||||
|
||||
let star = false;
|
||||
const includes: string[] = [];
|
||||
const excludes: string[] = [];
|
||||
for (let s of text.split(/,/g)) {
|
||||
s = s.trim().toLowerCase();
|
||||
if (s.length === 0) continue;
|
||||
if (s === "*") {
|
||||
star = true;
|
||||
}
|
||||
else if (ts.startsWith(s, "-") || ts.startsWith(s, "!")) {
|
||||
excludes.push(s.slice(1));
|
||||
}
|
||||
else {
|
||||
includes.push(s);
|
||||
}
|
||||
}
|
||||
|
||||
// do nothing if the setting has no variations
|
||||
if (includes.length <= 1 && !star && excludes.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const variations: { key: string, value?: string | number }[] = [];
|
||||
const values = getVaryByStarSettingValues(varyBy);
|
||||
|
||||
// add (and deduplicate) all included entries
|
||||
for (const include of includes) {
|
||||
const value = values?.get(include);
|
||||
if (ts.findIndex(variations, v => v.key === include || value !== undefined && v.value === value) === -1) {
|
||||
variations.push({ key: include, value });
|
||||
}
|
||||
}
|
||||
|
||||
if (star && values) {
|
||||
// add all entries
|
||||
for (const [key, value] of ts.arrayFrom(values.entries())) {
|
||||
if (ts.findIndex(variations, v => v.key === key || v.value === value) === -1) {
|
||||
variations.push({ key, value });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove all excluded entries
|
||||
for (const exclude of excludes) {
|
||||
const value = values?.get(exclude);
|
||||
let index: number;
|
||||
while ((index = ts.findIndex(variations, v => v.key === exclude || value !== undefined && v.value === value)) >= 0) {
|
||||
ts.orderedRemoveItemAt(variations, index);
|
||||
}
|
||||
}
|
||||
|
||||
if (variations.length === 0) {
|
||||
throw new Error(`Variations in test option '@${varyBy}' resulted in an empty set.`);
|
||||
}
|
||||
|
||||
return ts.map(variations, v => v.key);
|
||||
}
|
||||
|
||||
function computeFileBasedTestConfigurationVariations(configurations: FileBasedTestConfiguration[], variationState: FileBasedTestConfiguration, varyByEntries: [string, string[]][], offset: number) {
|
||||
@ -1433,17 +1488,37 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
let booleanVaryByStarSettingValues: ts.Map<string | number> | undefined;
|
||||
|
||||
function getVaryByStarSettingValues(varyBy: string): ts.ReadonlyMap<string | number> | undefined {
|
||||
const option = ts.forEach(ts.optionDeclarations, decl => ts.equateStringsCaseInsensitive(decl.name, varyBy) ? decl : undefined);
|
||||
if (option) {
|
||||
if (typeof option.type === "object") {
|
||||
return option.type;
|
||||
}
|
||||
if (option.type === "boolean") {
|
||||
return booleanVaryByStarSettingValues || (booleanVaryByStarSettingValues = ts.createMapFromTemplate({
|
||||
true: 1,
|
||||
false: 0
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute FileBasedTestConfiguration variations based on a supplied list of variable settings.
|
||||
*/
|
||||
export function getFileBasedTestConfigurations(settings: TestCaseParser.CompilerSettings, varyBy: string[]): FileBasedTestConfiguration[] | undefined {
|
||||
export function getFileBasedTestConfigurations(settings: TestCaseParser.CompilerSettings, varyBy: readonly string[]): FileBasedTestConfiguration[] | undefined {
|
||||
let varyByEntries: [string, string[]][] | undefined;
|
||||
let variationCount = 1;
|
||||
for (const varyByKey of varyBy) {
|
||||
if (ts.hasProperty(settings, varyByKey)) {
|
||||
// we only consider variations when there are 2 or more variable entries.
|
||||
const entries = splitVaryBySettingValue(settings[varyByKey]);
|
||||
const entries = splitVaryBySettingValue(settings[varyByKey], varyByKey);
|
||||
if (entries) {
|
||||
if (!varyByEntries) varyByEntries = [];
|
||||
variationCount *= entries.length;
|
||||
if (variationCount > 25) throw new Error(`Provided test options exceeded the maximum number of variations: ${varyBy.map(v => `'@${v}'`).join(", ")}`);
|
||||
varyByEntries.push([varyByKey, entries]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,6 +112,30 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
class CompilerTest {
|
||||
private static varyBy: readonly string[] = [
|
||||
"module",
|
||||
"target",
|
||||
"jsx",
|
||||
"removeComments",
|
||||
"importHelpers",
|
||||
"importHelpers",
|
||||
"downlevelIteration",
|
||||
"isolatedModules",
|
||||
"strict",
|
||||
"noImplicitAny",
|
||||
"strictNullChecks",
|
||||
"strictFunctionTypes",
|
||||
"strictBindCallApply",
|
||||
"strictPropertyInitialization",
|
||||
"noImplicitThis",
|
||||
"alwaysStrict",
|
||||
"allowSyntheticDefaultImports",
|
||||
"esModuleInterop",
|
||||
"emitDecoratorMetadata",
|
||||
"skipDefaultLibCheck",
|
||||
"preserveConstEnums",
|
||||
"skipLibCheck",
|
||||
];
|
||||
private fileName: string;
|
||||
private justName: string;
|
||||
private configuredName: string;
|
||||
@ -220,7 +244,7 @@ class CompilerTest {
|
||||
// also see `parseCompilerTestConfigurations` in tests/webTestServer.ts
|
||||
const content = Harness.IO.readFile(file)!;
|
||||
const settings = Harness.TestCaseParser.extractCompilerSettings(content);
|
||||
const configurations = Harness.getFileBasedTestConfigurations(settings, /*varyBy*/ ["module", "target"]);
|
||||
const configurations = Harness.getFileBasedTestConfigurations(settings, CompilerTest.varyBy);
|
||||
return { file, configurations, content };
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
//// [callChainWithSuper.ts]
|
||||
// GH#34952
|
||||
class Base { method?() {} }
|
||||
class Derived extends Base {
|
||||
method1() { return super.method?.(); }
|
||||
method2() { return super["method"]?.(); }
|
||||
}
|
||||
|
||||
//// [callChainWithSuper.js]
|
||||
"use strict";
|
||||
// GH#34952
|
||||
class Base {
|
||||
method() { }
|
||||
}
|
||||
class Derived extends Base {
|
||||
method1() { var _a; return (_a = super.method) === null || _a === void 0 ? void 0 : _a.call(this); }
|
||||
method2() { var _a; return (_a = super["method"]) === null || _a === void 0 ? void 0 : _a.call(this); }
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
//// [callChainWithSuper.ts]
|
||||
// GH#34952
|
||||
class Base { method?() {} }
|
||||
class Derived extends Base {
|
||||
method1() { return super.method?.(); }
|
||||
method2() { return super["method"]?.(); }
|
||||
}
|
||||
|
||||
//// [callChainWithSuper.js]
|
||||
"use strict";
|
||||
// GH#34952
|
||||
class Base {
|
||||
method() { }
|
||||
}
|
||||
class Derived extends Base {
|
||||
method1() { var _a; return (_a = super.method) === null || _a === void 0 ? void 0 : _a.call(this); }
|
||||
method2() { var _a; return (_a = super["method"]) === null || _a === void 0 ? void 0 : _a.call(this); }
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
//// [callChainWithSuper.ts]
|
||||
// GH#34952
|
||||
class Base { method?() {} }
|
||||
class Derived extends Base {
|
||||
method1() { return super.method?.(); }
|
||||
method2() { return super["method"]?.(); }
|
||||
}
|
||||
|
||||
//// [callChainWithSuper.js]
|
||||
"use strict";
|
||||
// GH#34952
|
||||
class Base {
|
||||
method() { }
|
||||
}
|
||||
class Derived extends Base {
|
||||
method1() { var _a; return (_a = super.method) === null || _a === void 0 ? void 0 : _a.call(this); }
|
||||
method2() { var _a; return (_a = super["method"]) === null || _a === void 0 ? void 0 : _a.call(this); }
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
//// [callChainWithSuper.ts]
|
||||
// GH#34952
|
||||
class Base { method?() {} }
|
||||
class Derived extends Base {
|
||||
method1() { return super.method?.(); }
|
||||
method2() { return super["method"]?.(); }
|
||||
}
|
||||
|
||||
//// [callChainWithSuper.js]
|
||||
"use strict";
|
||||
// GH#34952
|
||||
class Base {
|
||||
method() { }
|
||||
}
|
||||
class Derived extends Base {
|
||||
method1() { var _a; return (_a = super.method) === null || _a === void 0 ? void 0 : _a.call(this); }
|
||||
method2() { var _a; return (_a = super["method"]) === null || _a === void 0 ? void 0 : _a.call(this); }
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
//// [callChainWithSuper.ts]
|
||||
// GH#34952
|
||||
class Base { method?() {} }
|
||||
class Derived extends Base {
|
||||
method1() { return super.method?.(); }
|
||||
method2() { return super["method"]?.(); }
|
||||
}
|
||||
|
||||
//// [callChainWithSuper.js]
|
||||
"use strict";
|
||||
// GH#34952
|
||||
class Base {
|
||||
method() { }
|
||||
}
|
||||
class Derived extends Base {
|
||||
method1() { var _a; return (_a = super.method) === null || _a === void 0 ? void 0 : _a.call(this); }
|
||||
method2() { var _a; return (_a = super["method"]) === null || _a === void 0 ? void 0 : _a.call(this); }
|
||||
}
|
||||
39
tests/baselines/reference/callChainWithSuper(target=es5).js
Normal file
39
tests/baselines/reference/callChainWithSuper(target=es5).js
Normal file
@ -0,0 +1,39 @@
|
||||
//// [callChainWithSuper.ts]
|
||||
// GH#34952
|
||||
class Base { method?() {} }
|
||||
class Derived extends Base {
|
||||
method1() { return super.method?.(); }
|
||||
method2() { return super["method"]?.(); }
|
||||
}
|
||||
|
||||
//// [callChainWithSuper.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
// GH#34952
|
||||
var Base = /** @class */ (function () {
|
||||
function Base() {
|
||||
}
|
||||
Base.prototype.method = function () { };
|
||||
return Base;
|
||||
}());
|
||||
var Derived = /** @class */ (function (_super) {
|
||||
__extends(Derived, _super);
|
||||
function Derived() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
Derived.prototype.method1 = function () { var _a; return (_a = _super.prototype.method) === null || _a === void 0 ? void 0 : _a.call(this); };
|
||||
Derived.prototype.method2 = function () { var _a; return (_a = _super.prototype["method"]) === null || _a === void 0 ? void 0 : _a.call(this); };
|
||||
return Derived;
|
||||
}(Base));
|
||||
18
tests/baselines/reference/callChainWithSuper(target=es6).js
Normal file
18
tests/baselines/reference/callChainWithSuper(target=es6).js
Normal file
@ -0,0 +1,18 @@
|
||||
//// [callChainWithSuper.ts]
|
||||
// GH#34952
|
||||
class Base { method?() {} }
|
||||
class Derived extends Base {
|
||||
method1() { return super.method?.(); }
|
||||
method2() { return super["method"]?.(); }
|
||||
}
|
||||
|
||||
//// [callChainWithSuper.js]
|
||||
"use strict";
|
||||
// GH#34952
|
||||
class Base {
|
||||
method() { }
|
||||
}
|
||||
class Derived extends Base {
|
||||
method1() { var _a; return (_a = super.method) === null || _a === void 0 ? void 0 : _a.call(this); }
|
||||
method2() { var _a; return (_a = super["method"]) === null || _a === void 0 ? void 0 : _a.call(this); }
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
//// [callChainWithSuper.ts]
|
||||
// GH#34952
|
||||
class Base { method?() {} }
|
||||
class Derived extends Base {
|
||||
method1() { return super.method?.(); }
|
||||
method2() { return super["method"]?.(); }
|
||||
}
|
||||
|
||||
//// [callChainWithSuper.js]
|
||||
"use strict";
|
||||
// GH#34952
|
||||
class Base {
|
||||
method() { }
|
||||
}
|
||||
class Derived extends Base {
|
||||
method1() { return super.method?.(); }
|
||||
method2() { return super["method"]?.(); }
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
//// [optionalMethodDeclarations.ts]
|
||||
// https://github.com/microsoft/TypeScript/issues/34952#issuecomment-552025027
|
||||
class C {
|
||||
// ? should be removed in emit
|
||||
method?() {}
|
||||
}
|
||||
|
||||
//// [optionalMethodDeclarations.js]
|
||||
// https://github.com/microsoft/TypeScript/issues/34952#issuecomment-552025027
|
||||
class C {
|
||||
// ? should be removed in emit
|
||||
method() { }
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
//// [optionalMethodDeclarations.ts]
|
||||
// https://github.com/microsoft/TypeScript/issues/34952#issuecomment-552025027
|
||||
class C {
|
||||
// ? should be removed in emit
|
||||
method?() {}
|
||||
}
|
||||
|
||||
//// [optionalMethodDeclarations.js]
|
||||
// https://github.com/microsoft/TypeScript/issues/34952#issuecomment-552025027
|
||||
class C {
|
||||
// ? should be removed in emit
|
||||
method() { }
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
// @target: esnext,es2016
|
||||
// @noTypesAndSymbols: true
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/34952#issuecomment-552025027
|
||||
class C {
|
||||
// ? should be removed in emit
|
||||
method?() {}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
// @target: *,-es3
|
||||
// @strict: true
|
||||
// @noTypesAndSymbols: true
|
||||
|
||||
// GH#34952
|
||||
class Base { method?() {} }
|
||||
class Derived extends Base {
|
||||
method1() { return super.method?.(); }
|
||||
method2() { return super["method"]?.(); }
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user