Merge pull request #14273 from Microsoft/infereClassPropertiesFromMethods
Infer class properties from methods and not just constructors in .js files
This commit is contained in:
commit
89f43d13e0
|
@ -2297,23 +2297,28 @@ namespace ts {
|
||||||
|
|
||||||
function bindThisPropertyAssignment(node: BinaryExpression) {
|
function bindThisPropertyAssignment(node: BinaryExpression) {
|
||||||
Debug.assert(isInJavaScriptFile(node));
|
Debug.assert(isInJavaScriptFile(node));
|
||||||
|
switch (container.kind) {
|
||||||
|
case SyntaxKind.FunctionDeclaration:
|
||||||
|
case SyntaxKind.FunctionExpression:
|
||||||
// Declare a 'member' if the container is an ES5 class or ES6 constructor
|
// Declare a 'member' if the container is an ES5 class or ES6 constructor
|
||||||
if (container.kind === SyntaxKind.FunctionDeclaration || container.kind === SyntaxKind.FunctionExpression) {
|
|
||||||
container.symbol.members = container.symbol.members || createMap<Symbol>();
|
container.symbol.members = container.symbol.members || createMap<Symbol>();
|
||||||
// It's acceptable for multiple 'this' assignments of the same identifier to occur
|
// It's acceptable for multiple 'this' assignments of the same identifier to occur
|
||||||
declareSymbol(container.symbol.members, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property);
|
declareSymbol(container.symbol.members, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property);
|
||||||
}
|
break;
|
||||||
else if (container.kind === SyntaxKind.Constructor) {
|
|
||||||
|
case SyntaxKind.Constructor:
|
||||||
|
case SyntaxKind.MethodDeclaration:
|
||||||
|
case SyntaxKind.GetAccessor:
|
||||||
|
case SyntaxKind.SetAccessor:
|
||||||
// this.foo assignment in a JavaScript class
|
// this.foo assignment in a JavaScript class
|
||||||
// Bind this property to the containing class
|
// Bind this property to the containing class
|
||||||
const saveContainer = container;
|
const containingClass = container.parent;
|
||||||
container = container.parent;
|
const symbol = declareSymbol(hasModifier(container, ModifierFlags.Static) ? containingClass.symbol.exports : containingClass.symbol.members, containingClass.symbol, node, SymbolFlags.Property, SymbolFlags.None);
|
||||||
const symbol = bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property, SymbolFlags.None);
|
|
||||||
if (symbol) {
|
if (symbol) {
|
||||||
// constructor-declared symbols can be overwritten by subsequent method declarations
|
// symbols declared through 'this' property assignements can be overwritten by subsequent method declarations
|
||||||
(symbol as Symbol).isReplaceableByMethod = true;
|
(symbol as Symbol).isReplaceableByMethod = true;
|
||||||
}
|
}
|
||||||
container = saveContainer;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3488,8 +3488,11 @@ namespace ts {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the inferred type for a variable, parameter, or property declaration
|
function getWidenedTypeFromJSSpecialPropertyDeclarations(symbol: Symbol) {
|
||||||
function getTypeForJSSpecialPropertyDeclaration(declaration: Declaration): Type {
|
const types: Type[] = [];
|
||||||
|
let definedInConstructor = false;
|
||||||
|
let definedInMethod = false;
|
||||||
|
for (const declaration of symbol.declarations) {
|
||||||
const expression = declaration.kind === SyntaxKind.BinaryExpression ? <BinaryExpression>declaration :
|
const expression = declaration.kind === SyntaxKind.BinaryExpression ? <BinaryExpression>declaration :
|
||||||
declaration.kind === SyntaxKind.PropertyAccessExpression ? <BinaryExpression>getAncestor(declaration, SyntaxKind.BinaryExpression) :
|
declaration.kind === SyntaxKind.PropertyAccessExpression ? <BinaryExpression>getAncestor(declaration, SyntaxKind.BinaryExpression) :
|
||||||
undefined;
|
undefined;
|
||||||
|
@ -3498,15 +3501,28 @@ namespace ts {
|
||||||
return unknownType;
|
return unknownType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isPropertyAccessExpression(expression.left) && expression.left.expression.kind === SyntaxKind.ThisKeyword) {
|
||||||
|
if (getThisContainer(expression, /*includeArrowFunctions*/ false).kind === SyntaxKind.Constructor) {
|
||||||
|
definedInConstructor = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
definedInMethod = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (expression.flags & NodeFlags.JavaScriptFile) {
|
if (expression.flags & NodeFlags.JavaScriptFile) {
|
||||||
// If there is a JSDoc type, use it
|
// If there is a JSDoc type, use it
|
||||||
const type = getTypeForDeclarationFromJSDocComment(expression.parent);
|
const type = getTypeForDeclarationFromJSDocComment(expression.parent);
|
||||||
if (type && type !== unknownType) {
|
if (type && type !== unknownType) {
|
||||||
return getWidenedType(type);
|
types.push(getWidenedType(type));
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return getWidenedLiteralType(checkExpressionCached(expression.right));
|
types.push(getWidenedLiteralType(checkExpressionCached(expression.right)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return getWidenedType(addOptionality(getUnionType(types, /*subtypeReduction*/ true), definedInMethod && !definedInConstructor));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the type implied by a binding pattern element. This is the type of the initializer of the element if
|
// Return the type implied by a binding pattern element. This is the type of the initializer of the element if
|
||||||
|
@ -3663,7 +3679,7 @@ namespace ts {
|
||||||
// * className.prototype.method = expr
|
// * className.prototype.method = expr
|
||||||
if (declaration.kind === SyntaxKind.BinaryExpression ||
|
if (declaration.kind === SyntaxKind.BinaryExpression ||
|
||||||
declaration.kind === SyntaxKind.PropertyAccessExpression && declaration.parent.kind === SyntaxKind.BinaryExpression) {
|
declaration.kind === SyntaxKind.PropertyAccessExpression && declaration.parent.kind === SyntaxKind.BinaryExpression) {
|
||||||
type = getWidenedType(getUnionType(map(symbol.declarations, getTypeForJSSpecialPropertyDeclaration), /*subtypeReduction*/ true));
|
type = getWidenedTypeFromJSSpecialPropertyDeclarations(symbol);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
type = getWidenedTypeForVariableLikeDeclaration(<VariableLikeDeclaration>declaration, /*reportErrors*/ true);
|
type = getWidenedTypeForVariableLikeDeclaration(<VariableLikeDeclaration>declaration, /*reportErrors*/ true);
|
||||||
|
|
|
@ -0,0 +1,163 @@
|
||||||
|
//// [tests/cases/conformance/salsa/inferringClassMembersFromAssignments.ts] ////
|
||||||
|
|
||||||
|
//// [a.js]
|
||||||
|
|
||||||
|
class C {
|
||||||
|
constructor() {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inConstructor = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inConstructor = "string"
|
||||||
|
}
|
||||||
|
this.inMultiple = 0;
|
||||||
|
}
|
||||||
|
method() {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inMethod = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inMethod = "string"
|
||||||
|
}
|
||||||
|
this.inMultiple = "string";
|
||||||
|
}
|
||||||
|
get() {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inGetter = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inGetter = "string"
|
||||||
|
}
|
||||||
|
this.inMultiple = false;
|
||||||
|
}
|
||||||
|
set() {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inSetter = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inSetter = "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static method() {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inStaticMethod = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inStaticMethod = "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static get() {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inStaticGetter = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inStaticGetter = "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static set() {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inStaticSetter = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inStaticSetter = "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//// [b.ts]
|
||||||
|
var c = new C();
|
||||||
|
|
||||||
|
var stringOrNumber: string | number;
|
||||||
|
var stringOrNumber = c.inConstructor;
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined: string | number | undefined;
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined = c.inMethod;
|
||||||
|
var stringOrNumberOrUndefined = c.inGetter;
|
||||||
|
var stringOrNumberOrUndefined = c.inSetter;
|
||||||
|
|
||||||
|
var stringOrNumberOrBoolean: string | number | boolean;
|
||||||
|
|
||||||
|
var stringOrNumberOrBoolean = c.inMultiple;
|
||||||
|
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined = C.inStaticMethod;
|
||||||
|
var stringOrNumberOrUndefined = C.inStaticGetter;
|
||||||
|
var stringOrNumberOrUndefined = C.inStaticSetter;
|
||||||
|
|
||||||
|
|
||||||
|
//// [output.js]
|
||||||
|
var C = (function () {
|
||||||
|
function C() {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inConstructor = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inConstructor = "string";
|
||||||
|
}
|
||||||
|
this.inMultiple = 0;
|
||||||
|
}
|
||||||
|
C.prototype.method = function () {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inMethod = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inMethod = "string";
|
||||||
|
}
|
||||||
|
this.inMultiple = "string";
|
||||||
|
};
|
||||||
|
C.prototype.get = function () {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inGetter = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inGetter = "string";
|
||||||
|
}
|
||||||
|
this.inMultiple = false;
|
||||||
|
};
|
||||||
|
C.prototype.set = function () {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inSetter = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inSetter = "string";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
C.method = function () {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inStaticMethod = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inStaticMethod = "string";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
C.get = function () {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inStaticGetter = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inStaticGetter = "string";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
C.set = function () {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inStaticSetter = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inStaticSetter = "string";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return C;
|
||||||
|
}());
|
||||||
|
var c = new C();
|
||||||
|
var stringOrNumber;
|
||||||
|
var stringOrNumber = c.inConstructor;
|
||||||
|
var stringOrNumberOrUndefined;
|
||||||
|
var stringOrNumberOrUndefined = c.inMethod;
|
||||||
|
var stringOrNumberOrUndefined = c.inGetter;
|
||||||
|
var stringOrNumberOrUndefined = c.inSetter;
|
||||||
|
var stringOrNumberOrBoolean;
|
||||||
|
var stringOrNumberOrBoolean = c.inMultiple;
|
||||||
|
var stringOrNumberOrUndefined = C.inStaticMethod;
|
||||||
|
var stringOrNumberOrUndefined = C.inStaticGetter;
|
||||||
|
var stringOrNumberOrUndefined = C.inStaticSetter;
|
|
@ -0,0 +1,220 @@
|
||||||
|
=== tests/cases/conformance/salsa/a.js ===
|
||||||
|
|
||||||
|
class C {
|
||||||
|
>C : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
if (Math.random()) {
|
||||||
|
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||||
|
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||||
|
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||||
|
|
||||||
|
this.inConstructor = 0;
|
||||||
|
>this.inConstructor : Symbol(C.inConstructor, Decl(a.js, 3, 28), Decl(a.js, 6, 14))
|
||||||
|
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inConstructor : Symbol(C.inConstructor, Decl(a.js, 3, 28), Decl(a.js, 6, 14))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inConstructor = "string"
|
||||||
|
>this.inConstructor : Symbol(C.inConstructor, Decl(a.js, 3, 28), Decl(a.js, 6, 14))
|
||||||
|
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inConstructor : Symbol(C.inConstructor, Decl(a.js, 3, 28), Decl(a.js, 6, 14))
|
||||||
|
}
|
||||||
|
this.inMultiple = 0;
|
||||||
|
>this.inMultiple : Symbol(C.inMultiple, Decl(a.js, 8, 9), Decl(a.js, 17, 9), Decl(a.js, 26, 9))
|
||||||
|
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inMultiple : Symbol(C.inMultiple, Decl(a.js, 8, 9), Decl(a.js, 17, 9), Decl(a.js, 26, 9))
|
||||||
|
}
|
||||||
|
method() {
|
||||||
|
>method : Symbol(C.method, Decl(a.js, 10, 5))
|
||||||
|
|
||||||
|
if (Math.random()) {
|
||||||
|
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||||
|
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||||
|
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||||
|
|
||||||
|
this.inMethod = 0;
|
||||||
|
>this.inMethod : Symbol(C.inMethod, Decl(a.js, 12, 28), Decl(a.js, 15, 14))
|
||||||
|
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inMethod : Symbol(C.inMethod, Decl(a.js, 12, 28), Decl(a.js, 15, 14))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inMethod = "string"
|
||||||
|
>this.inMethod : Symbol(C.inMethod, Decl(a.js, 12, 28), Decl(a.js, 15, 14))
|
||||||
|
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inMethod : Symbol(C.inMethod, Decl(a.js, 12, 28), Decl(a.js, 15, 14))
|
||||||
|
}
|
||||||
|
this.inMultiple = "string";
|
||||||
|
>this.inMultiple : Symbol(C.inMultiple, Decl(a.js, 8, 9), Decl(a.js, 17, 9), Decl(a.js, 26, 9))
|
||||||
|
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inMultiple : Symbol(C.inMultiple, Decl(a.js, 8, 9), Decl(a.js, 17, 9), Decl(a.js, 26, 9))
|
||||||
|
}
|
||||||
|
get() {
|
||||||
|
>get : Symbol(C.get, Decl(a.js, 19, 5))
|
||||||
|
|
||||||
|
if (Math.random()) {
|
||||||
|
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||||
|
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||||
|
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||||
|
|
||||||
|
this.inGetter = 0;
|
||||||
|
>this.inGetter : Symbol(C.inGetter, Decl(a.js, 21, 28), Decl(a.js, 24, 14))
|
||||||
|
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inGetter : Symbol(C.inGetter, Decl(a.js, 21, 28), Decl(a.js, 24, 14))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inGetter = "string"
|
||||||
|
>this.inGetter : Symbol(C.inGetter, Decl(a.js, 21, 28), Decl(a.js, 24, 14))
|
||||||
|
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inGetter : Symbol(C.inGetter, Decl(a.js, 21, 28), Decl(a.js, 24, 14))
|
||||||
|
}
|
||||||
|
this.inMultiple = false;
|
||||||
|
>this.inMultiple : Symbol(C.inMultiple, Decl(a.js, 8, 9), Decl(a.js, 17, 9), Decl(a.js, 26, 9))
|
||||||
|
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inMultiple : Symbol(C.inMultiple, Decl(a.js, 8, 9), Decl(a.js, 17, 9), Decl(a.js, 26, 9))
|
||||||
|
}
|
||||||
|
set() {
|
||||||
|
>set : Symbol(C.set, Decl(a.js, 28, 5))
|
||||||
|
|
||||||
|
if (Math.random()) {
|
||||||
|
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||||
|
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||||
|
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||||
|
|
||||||
|
this.inSetter = 0;
|
||||||
|
>this.inSetter : Symbol(C.inSetter, Decl(a.js, 30, 28), Decl(a.js, 33, 14))
|
||||||
|
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inSetter : Symbol(C.inSetter, Decl(a.js, 30, 28), Decl(a.js, 33, 14))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inSetter = "string"
|
||||||
|
>this.inSetter : Symbol(C.inSetter, Decl(a.js, 30, 28), Decl(a.js, 33, 14))
|
||||||
|
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inSetter : Symbol(C.inSetter, Decl(a.js, 30, 28), Decl(a.js, 33, 14))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static method() {
|
||||||
|
>method : Symbol(C.method, Decl(a.js, 36, 5))
|
||||||
|
|
||||||
|
if (Math.random()) {
|
||||||
|
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||||
|
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||||
|
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||||
|
|
||||||
|
this.inStaticMethod = 0;
|
||||||
|
>this.inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
|
||||||
|
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inStaticMethod = "string"
|
||||||
|
>this.inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
|
||||||
|
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static get() {
|
||||||
|
>get : Symbol(C.get, Decl(a.js, 44, 5))
|
||||||
|
|
||||||
|
if (Math.random()) {
|
||||||
|
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||||
|
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||||
|
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||||
|
|
||||||
|
this.inStaticGetter = 0;
|
||||||
|
>this.inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
|
||||||
|
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inStaticGetter = "string"
|
||||||
|
>this.inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
|
||||||
|
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static set() {
|
||||||
|
>set : Symbol(C.set, Decl(a.js, 52, 5))
|
||||||
|
|
||||||
|
if (Math.random()) {
|
||||||
|
>Math.random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||||
|
>Math : Symbol(Math, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||||
|
>random : Symbol(Math.random, Decl(lib.d.ts, --, --))
|
||||||
|
|
||||||
|
this.inStaticSetter = 0;
|
||||||
|
>this.inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
|
||||||
|
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inStaticSetter = "string"
|
||||||
|
>this.inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
|
||||||
|
>this : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
=== tests/cases/conformance/salsa/b.ts ===
|
||||||
|
var c = new C();
|
||||||
|
>c : Symbol(c, Decl(b.ts, 0, 3))
|
||||||
|
>C : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
|
||||||
|
var stringOrNumber: string | number;
|
||||||
|
>stringOrNumber : Symbol(stringOrNumber, Decl(b.ts, 2, 3), Decl(b.ts, 3, 3))
|
||||||
|
|
||||||
|
var stringOrNumber = c.inConstructor;
|
||||||
|
>stringOrNumber : Symbol(stringOrNumber, Decl(b.ts, 2, 3), Decl(b.ts, 3, 3))
|
||||||
|
>c.inConstructor : Symbol(C.inConstructor, Decl(a.js, 3, 28), Decl(a.js, 6, 14))
|
||||||
|
>c : Symbol(c, Decl(b.ts, 0, 3))
|
||||||
|
>inConstructor : Symbol(C.inConstructor, Decl(a.js, 3, 28), Decl(a.js, 6, 14))
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined: string | number | undefined;
|
||||||
|
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 16, 3), Decl(b.ts, 17, 3), Decl(b.ts, 18, 3))
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined = c.inMethod;
|
||||||
|
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 16, 3), Decl(b.ts, 17, 3), Decl(b.ts, 18, 3))
|
||||||
|
>c.inMethod : Symbol(C.inMethod, Decl(a.js, 12, 28), Decl(a.js, 15, 14))
|
||||||
|
>c : Symbol(c, Decl(b.ts, 0, 3))
|
||||||
|
>inMethod : Symbol(C.inMethod, Decl(a.js, 12, 28), Decl(a.js, 15, 14))
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined = c.inGetter;
|
||||||
|
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 16, 3), Decl(b.ts, 17, 3), Decl(b.ts, 18, 3))
|
||||||
|
>c.inGetter : Symbol(C.inGetter, Decl(a.js, 21, 28), Decl(a.js, 24, 14))
|
||||||
|
>c : Symbol(c, Decl(b.ts, 0, 3))
|
||||||
|
>inGetter : Symbol(C.inGetter, Decl(a.js, 21, 28), Decl(a.js, 24, 14))
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined = c.inSetter;
|
||||||
|
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 16, 3), Decl(b.ts, 17, 3), Decl(b.ts, 18, 3))
|
||||||
|
>c.inSetter : Symbol(C.inSetter, Decl(a.js, 30, 28), Decl(a.js, 33, 14))
|
||||||
|
>c : Symbol(c, Decl(b.ts, 0, 3))
|
||||||
|
>inSetter : Symbol(C.inSetter, Decl(a.js, 30, 28), Decl(a.js, 33, 14))
|
||||||
|
|
||||||
|
var stringOrNumberOrBoolean: string | number | boolean;
|
||||||
|
>stringOrNumberOrBoolean : Symbol(stringOrNumberOrBoolean, Decl(b.ts, 11, 3), Decl(b.ts, 13, 3))
|
||||||
|
|
||||||
|
var stringOrNumberOrBoolean = c.inMultiple;
|
||||||
|
>stringOrNumberOrBoolean : Symbol(stringOrNumberOrBoolean, Decl(b.ts, 11, 3), Decl(b.ts, 13, 3))
|
||||||
|
>c.inMultiple : Symbol(C.inMultiple, Decl(a.js, 8, 9), Decl(a.js, 17, 9), Decl(a.js, 26, 9))
|
||||||
|
>c : Symbol(c, Decl(b.ts, 0, 3))
|
||||||
|
>inMultiple : Symbol(C.inMultiple, Decl(a.js, 8, 9), Decl(a.js, 17, 9), Decl(a.js, 26, 9))
|
||||||
|
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined = C.inStaticMethod;
|
||||||
|
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 16, 3), Decl(b.ts, 17, 3), Decl(b.ts, 18, 3))
|
||||||
|
>C.inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
|
||||||
|
>C : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inStaticMethod : Symbol(C.inStaticMethod, Decl(a.js, 38, 28), Decl(a.js, 41, 14))
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined = C.inStaticGetter;
|
||||||
|
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 16, 3), Decl(b.ts, 17, 3), Decl(b.ts, 18, 3))
|
||||||
|
>C.inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
|
||||||
|
>C : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inStaticGetter : Symbol(C.inStaticGetter, Decl(a.js, 46, 28), Decl(a.js, 49, 14))
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined = C.inStaticSetter;
|
||||||
|
>stringOrNumberOrUndefined : Symbol(stringOrNumberOrUndefined, Decl(b.ts, 5, 3), Decl(b.ts, 7, 3), Decl(b.ts, 8, 3), Decl(b.ts, 9, 3), Decl(b.ts, 16, 3), Decl(b.ts, 17, 3), Decl(b.ts, 18, 3))
|
||||||
|
>C.inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
|
||||||
|
>C : Symbol(C, Decl(a.js, 0, 0))
|
||||||
|
>inStaticSetter : Symbol(C.inStaticSetter, Decl(a.js, 54, 28), Decl(a.js, 57, 14))
|
||||||
|
|
|
@ -0,0 +1,262 @@
|
||||||
|
=== tests/cases/conformance/salsa/a.js ===
|
||||||
|
|
||||||
|
class C {
|
||||||
|
>C : C
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
if (Math.random()) {
|
||||||
|
>Math.random() : number
|
||||||
|
>Math.random : () => number
|
||||||
|
>Math : Math
|
||||||
|
>random : () => number
|
||||||
|
|
||||||
|
this.inConstructor = 0;
|
||||||
|
>this.inConstructor = 0 : 0
|
||||||
|
>this.inConstructor : string | number
|
||||||
|
>this : this
|
||||||
|
>inConstructor : string | number
|
||||||
|
>0 : 0
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inConstructor = "string"
|
||||||
|
>this.inConstructor = "string" : "string"
|
||||||
|
>this.inConstructor : string | number
|
||||||
|
>this : this
|
||||||
|
>inConstructor : string | number
|
||||||
|
>"string" : "string"
|
||||||
|
}
|
||||||
|
this.inMultiple = 0;
|
||||||
|
>this.inMultiple = 0 : 0
|
||||||
|
>this.inMultiple : string | number | boolean
|
||||||
|
>this : this
|
||||||
|
>inMultiple : string | number | boolean
|
||||||
|
>0 : 0
|
||||||
|
}
|
||||||
|
method() {
|
||||||
|
>method : () => void
|
||||||
|
|
||||||
|
if (Math.random()) {
|
||||||
|
>Math.random() : number
|
||||||
|
>Math.random : () => number
|
||||||
|
>Math : Math
|
||||||
|
>random : () => number
|
||||||
|
|
||||||
|
this.inMethod = 0;
|
||||||
|
>this.inMethod = 0 : 0
|
||||||
|
>this.inMethod : string | number | undefined
|
||||||
|
>this : this
|
||||||
|
>inMethod : string | number | undefined
|
||||||
|
>0 : 0
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inMethod = "string"
|
||||||
|
>this.inMethod = "string" : "string"
|
||||||
|
>this.inMethod : string | number | undefined
|
||||||
|
>this : this
|
||||||
|
>inMethod : string | number | undefined
|
||||||
|
>"string" : "string"
|
||||||
|
}
|
||||||
|
this.inMultiple = "string";
|
||||||
|
>this.inMultiple = "string" : "string"
|
||||||
|
>this.inMultiple : string | number | boolean
|
||||||
|
>this : this
|
||||||
|
>inMultiple : string | number | boolean
|
||||||
|
>"string" : "string"
|
||||||
|
}
|
||||||
|
get() {
|
||||||
|
>get : () => void
|
||||||
|
|
||||||
|
if (Math.random()) {
|
||||||
|
>Math.random() : number
|
||||||
|
>Math.random : () => number
|
||||||
|
>Math : Math
|
||||||
|
>random : () => number
|
||||||
|
|
||||||
|
this.inGetter = 0;
|
||||||
|
>this.inGetter = 0 : 0
|
||||||
|
>this.inGetter : string | number | undefined
|
||||||
|
>this : this
|
||||||
|
>inGetter : string | number | undefined
|
||||||
|
>0 : 0
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inGetter = "string"
|
||||||
|
>this.inGetter = "string" : "string"
|
||||||
|
>this.inGetter : string | number | undefined
|
||||||
|
>this : this
|
||||||
|
>inGetter : string | number | undefined
|
||||||
|
>"string" : "string"
|
||||||
|
}
|
||||||
|
this.inMultiple = false;
|
||||||
|
>this.inMultiple = false : false
|
||||||
|
>this.inMultiple : string | number | boolean
|
||||||
|
>this : this
|
||||||
|
>inMultiple : string | number | boolean
|
||||||
|
>false : false
|
||||||
|
}
|
||||||
|
set() {
|
||||||
|
>set : () => void
|
||||||
|
|
||||||
|
if (Math.random()) {
|
||||||
|
>Math.random() : number
|
||||||
|
>Math.random : () => number
|
||||||
|
>Math : Math
|
||||||
|
>random : () => number
|
||||||
|
|
||||||
|
this.inSetter = 0;
|
||||||
|
>this.inSetter = 0 : 0
|
||||||
|
>this.inSetter : string | number | undefined
|
||||||
|
>this : this
|
||||||
|
>inSetter : string | number | undefined
|
||||||
|
>0 : 0
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inSetter = "string"
|
||||||
|
>this.inSetter = "string" : "string"
|
||||||
|
>this.inSetter : string | number | undefined
|
||||||
|
>this : this
|
||||||
|
>inSetter : string | number | undefined
|
||||||
|
>"string" : "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static method() {
|
||||||
|
>method : () => void
|
||||||
|
|
||||||
|
if (Math.random()) {
|
||||||
|
>Math.random() : number
|
||||||
|
>Math.random : () => number
|
||||||
|
>Math : Math
|
||||||
|
>random : () => number
|
||||||
|
|
||||||
|
this.inStaticMethod = 0;
|
||||||
|
>this.inStaticMethod = 0 : 0
|
||||||
|
>this.inStaticMethod : string | number | undefined
|
||||||
|
>this : typeof C
|
||||||
|
>inStaticMethod : string | number | undefined
|
||||||
|
>0 : 0
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inStaticMethod = "string"
|
||||||
|
>this.inStaticMethod = "string" : "string"
|
||||||
|
>this.inStaticMethod : string | number | undefined
|
||||||
|
>this : typeof C
|
||||||
|
>inStaticMethod : string | number | undefined
|
||||||
|
>"string" : "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static get() {
|
||||||
|
>get : () => void
|
||||||
|
|
||||||
|
if (Math.random()) {
|
||||||
|
>Math.random() : number
|
||||||
|
>Math.random : () => number
|
||||||
|
>Math : Math
|
||||||
|
>random : () => number
|
||||||
|
|
||||||
|
this.inStaticGetter = 0;
|
||||||
|
>this.inStaticGetter = 0 : 0
|
||||||
|
>this.inStaticGetter : string | number | undefined
|
||||||
|
>this : typeof C
|
||||||
|
>inStaticGetter : string | number | undefined
|
||||||
|
>0 : 0
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inStaticGetter = "string"
|
||||||
|
>this.inStaticGetter = "string" : "string"
|
||||||
|
>this.inStaticGetter : string | number | undefined
|
||||||
|
>this : typeof C
|
||||||
|
>inStaticGetter : string | number | undefined
|
||||||
|
>"string" : "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static set() {
|
||||||
|
>set : () => void
|
||||||
|
|
||||||
|
if (Math.random()) {
|
||||||
|
>Math.random() : number
|
||||||
|
>Math.random : () => number
|
||||||
|
>Math : Math
|
||||||
|
>random : () => number
|
||||||
|
|
||||||
|
this.inStaticSetter = 0;
|
||||||
|
>this.inStaticSetter = 0 : 0
|
||||||
|
>this.inStaticSetter : string | number | undefined
|
||||||
|
>this : typeof C
|
||||||
|
>inStaticSetter : string | number | undefined
|
||||||
|
>0 : 0
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inStaticSetter = "string"
|
||||||
|
>this.inStaticSetter = "string" : "string"
|
||||||
|
>this.inStaticSetter : string | number | undefined
|
||||||
|
>this : typeof C
|
||||||
|
>inStaticSetter : string | number | undefined
|
||||||
|
>"string" : "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
=== tests/cases/conformance/salsa/b.ts ===
|
||||||
|
var c = new C();
|
||||||
|
>c : C
|
||||||
|
>new C() : C
|
||||||
|
>C : typeof C
|
||||||
|
|
||||||
|
var stringOrNumber: string | number;
|
||||||
|
>stringOrNumber : string | number
|
||||||
|
|
||||||
|
var stringOrNumber = c.inConstructor;
|
||||||
|
>stringOrNumber : string | number
|
||||||
|
>c.inConstructor : string | number
|
||||||
|
>c : C
|
||||||
|
>inConstructor : string | number
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined: string | number | undefined;
|
||||||
|
>stringOrNumberOrUndefined : string | number | undefined
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined = c.inMethod;
|
||||||
|
>stringOrNumberOrUndefined : string | number | undefined
|
||||||
|
>c.inMethod : string | number | undefined
|
||||||
|
>c : C
|
||||||
|
>inMethod : string | number | undefined
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined = c.inGetter;
|
||||||
|
>stringOrNumberOrUndefined : string | number | undefined
|
||||||
|
>c.inGetter : string | number | undefined
|
||||||
|
>c : C
|
||||||
|
>inGetter : string | number | undefined
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined = c.inSetter;
|
||||||
|
>stringOrNumberOrUndefined : string | number | undefined
|
||||||
|
>c.inSetter : string | number | undefined
|
||||||
|
>c : C
|
||||||
|
>inSetter : string | number | undefined
|
||||||
|
|
||||||
|
var stringOrNumberOrBoolean: string | number | boolean;
|
||||||
|
>stringOrNumberOrBoolean : string | number | boolean
|
||||||
|
|
||||||
|
var stringOrNumberOrBoolean = c.inMultiple;
|
||||||
|
>stringOrNumberOrBoolean : string | number | boolean
|
||||||
|
>c.inMultiple : string | number | boolean
|
||||||
|
>c : C
|
||||||
|
>inMultiple : string | number | boolean
|
||||||
|
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined = C.inStaticMethod;
|
||||||
|
>stringOrNumberOrUndefined : string | number | undefined
|
||||||
|
>C.inStaticMethod : string | number | undefined
|
||||||
|
>C : typeof C
|
||||||
|
>inStaticMethod : string | number | undefined
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined = C.inStaticGetter;
|
||||||
|
>stringOrNumberOrUndefined : string | number | undefined
|
||||||
|
>C.inStaticGetter : string | number | undefined
|
||||||
|
>C : typeof C
|
||||||
|
>inStaticGetter : string | number | undefined
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined = C.inStaticSetter;
|
||||||
|
>stringOrNumberOrUndefined : string | number | undefined
|
||||||
|
>C.inStaticSetter : string | number | undefined
|
||||||
|
>C : typeof C
|
||||||
|
>inStaticSetter : string | number | undefined
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
// @out: output.js
|
||||||
|
// @allowJs: true
|
||||||
|
// @strictNullChecks: true
|
||||||
|
|
||||||
|
// @filename: a.js
|
||||||
|
class C {
|
||||||
|
constructor() {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inConstructor = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inConstructor = "string"
|
||||||
|
}
|
||||||
|
this.inMultiple = 0;
|
||||||
|
}
|
||||||
|
method() {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inMethod = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inMethod = "string"
|
||||||
|
}
|
||||||
|
this.inMultiple = "string";
|
||||||
|
}
|
||||||
|
get() {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inGetter = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inGetter = "string"
|
||||||
|
}
|
||||||
|
this.inMultiple = false;
|
||||||
|
}
|
||||||
|
set() {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inSetter = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inSetter = "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static method() {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inStaticMethod = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inStaticMethod = "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static get() {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inStaticGetter = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inStaticGetter = "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static set() {
|
||||||
|
if (Math.random()) {
|
||||||
|
this.inStaticSetter = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.inStaticSetter = "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @filename: b.ts
|
||||||
|
var c = new C();
|
||||||
|
|
||||||
|
var stringOrNumber: string | number;
|
||||||
|
var stringOrNumber = c.inConstructor;
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined: string | number | undefined;
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined = c.inMethod;
|
||||||
|
var stringOrNumberOrUndefined = c.inGetter;
|
||||||
|
var stringOrNumberOrUndefined = c.inSetter;
|
||||||
|
|
||||||
|
var stringOrNumberOrBoolean: string | number | boolean;
|
||||||
|
|
||||||
|
var stringOrNumberOrBoolean = c.inMultiple;
|
||||||
|
|
||||||
|
|
||||||
|
var stringOrNumberOrUndefined = C.inStaticMethod;
|
||||||
|
var stringOrNumberOrUndefined = C.inStaticGetter;
|
||||||
|
var stringOrNumberOrUndefined = C.inStaticSetter;
|
Loading…
Reference in a new issue