diff --git a/AUTHORS.md b/AUTHORS.md index 486a15bf47..0501514d75 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -2,9 +2,11 @@ TypeScript is authored by: * Adam Freidin * Ahmad Farid +* Akshar Patel * Anders Hejlsberg * Arnav Singh * Arthur Ozga +* Asad Saeeduddin * Basarat Ali Syed * Ben Duffield * Bill Ticehurst @@ -15,30 +17,39 @@ TypeScript is authored by: * Colby Russell * Colin Snover * Cyrus Najmabadi +* Dan Corder * Dan Quirk * Daniel Rosenwasser +* @dashaus * David Li * Denis Nedelyaev * Dick van den Brink * Dirk Bäumer +* Dirk Holtwick * Eyas Sharaiha +* @falsandtru * Frank Wallis * Gabriel Isenberg * Gilad Peleg * Graeme Wicksted * Guillaume Salles +* Guy Bedford * Harald Niesche +* Iain Monro * Ingvar Stepanyan * Ivo Gabe de Wolff * James Whitney * Jason Freeman +* Jason Killian * Jason Ramsay * Jed Mao +* Jeffrey Morlan * Johannes Rieken * John Vilk * Jonathan Bond-Caron * Jonathan Park * Jonathan Turner +* Jonathon Smith * Josh Kalderimis * Julian Williams * Kagami Sascha Rosylight @@ -46,21 +57,27 @@ TypeScript is authored by: * Ken Howard * Kenji Imamula * Lorant Pinter +* Lucien Greathouse * Martin Všetička * Masahiro Wakame +* Mattias Buelens * Max Deepfield * Micah Zoltu * Mohamed Hegazy * Nathan Shively-Sanders +* Nathan Yee * Oleg Mihailik * Oleksandr Chekhovskyi * Paul van Brenk +* @pcbro * Pedro Maltez * Philip Bulley * piloopin * @progre * Punya Biswal +* Richard Sentino * Ron Buckton +* Rowan Wyborn * Ryan Cavanaugh * Ryohei Ikegami * Sébastien Arod @@ -71,7 +88,9 @@ TypeScript is authored by: * Solal Pirelli * Stan Thomas * Steve Lucco +* Thomas Loubiou * Tien Hoanhtien +* Tim Perry * Tingan Ho * togru * Tomas Grubliauskas @@ -81,5 +100,6 @@ TypeScript is authored by: * Wesley Wigham * York Yao * Yui Tanglertsampan +* Yuichi Nukiyama * Zev Spitz * Zhengbo Li diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 11f550bad5..6adf39377c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10442,7 +10442,8 @@ namespace ts { } else { error(func, Diagnostics.No_best_common_type_exists_among_return_expressions); - return unknownType; + // Defer to unioning the return types so we get a) downstream errors earlier and b) better Salsa experience + return getUnionType(types); } } @@ -15379,6 +15380,20 @@ namespace ts { return getSymbolOfNode(entityName.parent); } + if (isInJavaScriptFile(entityName) && entityName.parent.kind === SyntaxKind.PropertyAccessExpression) { + const specialPropertyAssignmentKind = getSpecialPropertyAssignmentKind(entityName.parent.parent); + switch (specialPropertyAssignmentKind) { + case SpecialPropertyAssignmentKind.ExportsProperty: + case SpecialPropertyAssignmentKind.PrototypeProperty: + return getSymbolOfNode(entityName.parent); + case SpecialPropertyAssignmentKind.ThisProperty: + case SpecialPropertyAssignmentKind.ModuleExports: + return getSymbolOfNode(entityName.parent.parent); + default: + // Fall through if it is not a special property assignment + } + } + if (entityName.parent.kind === SyntaxKind.ExportAssignment) { return resolveEntityName(entityName, /*all meanings*/ SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias); diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 9a57b4b1a3..ab0b16947f 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -637,18 +637,21 @@ namespace ts { } } - function emitClassMemberDeclarationFlags(node: Declaration) { - if (node.flags & NodeFlags.Private) { + function emitClassMemberDeclarationFlags(flags: NodeFlags) { + if (flags & NodeFlags.Private) { write("private "); } - else if (node.flags & NodeFlags.Protected) { + else if (flags & NodeFlags.Protected) { write("protected "); } - if (node.flags & NodeFlags.Static) { + if (flags & NodeFlags.Static) { write("static "); } - if (node.flags & NodeFlags.Abstract) { + if (flags & NodeFlags.Readonly) { + write("readonly "); + } + if (flags & NodeFlags.Abstract) { write("abstract "); } } @@ -1074,7 +1077,7 @@ namespace ts { } emitJsDocComments(node); - emitClassMemberDeclarationFlags(node); + emitClassMemberDeclarationFlags(node.flags); emitVariableDeclaration(node); write(";"); writeLine(); @@ -1227,7 +1230,7 @@ namespace ts { if (node === accessors.firstAccessor) { emitJsDocComments(accessors.getAccessor); emitJsDocComments(accessors.setAccessor); - emitClassMemberDeclarationFlags(node); + emitClassMemberDeclarationFlags(node.flags | (accessors.setAccessor ? 0 : NodeFlags.Readonly)); writeTextOfNode(currentText, node.name); if (!(node.flags & NodeFlags.Private)) { accessorWithTypeAnnotation = node; @@ -1314,7 +1317,7 @@ namespace ts { emitModuleElementDeclarationFlags(node); } else if (node.kind === SyntaxKind.MethodDeclaration) { - emitClassMemberDeclarationFlags(node); + emitClassMemberDeclarationFlags(node.flags); } if (node.kind === SyntaxKind.FunctionDeclaration) { write("function "); @@ -1342,15 +1345,17 @@ namespace ts { const prevEnclosingDeclaration = enclosingDeclaration; enclosingDeclaration = node; - // Construct signature or constructor type write new Signature - if (node.kind === SyntaxKind.ConstructSignature || node.kind === SyntaxKind.ConstructorType) { - write("new "); - } - emitTypeParameters(node.typeParameters); if (node.kind === SyntaxKind.IndexSignature) { + // Index signature can have readonly modifier + emitClassMemberDeclarationFlags(node.flags); write("["); } else { + // Construct signature or constructor type write new Signature + if (node.kind === SyntaxKind.ConstructSignature || node.kind === SyntaxKind.ConstructorType) { + write("new "); + } + emitTypeParameters(node.typeParameters); write("("); } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 0a3cbd89d9..27512ab3dc 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -7123,14 +7123,22 @@ const _super = (function (geti, seti) { for (let i = 0; i < externalImports.length; i++) { const text = getExternalModuleNameText(externalImports[i], emitRelativePathAsModuleName); - if (hasProperty(groupIndices, text)) { + if (text === undefined) { + continue; + } + + // text should be quoted string + // for deduplication purposes in key remove leading and trailing quotes so 'a' and "a" will be considered the same + const key = text.substr(1, text.length - 2); + + if (hasProperty(groupIndices, key)) { // deduplicate/group entries in dependency list by the dependency name - const groupIndex = groupIndices[text]; + const groupIndex = groupIndices[key]; dependencyGroups[groupIndex].push(externalImports[i]); continue; } else { - groupIndices[text] = dependencyGroups.length; + groupIndices[key] = dependencyGroups.length; dependencyGroups.push([externalImports[i]]); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index bf88a87d3e..787a022140 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4017,7 +4017,7 @@ namespace ts { setDecoratorContext(/*val*/ true); } - return finishNode(node); + return addJSDocComment(finishNode(node)); } function parseOptionalIdentifier() { @@ -4301,13 +4301,13 @@ namespace ts { const labeledStatement = createNode(SyntaxKind.LabeledStatement, fullStart); labeledStatement.label = expression; labeledStatement.statement = parseStatement(); - return finishNode(labeledStatement); + return addJSDocComment(finishNode(labeledStatement)); } else { const expressionStatement = createNode(SyntaxKind.ExpressionStatement, fullStart); expressionStatement.expression = expression; parseSemicolon(); - return finishNode(expressionStatement); + return addJSDocComment(finishNode(expressionStatement)); } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 05dc4be1d0..33ad24d7f5 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1205,7 +1205,19 @@ namespace ts { node.parent.parent.parent.kind === SyntaxKind.VariableStatement; const variableStatementNode = isInitializerOfVariableDeclarationInStatement ? node.parent.parent.parent : undefined; - return variableStatementNode && variableStatementNode.jsDocComment; + if (variableStatementNode) { + return variableStatementNode.jsDocComment; + } + + // Also recognize when the node is the RHS of an assignment expression + const isSourceOfAssignmentExpressionStatement = + node.parent && node.parent.parent && + node.parent.kind === SyntaxKind.BinaryExpression && + (node.parent as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken && + node.parent.parent.kind === SyntaxKind.ExpressionStatement; + if (isSourceOfAssignmentExpressionStatement) { + return node.parent.parent.jsDocComment; + } } return undefined; diff --git a/tests/baselines/reference/classdecl.js b/tests/baselines/reference/classdecl.js index 710c5166d3..a8a440fa17 100644 --- a/tests/baselines/reference/classdecl.js +++ b/tests/baselines/reference/classdecl.js @@ -211,12 +211,12 @@ declare class a { pgF(): void; pv: any; d: number; - static p2: { + static readonly p2: { x: number; y: number; }; private static d2(); - private static p3; + private static readonly p3; private pv3; private foo(n); private foo(s); diff --git a/tests/baselines/reference/commentsClassMembers.js b/tests/baselines/reference/commentsClassMembers.js index fe2dc0a63d..dacbde7a27 100644 --- a/tests/baselines/reference/commentsClassMembers.js +++ b/tests/baselines/reference/commentsClassMembers.js @@ -568,8 +568,8 @@ declare var i1_c: typeof c1; declare class cProperties { private val; /** getter only property*/ - p1: number; - nc_p1: number; + readonly p1: number; + readonly nc_p1: number; /**setter only property*/ p2: number; nc_p2: number; diff --git a/tests/baselines/reference/commentsInheritance.js b/tests/baselines/reference/commentsInheritance.js index b9d84b2475..42df3cca38 100644 --- a/tests/baselines/reference/commentsInheritance.js +++ b/tests/baselines/reference/commentsInheritance.js @@ -316,19 +316,19 @@ declare class c2 { /** c2 c2_f1*/ c2_f1(): void; /** c2 c2_prop*/ - c2_prop: number; + readonly c2_prop: number; c2_nc_p1: number; c2_nc_f1(): void; - c2_nc_prop: number; + readonly c2_nc_prop: number; /** c2 p1*/ p1: number; /** c2 f1*/ f1(): void; /** c2 prop*/ - prop: number; + readonly prop: number; nc_p1: number; nc_f1(): void; - nc_prop: number; + readonly nc_prop: number; /** c2 constructor*/ constructor(a: number); } @@ -339,10 +339,10 @@ declare class c3 extends c2 { /** c3 f1*/ f1(): void; /** c3 prop*/ - prop: number; + readonly prop: number; nc_p1: number; nc_f1(): void; - nc_prop: number; + readonly nc_prop: number; } declare var c2_i: c2; declare var c3_i: c3; diff --git a/tests/baselines/reference/declFileAccessors.js b/tests/baselines/reference/declFileAccessors.js index e3616c79e3..2bd51bfbfb 100644 --- a/tests/baselines/reference/declFileAccessors.js +++ b/tests/baselines/reference/declFileAccessors.js @@ -284,7 +284,7 @@ export declare class c1 { nc_p3: number; private nc_pp3; static nc_s3: string; - onlyGetter: number; + readonly onlyGetter: number; onlySetter: number; } //// [declFileAccessors_1.d.ts] @@ -302,6 +302,6 @@ declare class c2 { nc_p3: number; private nc_pp3; static nc_s3: string; - onlyGetter: number; + readonly onlyGetter: number; onlySetter: number; } diff --git a/tests/baselines/reference/declFilePrivateStatic.js b/tests/baselines/reference/declFilePrivateStatic.js index dd81d94b3c..30cd85444c 100644 --- a/tests/baselines/reference/declFilePrivateStatic.js +++ b/tests/baselines/reference/declFilePrivateStatic.js @@ -52,8 +52,8 @@ declare class C { static y: number; private static a(); static b(): void; - private static c; - static d: number; + private static readonly c; + static readonly d: number; private static e; static f: any; } diff --git a/tests/baselines/reference/declarationEmit_protectedMembers.js b/tests/baselines/reference/declarationEmit_protectedMembers.js index 5aad004939..192f0647ed 100644 --- a/tests/baselines/reference/declarationEmit_protectedMembers.js +++ b/tests/baselines/reference/declarationEmit_protectedMembers.js @@ -135,7 +135,7 @@ declare class C1 { protected static sx: number; protected static sf(): number; protected static staticSetter: number; - protected static staticGetter: number; + protected static readonly staticGetter: number; } declare class C2 extends C1 { protected f(): number; @@ -146,7 +146,7 @@ declare class C3 extends C2 { static sx: number; f(): number; static sf(): number; - static staticGetter: number; + static readonly staticGetter: number; } declare class C4 { protected a: number; diff --git a/tests/baselines/reference/deduplicateImportsInSystem.errors.txt b/tests/baselines/reference/deduplicateImportsInSystem.errors.txt new file mode 100644 index 0000000000..d1bfe88160 --- /dev/null +++ b/tests/baselines/reference/deduplicateImportsInSystem.errors.txt @@ -0,0 +1,32 @@ +tests/cases/compiler/deduplicateImportsInSystem.ts(1,17): error TS2307: Cannot find module 'f1'. +tests/cases/compiler/deduplicateImportsInSystem.ts(2,17): error TS2307: Cannot find module 'f2'. +tests/cases/compiler/deduplicateImportsInSystem.ts(3,17): error TS2307: Cannot find module 'f3'. +tests/cases/compiler/deduplicateImportsInSystem.ts(4,17): error TS2307: Cannot find module 'f2'. +tests/cases/compiler/deduplicateImportsInSystem.ts(5,17): error TS2307: Cannot find module 'f2'. +tests/cases/compiler/deduplicateImportsInSystem.ts(6,17): error TS2307: Cannot find module 'f1'. +tests/cases/compiler/deduplicateImportsInSystem.ts(8,1): error TS2304: Cannot find name 'console'. + + +==== tests/cases/compiler/deduplicateImportsInSystem.ts (7 errors) ==== + import {A} from "f1"; + ~~~~ +!!! error TS2307: Cannot find module 'f1'. + import {B} from "f2"; + ~~~~ +!!! error TS2307: Cannot find module 'f2'. + import {C} from "f3"; + ~~~~ +!!! error TS2307: Cannot find module 'f3'. + import {D} from 'f2'; + ~~~~ +!!! error TS2307: Cannot find module 'f2'. + import {E} from "f2"; + ~~~~ +!!! error TS2307: Cannot find module 'f2'. + import {F} from 'f1'; + ~~~~ +!!! error TS2307: Cannot find module 'f1'. + + console.log(A + B + C + D + E + F) + ~~~~~~~ +!!! error TS2304: Cannot find name 'console'. \ No newline at end of file diff --git a/tests/baselines/reference/deduplicateImportsInSystem.js b/tests/baselines/reference/deduplicateImportsInSystem.js new file mode 100644 index 0000000000..956d293cad --- /dev/null +++ b/tests/baselines/reference/deduplicateImportsInSystem.js @@ -0,0 +1,33 @@ +//// [deduplicateImportsInSystem.ts] +import {A} from "f1"; +import {B} from "f2"; +import {C} from "f3"; +import {D} from 'f2'; +import {E} from "f2"; +import {F} from 'f1'; + +console.log(A + B + C + D + E + F) + +//// [deduplicateImportsInSystem.js] +System.register(["f1", "f2", "f3"], function(exports_1) { + "use strict"; + var f1_1, f2_1, f3_1, f2_2, f2_3, f1_2; + return { + setters:[ + function (f1_1_1) { + f1_1 = f1_1_1; + f1_2 = f1_1_1; + }, + function (f2_1_1) { + f2_1 = f2_1_1; + f2_2 = f2_1_1; + f2_3 = f2_1_1; + }, + function (f3_1_1) { + f3_1 = f3_1_1; + }], + execute: function() { + console.log(f1_1.A + f2_1.B + f3_1.C + f2_2.D + f2_3.E + f1_2.F); + } + } +}); diff --git a/tests/baselines/reference/giant.js b/tests/baselines/reference/giant.js index 2a04541ef2..149a975d41 100644 --- a/tests/baselines/reference/giant.js +++ b/tests/baselines/reference/giant.js @@ -1120,11 +1120,11 @@ export declare class eC { pF(): void; private rF(); pgF(): void; - pgF: any; + readonly pgF: any; psF(param: any): void; psF: any; private rgF(); - private rgF; + private readonly rgF; private rsF(param); private rsF; static tV: any; @@ -1132,7 +1132,7 @@ export declare class eC { static tsF(param: any): void; static tsF: any; static tgF(): void; - static tgF: any; + static readonly tgF: any; } export interface eI { (): any; @@ -1172,11 +1172,11 @@ export declare module eM { pF(): void; private rF(); pgF(): void; - pgF: any; + readonly pgF: any; psF(param: any): void; psF: any; private rgF(); - private rgF; + private readonly rgF; private rsF(param); private rsF; static tV: any; @@ -1184,7 +1184,7 @@ export declare module eM { static tsF(param: any): void; static tsF: any; static tgF(): void; - static tgF: any; + static readonly tgF: any; } interface eI { (): any; @@ -1239,11 +1239,11 @@ export declare module eM { pF(): void; private rF(); pgF(): void; - pgF: any; + readonly pgF: any; psF(param: any): void; psF: any; private rgF(); - private rgF; + private readonly rgF; private rsF(param); private rsF; static tV: any; @@ -1251,7 +1251,7 @@ export declare module eM { static tsF(param: any): void; static tsF: any; static tgF(): void; - static tgF: any; + static readonly tgF: any; } module eaM { var V: any; @@ -1281,11 +1281,11 @@ export declare class eaC { pF(): void; private rF(); pgF(): void; - pgF: any; + readonly pgF: any; psF(param: any): void; psF: any; private rgF(); - private rgF; + private readonly rgF; private rsF(param); private rsF; static tV: any; @@ -1293,7 +1293,7 @@ export declare class eaC { static tsF(param: any): void; static tsF: any; static tgF(): void; - static tgF: any; + static readonly tgF: any; } export declare module eaM { var V: any; diff --git a/tests/baselines/reference/isDeclarationVisibleNodeKinds.js b/tests/baselines/reference/isDeclarationVisibleNodeKinds.js index 99e1ac72ac..e24032eb85 100644 --- a/tests/baselines/reference/isDeclarationVisibleNodeKinds.js +++ b/tests/baselines/reference/isDeclarationVisibleNodeKinds.js @@ -193,7 +193,7 @@ declare module schema { } declare module schema { class T { - createValidator9: (data: T) => T; + readonly createValidator9: (data: T) => T; createValidator10: (data: T) => T; } } diff --git a/tests/baselines/reference/moduledecl.js b/tests/baselines/reference/moduledecl.js index 2e765e512d..f4efbadbf3 100644 --- a/tests/baselines/reference/moduledecl.js +++ b/tests/baselines/reference/moduledecl.js @@ -459,10 +459,10 @@ declare module exportTests { class C3_public { private getC2_private(); private setC2_private(arg); - private c2; + private readonly c2; getC1_public(): C1_public; setC1_public(arg: C1_public): void; - c1: C1_public; + readonly c1: C1_public; } } declare module mAmbient { diff --git a/tests/baselines/reference/readonlyInDeclarationFile.js b/tests/baselines/reference/readonlyInDeclarationFile.js new file mode 100644 index 0000000000..71e48272ec --- /dev/null +++ b/tests/baselines/reference/readonlyInDeclarationFile.js @@ -0,0 +1,180 @@ +//// [readonlyInDeclarationFile.ts] + +interface Foo { + readonly x: number; + readonly [x: string]: Object; +} + +class C { + readonly [x: string]: Object; + private readonly a1: number; + protected readonly a2: number; + public readonly a3: number; + private get b1() { return 1 } + protected get b2() { return 1 } + public get b3() { return 1 } + private get c1() { return 1 } + private set c1(value) { } + protected get c2() { return 1 } + protected set c2(value) { } + public get c3() { return 1 } + public set c3(value) { } + private static readonly s1: number; + protected static readonly s2: number; + public static readonly s3: number; + private static get t1() { return 1 } + protected static get t2() { return 1 } + public static get t3() { return 1 } + private static get u1() { return 1 } + private static set u1(value) { } + protected static get u2() { return 1 } + protected static set u2(value) { } + public static get u3() { return 1 } + public static set u3(value) { } +} + +var z: { + readonly a: string; + readonly [x: string]: Object; +} + +function f() { + return { + get x() { return 1; }, + get y() { return 1; }, + set y(value) { } + } +} + +function g() { + var x: { + readonly a: string; + readonly [x: string]: Object; + } + return x; +} + +//// [readonlyInDeclarationFile.js] +var C = (function () { + function C() { + } + Object.defineProperty(C.prototype, "b1", { + get: function () { return 1; }, + enumerable: true, + configurable: true + }); + Object.defineProperty(C.prototype, "b2", { + get: function () { return 1; }, + enumerable: true, + configurable: true + }); + Object.defineProperty(C.prototype, "b3", { + get: function () { return 1; }, + enumerable: true, + configurable: true + }); + Object.defineProperty(C.prototype, "c1", { + get: function () { return 1; }, + set: function (value) { }, + enumerable: true, + configurable: true + }); + Object.defineProperty(C.prototype, "c2", { + get: function () { return 1; }, + set: function (value) { }, + enumerable: true, + configurable: true + }); + Object.defineProperty(C.prototype, "c3", { + get: function () { return 1; }, + set: function (value) { }, + enumerable: true, + configurable: true + }); + Object.defineProperty(C, "t1", { + get: function () { return 1; }, + enumerable: true, + configurable: true + }); + Object.defineProperty(C, "t2", { + get: function () { return 1; }, + enumerable: true, + configurable: true + }); + Object.defineProperty(C, "t3", { + get: function () { return 1; }, + enumerable: true, + configurable: true + }); + Object.defineProperty(C, "u1", { + get: function () { return 1; }, + set: function (value) { }, + enumerable: true, + configurable: true + }); + Object.defineProperty(C, "u2", { + get: function () { return 1; }, + set: function (value) { }, + enumerable: true, + configurable: true + }); + Object.defineProperty(C, "u3", { + get: function () { return 1; }, + set: function (value) { }, + enumerable: true, + configurable: true + }); + return C; +}()); +var z; +function f() { + return { + get x() { return 1; }, + get y() { return 1; }, + set y(value) { } + }; +} +function g() { + var x; + return x; +} + + +//// [readonlyInDeclarationFile.d.ts] +interface Foo { + readonly x: number; + readonly [x: string]: Object; +} +declare class C { + readonly [x: string]: Object; + private readonly a1; + protected readonly a2: number; + readonly a3: number; + private readonly b1; + protected readonly b2: number; + readonly b3: number; + private c1; + protected c2: number; + c3: number; + private static readonly s1; + protected static readonly s2: number; + static readonly s3: number; + private static readonly t1; + protected static readonly t2: number; + static readonly t3: number; + private static u1; + protected static u2: number; + static u3: number; +} +declare var z: { + readonly a: string; + readonly [x: string]: Object; +}; +declare function f(): { + readonly x: number; + y: number; +}; +declare function g(): { + readonly [x: string]: Object; + readonly a: string; +}; diff --git a/tests/baselines/reference/readonlyInDeclarationFile.symbols b/tests/baselines/reference/readonlyInDeclarationFile.symbols new file mode 100644 index 0000000000..af979e4dac --- /dev/null +++ b/tests/baselines/reference/readonlyInDeclarationFile.symbols @@ -0,0 +1,142 @@ +=== tests/cases/compiler/readonlyInDeclarationFile.ts === + +interface Foo { +>Foo : Symbol(Foo, Decl(readonlyInDeclarationFile.ts, 0, 0)) + + readonly x: number; +>x : Symbol(x, Decl(readonlyInDeclarationFile.ts, 1, 15)) + + readonly [x: string]: Object; +>x : Symbol(x, Decl(readonlyInDeclarationFile.ts, 3, 14)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +} + +class C { +>C : Symbol(C, Decl(readonlyInDeclarationFile.ts, 4, 1)) + + readonly [x: string]: Object; +>x : Symbol(x, Decl(readonlyInDeclarationFile.ts, 7, 14)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + + private readonly a1: number; +>a1 : Symbol(a1, Decl(readonlyInDeclarationFile.ts, 7, 33)) + + protected readonly a2: number; +>a2 : Symbol(a2, Decl(readonlyInDeclarationFile.ts, 8, 32)) + + public readonly a3: number; +>a3 : Symbol(a3, Decl(readonlyInDeclarationFile.ts, 9, 34)) + + private get b1() { return 1 } +>b1 : Symbol(b1, Decl(readonlyInDeclarationFile.ts, 10, 31)) + + protected get b2() { return 1 } +>b2 : Symbol(b2, Decl(readonlyInDeclarationFile.ts, 11, 33)) + + public get b3() { return 1 } +>b3 : Symbol(b3, Decl(readonlyInDeclarationFile.ts, 12, 35)) + + private get c1() { return 1 } +>c1 : Symbol(c1, Decl(readonlyInDeclarationFile.ts, 13, 32), Decl(readonlyInDeclarationFile.ts, 14, 33)) + + private set c1(value) { } +>c1 : Symbol(c1, Decl(readonlyInDeclarationFile.ts, 13, 32), Decl(readonlyInDeclarationFile.ts, 14, 33)) +>value : Symbol(value, Decl(readonlyInDeclarationFile.ts, 15, 19)) + + protected get c2() { return 1 } +>c2 : Symbol(c2, Decl(readonlyInDeclarationFile.ts, 15, 29), Decl(readonlyInDeclarationFile.ts, 16, 35)) + + protected set c2(value) { } +>c2 : Symbol(c2, Decl(readonlyInDeclarationFile.ts, 15, 29), Decl(readonlyInDeclarationFile.ts, 16, 35)) +>value : Symbol(value, Decl(readonlyInDeclarationFile.ts, 17, 21)) + + public get c3() { return 1 } +>c3 : Symbol(c3, Decl(readonlyInDeclarationFile.ts, 17, 31), Decl(readonlyInDeclarationFile.ts, 18, 32)) + + public set c3(value) { } +>c3 : Symbol(c3, Decl(readonlyInDeclarationFile.ts, 17, 31), Decl(readonlyInDeclarationFile.ts, 18, 32)) +>value : Symbol(value, Decl(readonlyInDeclarationFile.ts, 19, 18)) + + private static readonly s1: number; +>s1 : Symbol(C.s1, Decl(readonlyInDeclarationFile.ts, 19, 28)) + + protected static readonly s2: number; +>s2 : Symbol(C.s2, Decl(readonlyInDeclarationFile.ts, 20, 39)) + + public static readonly s3: number; +>s3 : Symbol(C.s3, Decl(readonlyInDeclarationFile.ts, 21, 41)) + + private static get t1() { return 1 } +>t1 : Symbol(C.t1, Decl(readonlyInDeclarationFile.ts, 22, 38)) + + protected static get t2() { return 1 } +>t2 : Symbol(C.t2, Decl(readonlyInDeclarationFile.ts, 23, 40)) + + public static get t3() { return 1 } +>t3 : Symbol(C.t3, Decl(readonlyInDeclarationFile.ts, 24, 42)) + + private static get u1() { return 1 } +>u1 : Symbol(C.u1, Decl(readonlyInDeclarationFile.ts, 25, 39), Decl(readonlyInDeclarationFile.ts, 26, 40)) + + private static set u1(value) { } +>u1 : Symbol(C.u1, Decl(readonlyInDeclarationFile.ts, 25, 39), Decl(readonlyInDeclarationFile.ts, 26, 40)) +>value : Symbol(value, Decl(readonlyInDeclarationFile.ts, 27, 26)) + + protected static get u2() { return 1 } +>u2 : Symbol(C.u2, Decl(readonlyInDeclarationFile.ts, 27, 36), Decl(readonlyInDeclarationFile.ts, 28, 42)) + + protected static set u2(value) { } +>u2 : Symbol(C.u2, Decl(readonlyInDeclarationFile.ts, 27, 36), Decl(readonlyInDeclarationFile.ts, 28, 42)) +>value : Symbol(value, Decl(readonlyInDeclarationFile.ts, 29, 28)) + + public static get u3() { return 1 } +>u3 : Symbol(C.u3, Decl(readonlyInDeclarationFile.ts, 29, 38), Decl(readonlyInDeclarationFile.ts, 30, 39)) + + public static set u3(value) { } +>u3 : Symbol(C.u3, Decl(readonlyInDeclarationFile.ts, 29, 38), Decl(readonlyInDeclarationFile.ts, 30, 39)) +>value : Symbol(value, Decl(readonlyInDeclarationFile.ts, 31, 25)) +} + +var z: { +>z : Symbol(z, Decl(readonlyInDeclarationFile.ts, 34, 3)) + + readonly a: string; +>a : Symbol(a, Decl(readonlyInDeclarationFile.ts, 34, 8)) + + readonly [x: string]: Object; +>x : Symbol(x, Decl(readonlyInDeclarationFile.ts, 36, 14)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +} + +function f() { +>f : Symbol(f, Decl(readonlyInDeclarationFile.ts, 37, 1)) + + return { + get x() { return 1; }, +>x : Symbol(x, Decl(readonlyInDeclarationFile.ts, 40, 12)) + + get y() { return 1; }, +>y : Symbol(y, Decl(readonlyInDeclarationFile.ts, 41, 30), Decl(readonlyInDeclarationFile.ts, 42, 30)) + + set y(value) { } +>y : Symbol(y, Decl(readonlyInDeclarationFile.ts, 41, 30), Decl(readonlyInDeclarationFile.ts, 42, 30)) +>value : Symbol(value, Decl(readonlyInDeclarationFile.ts, 43, 14)) + } +} + +function g() { +>g : Symbol(g, Decl(readonlyInDeclarationFile.ts, 45, 1)) + + var x: { +>x : Symbol(x, Decl(readonlyInDeclarationFile.ts, 48, 7)) + + readonly a: string; +>a : Symbol(a, Decl(readonlyInDeclarationFile.ts, 48, 12)) + + readonly [x: string]: Object; +>x : Symbol(x, Decl(readonlyInDeclarationFile.ts, 50, 18)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) + } + return x; +>x : Symbol(x, Decl(readonlyInDeclarationFile.ts, 48, 7)) +} diff --git a/tests/baselines/reference/readonlyInDeclarationFile.types b/tests/baselines/reference/readonlyInDeclarationFile.types new file mode 100644 index 0000000000..7a3e11577c --- /dev/null +++ b/tests/baselines/reference/readonlyInDeclarationFile.types @@ -0,0 +1,158 @@ +=== tests/cases/compiler/readonlyInDeclarationFile.ts === + +interface Foo { +>Foo : Foo + + readonly x: number; +>x : number + + readonly [x: string]: Object; +>x : string +>Object : Object +} + +class C { +>C : C + + readonly [x: string]: Object; +>x : string +>Object : Object + + private readonly a1: number; +>a1 : number + + protected readonly a2: number; +>a2 : number + + public readonly a3: number; +>a3 : number + + private get b1() { return 1 } +>b1 : number +>1 : number + + protected get b2() { return 1 } +>b2 : number +>1 : number + + public get b3() { return 1 } +>b3 : number +>1 : number + + private get c1() { return 1 } +>c1 : number +>1 : number + + private set c1(value) { } +>c1 : number +>value : number + + protected get c2() { return 1 } +>c2 : number +>1 : number + + protected set c2(value) { } +>c2 : number +>value : number + + public get c3() { return 1 } +>c3 : number +>1 : number + + public set c3(value) { } +>c3 : number +>value : number + + private static readonly s1: number; +>s1 : number + + protected static readonly s2: number; +>s2 : number + + public static readonly s3: number; +>s3 : number + + private static get t1() { return 1 } +>t1 : number +>1 : number + + protected static get t2() { return 1 } +>t2 : number +>1 : number + + public static get t3() { return 1 } +>t3 : number +>1 : number + + private static get u1() { return 1 } +>u1 : number +>1 : number + + private static set u1(value) { } +>u1 : number +>value : number + + protected static get u2() { return 1 } +>u2 : number +>1 : number + + protected static set u2(value) { } +>u2 : number +>value : number + + public static get u3() { return 1 } +>u3 : number +>1 : number + + public static set u3(value) { } +>u3 : number +>value : number +} + +var z: { +>z : { readonly [x: string]: Object; readonly a: string; } + + readonly a: string; +>a : string + + readonly [x: string]: Object; +>x : string +>Object : Object +} + +function f() { +>f : () => { readonly x: number; y: number; } + + return { +>{ get x() { return 1; }, get y() { return 1; }, set y(value) { } } : { readonly x: number; y: number; } + + get x() { return 1; }, +>x : number +>1 : number + + get y() { return 1; }, +>y : number +>1 : number + + set y(value) { } +>y : number +>value : number + } +} + +function g() { +>g : () => { readonly [x: string]: Object; readonly a: string; } + + var x: { +>x : { readonly [x: string]: Object; readonly a: string; } + + readonly a: string; +>a : string + + readonly [x: string]: Object; +>x : string +>Object : Object + } + return x; +>x : { readonly [x: string]: Object; readonly a: string; } +} diff --git a/tests/baselines/reference/symbolDeclarationEmit13.js b/tests/baselines/reference/symbolDeclarationEmit13.js index 8111672866..bbd2c15cfc 100644 --- a/tests/baselines/reference/symbolDeclarationEmit13.js +++ b/tests/baselines/reference/symbolDeclarationEmit13.js @@ -13,6 +13,6 @@ class C { //// [symbolDeclarationEmit13.d.ts] declare class C { - [Symbol.toPrimitive]: string; + readonly [Symbol.toPrimitive]: string; [Symbol.toStringTag]: any; } diff --git a/tests/baselines/reference/symbolDeclarationEmit14.js b/tests/baselines/reference/symbolDeclarationEmit14.js index b8a6b3e409..d4ae3eeb43 100644 --- a/tests/baselines/reference/symbolDeclarationEmit14.js +++ b/tests/baselines/reference/symbolDeclarationEmit14.js @@ -13,6 +13,6 @@ class C { //// [symbolDeclarationEmit14.d.ts] declare class C { - [Symbol.toPrimitive]: string; - [Symbol.toStringTag]: string; + readonly [Symbol.toPrimitive]: string; + readonly [Symbol.toStringTag]: string; } diff --git a/tests/baselines/reference/typeGuardOfFormThisMember.js b/tests/baselines/reference/typeGuardOfFormThisMember.js index 2f983d2cdf..9d71613ed8 100644 --- a/tests/baselines/reference/typeGuardOfFormThisMember.js +++ b/tests/baselines/reference/typeGuardOfFormThisMember.js @@ -170,7 +170,7 @@ declare namespace Test { path: string; isFSO: this is FileSystemObject; isFile: this is File; - isDirectory: this is Directory; + readonly isDirectory: this is Directory; isNetworked: this is (Networked & this); constructor(path: string); } diff --git a/tests/baselines/reference/typeGuardOfFormThisMemberErrors.js b/tests/baselines/reference/typeGuardOfFormThisMemberErrors.js index 6f681ab09c..5991fdd316 100644 --- a/tests/baselines/reference/typeGuardOfFormThisMemberErrors.js +++ b/tests/baselines/reference/typeGuardOfFormThisMemberErrors.js @@ -95,7 +95,7 @@ declare namespace Test { path: string; isFSO: this is FileSystemObject; isFile: this is File; - isDirectory: this is Directory; + readonly isDirectory: this is Directory; isNetworked: this is (Networked & this); constructor(path: string); } diff --git a/tests/cases/compiler/deduplicateImportsInSystem.ts b/tests/cases/compiler/deduplicateImportsInSystem.ts new file mode 100644 index 0000000000..2fcbc16be0 --- /dev/null +++ b/tests/cases/compiler/deduplicateImportsInSystem.ts @@ -0,0 +1,9 @@ +// @module: system +import {A} from "f1"; +import {B} from "f2"; +import {C} from "f3"; +import {D} from 'f2'; +import {E} from "f2"; +import {F} from 'f1'; + +console.log(A + B + C + D + E + F) \ No newline at end of file diff --git a/tests/cases/compiler/readonlyInDeclarationFile.ts b/tests/cases/compiler/readonlyInDeclarationFile.ts new file mode 100644 index 0000000000..03e643782f --- /dev/null +++ b/tests/cases/compiler/readonlyInDeclarationFile.ts @@ -0,0 +1,56 @@ +// @target: es5 +// @declaration: true + +interface Foo { + readonly x: number; + readonly [x: string]: Object; +} + +class C { + readonly [x: string]: Object; + private readonly a1: number; + protected readonly a2: number; + public readonly a3: number; + private get b1() { return 1 } + protected get b2() { return 1 } + public get b3() { return 1 } + private get c1() { return 1 } + private set c1(value) { } + protected get c2() { return 1 } + protected set c2(value) { } + public get c3() { return 1 } + public set c3(value) { } + private static readonly s1: number; + protected static readonly s2: number; + public static readonly s3: number; + private static get t1() { return 1 } + protected static get t2() { return 1 } + public static get t3() { return 1 } + private static get u1() { return 1 } + private static set u1(value) { } + protected static get u2() { return 1 } + protected static set u2(value) { } + public static get u3() { return 1 } + public static set u3(value) { } +} + +var z: { + readonly a: string; + readonly [x: string]: Object; +} + +function f() { + return { + get x() { return 1; }, + get y() { return 1; }, + set y(value) { } + } +} + +function g() { + var x: { + readonly a: string; + readonly [x: string]: Object; + } + return x; +} \ No newline at end of file diff --git a/tests/cases/fourslash/getJavaScriptCompletions18.ts b/tests/cases/fourslash/getJavaScriptCompletions18.ts new file mode 100644 index 0000000000..a30d4943f4 --- /dev/null +++ b/tests/cases/fourslash/getJavaScriptCompletions18.ts @@ -0,0 +1,21 @@ +/// + +// @allowNonTsExtensions: true +// @Filename: file.js +//// /** +//// * @param {number} a +//// * @param {string} b +//// */ +//// exports.foo = function(a, b) { +//// a/*a*/; +//// b/*b*/ +//// }; + +goTo.marker('a'); +edit.insert('.'); +verify.completionListContains('toFixed', undefined, undefined, 'method'); + + +goTo.marker('b'); +edit.insert('.'); +verify.completionListContains('substr', undefined, undefined, 'method'); diff --git a/tests/cases/fourslash/getJavaScriptCompletions19.ts b/tests/cases/fourslash/getJavaScriptCompletions19.ts new file mode 100644 index 0000000000..5a361930e8 --- /dev/null +++ b/tests/cases/fourslash/getJavaScriptCompletions19.ts @@ -0,0 +1,25 @@ +/// + +// @allowNonTsExtensions: true +// @Filename: file.js +//// function fn() { +//// if (foo) { +//// return 0; +//// } else { +//// return '0'; +//// } +//// } +//// let x = fn(); +//// if(typeof x === 'string') { +//// x/*str*/ +//// } else { +//// x/*num*/ +//// } + +goTo.marker('str'); +edit.insert('.'); +verify.completionListContains('substr', undefined, undefined, 'method'); + +goTo.marker('num'); +edit.insert('.'); +verify.completionListContains('toFixed', undefined, undefined, 'method'); diff --git a/tests/cases/fourslash/renameCrossJsTs01.ts b/tests/cases/fourslash/renameCrossJsTs01.ts new file mode 100644 index 0000000000..52cb4c587d --- /dev/null +++ b/tests/cases/fourslash/renameCrossJsTs01.ts @@ -0,0 +1,12 @@ +/// + +// @allowJs: true +// @Filename: a.js +////exports.[|area|] = function (r) { return r * r; } + +// @Filename: b.ts +////import { [|area|] } from './a'; +////var t = /**/[|area|](10); + +goTo.marker(); +verify.renameLocations( /*findInStrings*/ false, /*findInComments*/ false); \ No newline at end of file diff --git a/tests/cases/fourslash/renameCrossJsTs02.ts b/tests/cases/fourslash/renameCrossJsTs02.ts new file mode 100644 index 0000000000..7ff1ae96ff --- /dev/null +++ b/tests/cases/fourslash/renameCrossJsTs02.ts @@ -0,0 +1,12 @@ +/// + +// @allowJs: true +// @Filename: a.js +////exports./**/[|area|] = function (r) { return r * r; } + +// @Filename: b.ts +////import { [|area|] } from './a'; +////var t = [|area|](10); + +goTo.marker(); +verify.renameLocations( /*findInStrings*/ false, /*findInComments*/ false); \ No newline at end of file diff --git a/tests/cases/fourslash/renameJsExports01.ts b/tests/cases/fourslash/renameJsExports01.ts new file mode 100644 index 0000000000..923d30eedf --- /dev/null +++ b/tests/cases/fourslash/renameJsExports01.ts @@ -0,0 +1,12 @@ +/// + +// @allowJs: true +// @Filename: a.js +////exports.[|area|] = function (r) { return r * r; } + +// @Filename: b.js +////var mod = require('./a'); +////var t = mod./**/[|area|](10); + +goTo.marker(); +verify.renameLocations( /*findInStrings*/ false, /*findInComments*/ false); \ No newline at end of file diff --git a/tests/cases/fourslash/renameJsExports02.ts b/tests/cases/fourslash/renameJsExports02.ts new file mode 100644 index 0000000000..86b0471dc1 --- /dev/null +++ b/tests/cases/fourslash/renameJsExports02.ts @@ -0,0 +1,12 @@ +/// + +// @allowJs: true +// @Filename: a.js +////exports./**/[|area|] = function (r) { return r * r; } + +// @Filename: b.js +////var mod = require('./a'); +////var t = mod.[|area|](10); + +goTo.marker(); +verify.renameLocations( /*findInStrings*/ false, /*findInComments*/ false); \ No newline at end of file diff --git a/tests/cases/fourslash/renameJsPrototypeProperty01.ts b/tests/cases/fourslash/renameJsPrototypeProperty01.ts new file mode 100644 index 0000000000..f756f57edb --- /dev/null +++ b/tests/cases/fourslash/renameJsPrototypeProperty01.ts @@ -0,0 +1,12 @@ +/// + +// @allowJs: true +// @Filename: a.js +////function bar() { +////} +////bar.prototype.[|x|] = 10; +////var t = new bar(); +////t./**/[|x|] = 11; + +goTo.marker(); +verify.renameLocations( /*findInStrings*/ false, /*findInComments*/ false); \ No newline at end of file diff --git a/tests/cases/fourslash/renameJsPrototypeProperty02.ts b/tests/cases/fourslash/renameJsPrototypeProperty02.ts new file mode 100644 index 0000000000..721dc312eb --- /dev/null +++ b/tests/cases/fourslash/renameJsPrototypeProperty02.ts @@ -0,0 +1,12 @@ +/// + +// @allowJs: true +// @Filename: a.js +////function bar() { +////} +////bar.prototype./**/[|x|] = 10; +////var t = new bar(); +////t.[|x|] = 11; + +goTo.marker(); +verify.renameLocations( /*findInStrings*/ false, /*findInComments*/ false); \ No newline at end of file diff --git a/tests/cases/fourslash/renameJsThisProperty01.ts b/tests/cases/fourslash/renameJsThisProperty01.ts new file mode 100644 index 0000000000..91338e0431 --- /dev/null +++ b/tests/cases/fourslash/renameJsThisProperty01.ts @@ -0,0 +1,12 @@ +/// + +// @allowJs: true +// @Filename: a.js +////function bar() { +//// this.[|x|] = 10; +////} +////var t = new bar(); +////t./**/[|x|] = 11; + +goTo.marker(); +verify.renameLocations( /*findInStrings*/ false, /*findInComments*/ false); \ No newline at end of file diff --git a/tests/cases/fourslash/renameJsThisProperty02.ts b/tests/cases/fourslash/renameJsThisProperty02.ts new file mode 100644 index 0000000000..8398507c9c --- /dev/null +++ b/tests/cases/fourslash/renameJsThisProperty02.ts @@ -0,0 +1,12 @@ +/// + +// @allowJs: true +// @Filename: a.js +////function bar() { +//// this./**/[|x|] = 10; +////} +////var t = new bar(); +////t.[|x|] = 11; + +goTo.marker(); +verify.renameLocations( /*findInStrings*/ false, /*findInComments*/ false); \ No newline at end of file