Skip to content

Commit 69f94cd

Browse files
committed
Merge branch 'master' into refactorNarrowTypeByInstanceOf
2 parents 4381d16 + dd6c87e commit 69f94cd

File tree

12 files changed

+353
-88
lines changed

12 files changed

+353
-88
lines changed

bin/tsc.js

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13005,15 +13005,30 @@ var ts;
1300513005
return type;
1300613006
}
1300713007
var prototypeProperty = getPropertyOfType(rightType, "prototype");
13008-
if (!prototypeProperty) {
13009-
return type;
13008+
if (prototypeProperty) {
13009+
var targetType = getTypeOfSymbol(prototypeProperty);
13010+
if (targetType !== anyType) {
13011+
if (isTypeSubtypeOf(targetType, type)) {
13012+
return targetType;
13013+
}
13014+
if (type.flags & 16384) {
13015+
return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, targetType); }));
13016+
}
13017+
}
1301013018
}
13011-
var targetType = getTypeOfSymbol(prototypeProperty);
13012-
if (isTypeSubtypeOf(targetType, type)) {
13013-
return targetType;
13019+
var constructSignatures;
13020+
if (rightType.flags & 2048) {
13021+
constructSignatures = resolveDeclaredMembers(rightType).declaredConstructSignatures;
1301413022
}
13015-
if (type.flags & 16384) {
13016-
return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, targetType); }));
13023+
else if (rightType.flags & 32768) {
13024+
constructSignatures = getSignaturesOfType(rightType, 1);
13025+
}
13026+
if (constructSignatures && constructSignatures.length !== 0) {
13027+
var instanceType = getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); }));
13028+
if (type.flags & 16384) {
13029+
return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, instanceType); }));
13030+
}
13031+
return instanceType;
1301713032
}
1301813033
return type;
1301913034
}
@@ -23260,15 +23275,6 @@ var ts;
2326023275
scopeEmitEnd();
2326123276
if (thisNodeIsDecorated) {
2326223277
write(";");
23263-
if (node.name) {
23264-
writeLine();
23265-
write("Object.defineProperty(");
23266-
emitDeclarationName(node);
23267-
write(", \"name\", { value: \"");
23268-
emitDeclarationName(node);
23269-
write("\", configurable: true });");
23270-
writeLine();
23271-
}
2327223278
}
2327323279
if (isClassExpressionWithStaticProperties) {
2327423280
for (var _a = 0; _a < staticProperties.length; _a++) {

bin/tsserver.js

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13389,15 +13389,30 @@ var ts;
1338913389
return type;
1339013390
}
1339113391
var prototypeProperty = getPropertyOfType(rightType, "prototype");
13392-
if (!prototypeProperty) {
13393-
return type;
13392+
if (prototypeProperty) {
13393+
var targetType = getTypeOfSymbol(prototypeProperty);
13394+
if (targetType !== anyType) {
13395+
if (isTypeSubtypeOf(targetType, type)) {
13396+
return targetType;
13397+
}
13398+
if (type.flags & 16384) {
13399+
return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, targetType); }));
13400+
}
13401+
}
1339413402
}
13395-
var targetType = getTypeOfSymbol(prototypeProperty);
13396-
if (isTypeSubtypeOf(targetType, type)) {
13397-
return targetType;
13403+
var constructSignatures;
13404+
if (rightType.flags & 2048) {
13405+
constructSignatures = resolveDeclaredMembers(rightType).declaredConstructSignatures;
1339813406
}
13399-
if (type.flags & 16384) {
13400-
return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, targetType); }));
13407+
else if (rightType.flags & 32768) {
13408+
constructSignatures = getSignaturesOfType(rightType, 1);
13409+
}
13410+
if (constructSignatures && constructSignatures.length !== 0) {
13411+
var instanceType = getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); }));
13412+
if (type.flags & 16384) {
13413+
return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, instanceType); }));
13414+
}
13415+
return instanceType;
1340113416
}
1340213417
return type;
1340313418
}
@@ -23644,15 +23659,6 @@ var ts;
2364423659
scopeEmitEnd();
2364523660
if (thisNodeIsDecorated) {
2364623661
write(";");
23647-
if (node.name) {
23648-
writeLine();
23649-
write("Object.defineProperty(");
23650-
emitDeclarationName(node);
23651-
write(", \"name\", { value: \"");
23652-
emitDeclarationName(node);
23653-
write("\", configurable: true });");
23654-
writeLine();
23655-
}
2365623662
}
2365723663
if (isClassExpressionWithStaticProperties) {
2365823664
for (var _a = 0; _a < staticProperties.length; _a++) {

bin/typescript.js

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15732,17 +15732,34 @@ var ts;
1573215732
}
1573315733
// Target type is type of prototype property
1573415734
var prototypeProperty = getPropertyOfType(rightType, "prototype");
15735-
if (!prototypeProperty) {
15736-
return type;
15735+
if (prototypeProperty) {
15736+
var targetType = getTypeOfSymbol(prototypeProperty);
15737+
if (targetType !== anyType) {
15738+
// Narrow to the target type if it's a subtype of the current type
15739+
if (isTypeSubtypeOf(targetType, type)) {
15740+
return targetType;
15741+
}
15742+
// If the current type is a union type, remove all constituents that aren't subtypes of the target.
15743+
if (type.flags & 16384 /* Union */) {
15744+
return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, targetType); }));
15745+
}
15746+
}
1573715747
}
15738-
var targetType = getTypeOfSymbol(prototypeProperty);
15739-
// Narrow to target type if it is a subtype of current type
15740-
if (isTypeSubtypeOf(targetType, type)) {
15741-
return targetType;
15748+
// Target type is type of construct signature
15749+
var constructSignatures;
15750+
if (rightType.flags & 2048 /* Interface */) {
15751+
constructSignatures = resolveDeclaredMembers(rightType).declaredConstructSignatures;
1574215752
}
15743-
// If current type is a union type, remove all constituents that aren't subtypes of target type
15744-
if (type.flags & 16384 /* Union */) {
15745-
return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, targetType); }));
15753+
else if (rightType.flags & 32768 /* Anonymous */) {
15754+
constructSignatures = getSignaturesOfType(rightType, 1 /* Construct */);
15755+
}
15756+
if (constructSignatures && constructSignatures.length !== 0) {
15757+
var instanceType = getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); }));
15758+
// Pickup type from union types
15759+
if (type.flags & 16384 /* Union */) {
15760+
return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, instanceType); }));
15761+
}
15762+
return instanceType;
1574615763
}
1574715764
return type;
1574815765
}
@@ -27577,6 +27594,7 @@ var ts;
2757727594
writeLine();
2757827595
emitToken(15 /* CloseBraceToken */, node.members.end);
2757927596
scopeEmitEnd();
27597+
// TODO(rbuckton): Need to go back to `let _a = class C {}` approach, removing the defineProperty call for now.
2758027598
// For a decorated class, we need to assign its name (if it has one). This is because we emit
2758127599
// the class as a class expression to avoid the double-binding of the identifier:
2758227600
//
@@ -27586,15 +27604,6 @@ var ts;
2758627604
//
2758727605
if (thisNodeIsDecorated) {
2758827606
write(";");
27589-
if (node.name) {
27590-
writeLine();
27591-
write("Object.defineProperty(");
27592-
emitDeclarationName(node);
27593-
write(", \"name\", { value: \"");
27594-
emitDeclarationName(node);
27595-
write("\", configurable: true });");
27596-
writeLine();
27597-
}
2759827607
}
2759927608
// Emit static property assignment. Because classDeclaration is lexically evaluated,
2760027609
// it is safe to emit static property assignment after classDeclaration

bin/typescriptServices.js

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15732,17 +15732,34 @@ var ts;
1573215732
}
1573315733
// Target type is type of prototype property
1573415734
var prototypeProperty = getPropertyOfType(rightType, "prototype");
15735-
if (!prototypeProperty) {
15736-
return type;
15735+
if (prototypeProperty) {
15736+
var targetType = getTypeOfSymbol(prototypeProperty);
15737+
if (targetType !== anyType) {
15738+
// Narrow to the target type if it's a subtype of the current type
15739+
if (isTypeSubtypeOf(targetType, type)) {
15740+
return targetType;
15741+
}
15742+
// If the current type is a union type, remove all constituents that aren't subtypes of the target.
15743+
if (type.flags & 16384 /* Union */) {
15744+
return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, targetType); }));
15745+
}
15746+
}
1573715747
}
15738-
var targetType = getTypeOfSymbol(prototypeProperty);
15739-
// Narrow to target type if it is a subtype of current type
15740-
if (isTypeSubtypeOf(targetType, type)) {
15741-
return targetType;
15748+
// Target type is type of construct signature
15749+
var constructSignatures;
15750+
if (rightType.flags & 2048 /* Interface */) {
15751+
constructSignatures = resolveDeclaredMembers(rightType).declaredConstructSignatures;
1574215752
}
15743-
// If current type is a union type, remove all constituents that aren't subtypes of target type
15744-
if (type.flags & 16384 /* Union */) {
15745-
return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, targetType); }));
15753+
else if (rightType.flags & 32768 /* Anonymous */) {
15754+
constructSignatures = getSignaturesOfType(rightType, 1 /* Construct */);
15755+
}
15756+
if (constructSignatures && constructSignatures.length !== 0) {
15757+
var instanceType = getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); }));
15758+
// Pickup type from union types
15759+
if (type.flags & 16384 /* Union */) {
15760+
return getUnionType(ts.filter(type.types, function (t) { return isTypeSubtypeOf(t, instanceType); }));
15761+
}
15762+
return instanceType;
1574615763
}
1574715764
return type;
1574815765
}
@@ -27577,6 +27594,7 @@ var ts;
2757727594
writeLine();
2757827595
emitToken(15 /* CloseBraceToken */, node.members.end);
2757927596
scopeEmitEnd();
27597+
// TODO(rbuckton): Need to go back to `let _a = class C {}` approach, removing the defineProperty call for now.
2758027598
// For a decorated class, we need to assign its name (if it has one). This is because we emit
2758127599
// the class as a class expression to avoid the double-binding of the identifier:
2758227600
//
@@ -27586,15 +27604,6 @@ var ts;
2758627604
//
2758727605
if (thisNodeIsDecorated) {
2758827606
write(";");
27589-
if (node.name) {
27590-
writeLine();
27591-
write("Object.defineProperty(");
27592-
emitDeclarationName(node);
27593-
write(", \"name\", { value: \"");
27594-
emitDeclarationName(node);
27595-
write("\", configurable: true });");
27596-
writeLine();
27597-
}
2759827607
}
2759927608
// Emit static property assignment. Because classDeclaration is lexically evaluated,
2760027609
// it is safe to emit static property assignment after classDeclaration

src/compiler/emitter.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3898,6 +3898,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
38983898
emitToken(SyntaxKind.CloseBraceToken, node.members.end);
38993899
scopeEmitEnd();
39003900

3901+
// TODO(rbuckton): Need to go back to `let _a = class C {}` approach, removing the defineProperty call for now.
3902+
39013903
// For a decorated class, we need to assign its name (if it has one). This is because we emit
39023904
// the class as a class expression to avoid the double-binding of the identifier:
39033905
//
@@ -3907,15 +3909,6 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
39073909
//
39083910
if (thisNodeIsDecorated) {
39093911
write(";");
3910-
if (node.name) {
3911-
writeLine();
3912-
write("Object.defineProperty(");
3913-
emitDeclarationName(node);
3914-
write(", \"name\", { value: \"");
3915-
emitDeclarationName(node);
3916-
write("\", configurable: true });");
3917-
writeLine();
3918-
}
39193912
}
39203913

39213914
// Emit static property assignment. Because classDeclaration is lexically evaluated,

src/lib/es6.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3580,6 +3580,7 @@ interface PromiseLike<T> {
35803580
* @returns A Promise for the completion of which ever callback is executed.
35813581
*/
35823582
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): PromiseLike<TResult>;
3583+
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): PromiseLike<TResult>;
35833584
}
35843585

35853586
/**
@@ -3593,6 +3594,7 @@ interface Promise<T> {
35933594
* @returns A Promise for the completion of which ever callback is executed.
35943595
*/
35953596
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): Promise<TResult>;
3597+
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): Promise<TResult>;
35963598

35973599
/**
35983600
* Attaches a callback for only the rejection of the Promise.

src/services/services.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,7 +1632,7 @@ module ts {
16321632
private fileNameToEntry: Map<HostFileInformation>;
16331633
private _compilationSettings: CompilerOptions;
16341634

1635-
constructor(private host: LanguageServiceHost) {
1635+
constructor(private host: LanguageServiceHost, private getCanonicalFileName: (fileName: string) => string) {
16361636
// script id => script index
16371637
this.fileNameToEntry = {};
16381638

@@ -1650,6 +1650,10 @@ module ts {
16501650
return this._compilationSettings;
16511651
}
16521652

1653+
private normalizeFileName(fileName: string): string {
1654+
return this.getCanonicalFileName(normalizeSlashes(fileName));
1655+
}
1656+
16531657
private createEntry(fileName: string) {
16541658
let entry: HostFileInformation;
16551659
let scriptSnapshot = this.host.getScriptSnapshot(fileName);
@@ -1661,15 +1665,15 @@ module ts {
16611665
};
16621666
}
16631667

1664-
return this.fileNameToEntry[normalizeSlashes(fileName)] = entry;
1668+
return this.fileNameToEntry[this.normalizeFileName(fileName)] = entry;
16651669
}
16661670

1667-
public getEntry(fileName: string): HostFileInformation {
1668-
return lookUp(this.fileNameToEntry, normalizeSlashes(fileName));
1671+
private getEntry(fileName: string): HostFileInformation {
1672+
return lookUp(this.fileNameToEntry, this.normalizeFileName(fileName));
16691673
}
16701674

1671-
public contains(fileName: string): boolean {
1672-
return hasProperty(this.fileNameToEntry, normalizeSlashes(fileName));
1675+
private contains(fileName: string): boolean {
1676+
return hasProperty(this.fileNameToEntry, this.normalizeFileName(fileName));
16731677
}
16741678

16751679
public getOrCreateEntry(fileName: string): HostFileInformation {
@@ -1684,8 +1688,10 @@ module ts {
16841688
let fileNames: string[] = [];
16851689

16861690
forEachKey(this.fileNameToEntry, key => {
1687-
if (hasProperty(this.fileNameToEntry, key) && this.fileNameToEntry[key])
1688-
fileNames.push(key);
1691+
let entry = this.getEntry(key);
1692+
if (entry) {
1693+
fileNames.push(entry.hostFileName);
1694+
}
16891695
});
16901696

16911697
return fileNames;
@@ -2387,7 +2393,7 @@ module ts {
23872393

23882394
function synchronizeHostData(): void {
23892395
// Get a fresh cache of the host information
2390-
let hostCache = new HostCache(host);
2396+
let hostCache = new HostCache(host, getCanonicalFileName);
23912397

23922398
// If the program is already up-to-date, we can reuse it
23932399
if (programUpToDate()) {
@@ -2408,7 +2414,7 @@ module ts {
24082414
let newProgram = createProgram(hostCache.getRootFileNames(), newSettings, {
24092415
getSourceFile: getOrCreateSourceFile,
24102416
getCancellationToken: () => cancellationToken,
2411-
getCanonicalFileName: (fileName) => useCaseSensitivefileNames ? fileName : fileName.toLowerCase(),
2417+
getCanonicalFileName,
24122418
useCaseSensitiveFileNames: () => useCaseSensitivefileNames,
24132419
getNewLine: () => host.getNewLine ? host.getNewLine() : "\r\n",
24142420
getDefaultLibFileName: (options) => host.getDefaultLibFileName(options),

tests/baselines/reference/decoratedClassFromExternalModule.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
2121
function decorate() { }
2222
let Decorated = class {
2323
};
24-
Object.defineProperty(Decorated, "name", { value: "Decorated", configurable: true });
2524
Decorated = __decorate([
2625
decorate
2726
], Decorated);

0 commit comments

Comments
 (0)