4-nested object-literal assignment works in JS

This commit is contained in:
Nathan Shively-Sanders
2018-02-08 16:07:22 -08:00
parent b0aebb4c1e
commit a09c2391a4
5 changed files with 73 additions and 43 deletions

View File

@@ -2406,8 +2406,8 @@ namespace ts {
let symbol = lookupSymbolForPropertyAccess(node.expression as Identifier | PropertyAccessExpression);
symbol = symbol && isDeclarationOfJavascriptContainerExpression(symbol) ? (symbol.valueDeclaration as VariableDeclaration).initializer.symbol :
symbol && isDeclarationOfDefaultedJavascriptContainerExpression(symbol) ? ((symbol.valueDeclaration as VariableDeclaration).initializer as BinaryExpression).right.symbol :
// TODO: Might want the next line below for even further nestings?
// symbol && isAssignmentOfDefaultedJavascriptContainerExpression(symbol) ? ((symbol.valueDeclaration.parent as BinaryExpression).right as BinaryExpression).symbol :
symbol && isAssignmentOfDefaultedJavascriptContainerExpression(symbol) ? (((symbol.valueDeclaration.parent as BinaryExpression).right as BinaryExpression).right as BinaryExpression).symbol :
symbol && isAssignmentOfJavascriptContainerExpression(symbol) ? ((symbol.valueDeclaration.parent as BinaryExpression).right as BinaryExpression).symbol :
symbol;
return symbol && symbol.exports && symbol.exports.get(node.name.escapedText);
}
@@ -2420,6 +2420,7 @@ namespace ts {
let targetSymbol = symbol && isDeclarationOfJavascriptContainerExpression(symbol) ? (symbol.valueDeclaration as VariableDeclaration).initializer.symbol :
symbol && isDeclarationOfDefaultedJavascriptContainerExpression(symbol) ? ((symbol.valueDeclaration as VariableDeclaration).initializer as BinaryExpression).right.symbol :
symbol && isAssignmentOfDefaultedJavascriptContainerExpression(symbol) ? (((symbol.valueDeclaration.parent as BinaryExpression).right as BinaryExpression).right as BinaryExpression).symbol :
symbol && isAssignmentOfJavascriptContainerExpression(symbol) ? ((symbol.valueDeclaration.parent as BinaryExpression).right as BinaryExpression).symbol :
symbol;
Debug.assert(propertyAccess.parent.kind === SyntaxKind.BinaryExpression ||
propertyAccess.parent.kind === SyntaxKind.ExpressionStatement ||

View File

@@ -1472,6 +1472,7 @@ namespace ts {
return getSourceTextOfNodeFromSourceFile(sourceFile, str).charCodeAt(0) === CharacterCodes.doubleQuote;
}
// TODO: All 5 (!) of these need to be de-duped
/**
* Returns true if the node is a variable declaration whose initializer is a function or class expression.
* This function does not test if the node is in a JavaScript file or not.
@@ -1511,6 +1512,16 @@ namespace ts {
s.valueDeclaration.initializer.right.properties.length === 0;
}
export function isAssignmentOfJavascriptContainerExpression(s: Symbol) {
return s.valueDeclaration &&
isPropertyAccessExpression(s.valueDeclaration) &&
isBinaryExpression(s.valueDeclaration.parent) &&
s.valueDeclaration.parent.right &&
(s.valueDeclaration.parent.right.kind === SyntaxKind.FunctionExpression ||
s.valueDeclaration.parent.right.kind === SyntaxKind.ClassExpression ||
isObjectLiteralExpression(s.valueDeclaration.parent.right) && s.valueDeclaration.parent.right.properties.length === 0);
}
export function isAssignmentOfDefaultedJavascriptContainerExpression(s: Symbol) {
return s.valueDeclaration &&
isPropertyAccessExpression(s.valueDeclaration) &&

View File

@@ -55,8 +55,16 @@ var q = new my.predicate.query();
>predicate : Symbol(predicate, Decl(a.js, 9, 10), Decl(a.js, 10, 34))
>query : Symbol(query, Decl(a.js, 10, 34))
// my.predicate.result = {};
// my.predicate.sorted = my.predicate.sorted || {};
my.predicate.query.result = 'none'
>my.predicate.query.result : Symbol((Anonymous function).result, Decl(a.js, 15, 33))
>my.predicate.query : Symbol(query, Decl(a.js, 10, 34))
>my.predicate : Symbol(predicate, Decl(a.js, 9, 10), Decl(a.js, 10, 34))
>my : Symbol(my, Decl(a.js, 4, 3), Decl(a.js, 4, 18))
>predicate : Symbol(predicate, Decl(a.js, 9, 10), Decl(a.js, 10, 34))
>query : Symbol(query, Decl(a.js, 10, 34))
>result : Symbol((Anonymous function).result, Decl(a.js, 15, 33))
// TODO: EVEN MORE NESTING
// my.predicate.sort = my.predicate.sort || function (first, second) {
// return first;
// }

View File

@@ -4,15 +4,15 @@
// TODO: Try initializer of function or class I guess (though classes aren't context sensitive)
// TODO: Duplicated declarations should be OK (if they have the same type (??))
var my = my || {};
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: () => void; }; }
>my || {} : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: () => void; }; }
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: () => void; }; }
>{} : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: () => void; }; }
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: { (): void; result: string; }; }; }
>my || {} : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: { (): void; result: string; }; }; }
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: { (): void; result: string; }; }; }
>{} : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: { (): void; result: string; }; }; }
my.m = function() {
>my.m = function() { return 1;} : () => number
>my.m : () => number
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: () => void; }; }
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: { (): void; result: string; }; }; }
>m : () => number
>function() { return 1;} : () => number
@@ -22,45 +22,45 @@ my.m = function() {
my.n = 1;
>my.n = 1 : 1
>my.n : number
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: () => void; }; }
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: { (): void; result: string; }; }; }
>n : number
>1 : 1
my.o = {};
>my.o = {} : { [x: string]: any; }
>my.o : { [x: string]: any; }
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: () => void; }; }
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: { (): void; result: string; }; }; }
>o : { [x: string]: any; }
>{} : { [x: string]: any; }
my.predicate = my.predicate || {};
>my.predicate = my.predicate || {} : { [x: string]: any; query: () => void; }
>my.predicate : { [x: string]: any; query: () => void; }
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: () => void; }; }
>predicate : { [x: string]: any; query: () => void; }
>my.predicate || {} : { [x: string]: any; query: () => void; }
>my.predicate : { [x: string]: any; query: () => void; }
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: () => void; }; }
>predicate : { [x: string]: any; query: () => void; }
>{} : { [x: string]: any; query: () => void; }
>my.predicate = my.predicate || {} : { [x: string]: any; query: { (): void; result: string; }; }
>my.predicate : { [x: string]: any; query: { (): void; result: string; }; }
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: { (): void; result: string; }; }; }
>predicate : { [x: string]: any; query: { (): void; result: string; }; }
>my.predicate || {} : { [x: string]: any; query: { (): void; result: string; }; }
>my.predicate : { [x: string]: any; query: { (): void; result: string; }; }
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: { (): void; result: string; }; }; }
>predicate : { [x: string]: any; query: { (): void; result: string; }; }
>{} : { [x: string]: any; query: { (): void; result: string; }; }
my.predicate.query = function () {
>my.predicate.query = function () { var me = this; me.property = false;} : () => void
>my.predicate.query : () => void
>my.predicate : { [x: string]: any; query: () => void; }
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: () => void; }; }
>predicate : { [x: string]: any; query: () => void; }
>query : () => void
>function () { var me = this; me.property = false;} : () => void
>my.predicate.query = function () { var me = this; me.property = false;} : { (): void; result: string; }
>my.predicate.query : { (): void; result: string; }
>my.predicate : { [x: string]: any; query: { (): void; result: string; }; }
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: { (): void; result: string; }; }; }
>predicate : { [x: string]: any; query: { (): void; result: string; }; }
>query : { (): void; result: string; }
>function () { var me = this; me.property = false;} : { (): void; result: string; }
var me = this;
>me : { [x: string]: any; query: () => void; }
>this : { [x: string]: any; query: () => void; }
>me : { [x: string]: any; query: { (): void; result: string; }; }
>this : { [x: string]: any; query: { (): void; result: string; }; }
me.property = false;
>me.property = false : false
>me.property : any
>me : { [x: string]: any; query: () => void; }
>me : { [x: string]: any; query: { (): void; result: string; }; }
>property : any
>false : false
@@ -68,14 +68,24 @@ my.predicate.query = function () {
var q = new my.predicate.query();
>q : any
>new my.predicate.query() : any
>my.predicate.query : () => void
>my.predicate : { [x: string]: any; query: () => void; }
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: () => void; }; }
>predicate : { [x: string]: any; query: () => void; }
>query : () => void
>my.predicate.query : { (): void; result: string; }
>my.predicate : { [x: string]: any; query: { (): void; result: string; }; }
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: { (): void; result: string; }; }; }
>predicate : { [x: string]: any; query: { (): void; result: string; }; }
>query : { (): void; result: string; }
// my.predicate.result = {};
// my.predicate.sorted = my.predicate.sorted || {};
my.predicate.query.result = 'none'
>my.predicate.query.result = 'none' : "none"
>my.predicate.query.result : string
>my.predicate.query : { (): void; result: string; }
>my.predicate : { [x: string]: any; query: { (): void; result: string; }; }
>my : { [x: string]: any; m: () => number; n: number; o: { [x: string]: any; }; predicate: { [x: string]: any; query: { (): void; result: string; }; }; }
>predicate : { [x: string]: any; query: { (): void; result: string; }; }
>query : { (): void; result: string; }
>result : string
>'none' : "none"
// TODO: EVEN MORE NESTING
// my.predicate.sort = my.predicate.sort || function (first, second) {
// return first;
// }

View File

@@ -20,7 +20,7 @@ my.predicate.query = function () {
me.property = false;
};
var q = new my.predicate.query();
// my.predicate.result = {};
// my.predicate.sorted = my.predicate.sorted || {};
// TODO: EVEN MORE NESTING
my.predicate.query.result = 'none'
// my.predicate.sort = my.predicate.sort || function (first, second) {
// return first;
// }