JS Property assignments create namespaces (hacky)

This version isn't done yet and I think it still causes failures in the
test suite.
This commit is contained in:
Nathan Shively-Sanders 2017-11-21 15:05:20 -08:00
parent fa96bd4b01
commit 2f0e581018
2 changed files with 20 additions and 16 deletions

View file

@ -273,6 +273,9 @@ namespace ts {
return getEscapedTextOfIdentifierOrLiteral(<Identifier | LiteralExpression>name);
}
switch (node.kind) {
case SyntaxKind.Identifier:
// THIS IS WRONG
return (node as any as Identifier).escapedText;
case SyntaxKind.Constructor:
return InternalSymbolName.Constructor;
case SyntaxKind.FunctionType:
@ -2354,7 +2357,7 @@ namespace ts {
constructorFunction.parent = classPrototype;
classPrototype.parent = leftSideOfAssignment;
bindPropertyAssignment(constructorFunction.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ true);
bindPropertyAssignment(constructorFunction.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ true, /*isMagic*/ false);
}
function bindStaticPropertyAssignment(node: BinaryExpression) {
@ -2377,7 +2380,7 @@ namespace ts {
bindExportsPropertyAssignment(node);
}
else {
bindPropertyAssignment(target.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ false);
bindPropertyAssignment(target.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ false, /*isMagic*/ true);
}
}
}
@ -2386,14 +2389,22 @@ namespace ts {
return (container.symbol && container.symbol.exports && container.symbol.exports.get(name)) || (container.locals && container.locals.get(name));
}
function bindPropertyAssignment(functionName: __String, propertyAccessExpression: PropertyAccessExpression, isPrototypeProperty: boolean) {
function bindPropertyAssignment(functionName: __String, propertyAccessExpression: PropertyAccessExpression, isPrototypeProperty: boolean, isMagic: boolean) {
let targetSymbol = lookupSymbolForName(functionName);
if (targetSymbol && isDeclarationOfFunctionOrClassExpression(targetSymbol)) {
targetSymbol = (targetSymbol.valueDeclaration as VariableDeclaration).initializer.symbol;
}
if (!targetSymbol || !(targetSymbol.flags & (SymbolFlags.Function | SymbolFlags.Class))) {
if (isMagic && (!targetSymbol || !(targetSymbol.flags & SymbolFlags.Namespace))) {
// TODO: Magic may not be required
// TODO: Container.locals as symbolTable is probably wrong sometimes (maybe it's sometimes exports?)
// TODO: Container.symbol as parent is probably wrong sometimes
// TODO: propertyAccessExpression.expression isn't a Declaration
targetSymbol = declareSymbol(container.locals, container.symbol, propertyAccessExpression.expression as any as Declaration, SymbolFlags.NamespaceModule, SymbolFlags.NamespaceModuleExcludes);
}
if (targetSymbol && isDeclarationOfFunctionOrClassExpression(targetSymbol)) {
targetSymbol = (targetSymbol.valueDeclaration as VariableDeclaration).initializer.symbol;
}
if (!isMagic && (!targetSymbol || !(targetSymbol.flags & (SymbolFlags.Function | SymbolFlags.Class)))) {
return;
}

View file

@ -1381,7 +1381,8 @@ namespace ts {
function checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation: Node, name: __String, meaning: SymbolFlags): boolean {
if (meaning & (SymbolFlags.Value & ~SymbolFlags.NamespaceModule & ~SymbolFlags.Type)) {
const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.NamespaceModule & ~SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false));
if (symbol) {
// TODO: WRONG
if (symbol && !isInJavaScriptFile(errorLocation)) {
error(errorLocation, Diagnostics.Cannot_use_namespace_0_as_a_value, unescapeLeadingUnderscores(name));
return true;
}
@ -1734,15 +1735,7 @@ namespace ts {
return undefined;
}
const right = name.kind === SyntaxKind.QualifiedName ? name.right : name.name;
let namespace = resolveEntityName(left, SymbolFlags.Namespace, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
if (!namespace && name.parent && isJSDocTypeReference(name.parent as TypeReferenceType)) {
// jsdoc type references may be values
namespace = resolveEntityName(left, SymbolFlags.Value, ignoreErrors, /*dontResolveAlias*/ false, location);
}
else if (!ignoreErrors) {
// run again for error reporting purposes
resolveEntityName(left, SymbolFlags.Namespace, /*ignoreErrors*/ false, /*dontResolveAlias*/ false, location);
}
let namespace = resolveEntityName(left, SymbolFlags.Namespace, ignoreErrors, /*dontResolveAlias*/ false, location);
if (!namespace || nodeIsMissing(right)) {
return undefined;
}