mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
Naming and duplication cleanup
This commit is contained in:
parent
0cadfcf6df
commit
4fdef85608
@ -2403,34 +2403,25 @@ namespace ts {
|
||||
return lookupSymbolForNameWorker(container, node.escapedText);
|
||||
}
|
||||
else {
|
||||
const symbol = follow(lookupSymbolForPropertyAccess(node.expression));
|
||||
const symbol = getJSInitializerSymbol(lookupSymbolForPropertyAccess(node.expression));
|
||||
return symbol && symbol.exports && symbol.exports.get(node.name.escapedText);
|
||||
}
|
||||
}
|
||||
|
||||
function isNamespaceableInitializer(initializer: Node) {
|
||||
return initializer.kind === SyntaxKind.ClassExpression ||
|
||||
initializer.kind === SyntaxKind.FunctionExpression ||
|
||||
initializer.kind === SyntaxKind.ObjectLiteralExpression && (initializer as ObjectLiteralExpression).properties.length === 0 ||
|
||||
initializer.kind === SyntaxKind.CallExpression && (skipParentheses((initializer as CallExpression).expression).kind === SyntaxKind.FunctionExpression ||
|
||||
skipParentheses((initializer as CallExpression).expression).kind === SyntaxKind.ArrowFunction);
|
||||
}
|
||||
|
||||
function bindPropertyAssignment(name: EntityNameExpression, propertyAccess: PropertyAccessEntityNameExpression, isPrototypeProperty: boolean) {
|
||||
// Look up the property in the local scope, since property assignments should follow the declaration
|
||||
let symbol = follow(lookupSymbolForPropertyAccess(name));
|
||||
// TODO: Should be able to structure this with less duplication
|
||||
let symbol = getJSInitializerSymbol(lookupSymbolForPropertyAccess(name));
|
||||
Debug.assert(propertyAccess.parent.kind === SyntaxKind.BinaryExpression ||
|
||||
propertyAccess.parent.kind === SyntaxKind.ExpressionStatement ||
|
||||
propertyAccess.parent.kind === SyntaxKind.PropertyAccessExpression);
|
||||
const isToplevelNamespaceableInitializer = propertyAccess.parent.kind === SyntaxKind.BinaryExpression ?
|
||||
propertyAccess.parent.parent.parent.kind === SyntaxKind.SourceFile && isNamespaceableInitializer((propertyAccess.parent as BinaryExpression).right) :
|
||||
const isToplevelNamespaceableInitializer = isBinaryExpression(propertyAccess.parent) ?
|
||||
propertyAccess.parent.parent.parent.kind === SyntaxKind.SourceFile && getJavascriptInitializer(propertyAccess.parent.right) :
|
||||
propertyAccess.parent.parent.kind === SyntaxKind.SourceFile;
|
||||
if (!isPrototypeProperty && (!symbol || !(symbol.flags & SymbolFlags.Namespace)) && isToplevelNamespaceableInitializer) {
|
||||
const flags = SymbolFlags.Module | SymbolFlags.JSContainer;
|
||||
const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.JSContainer;
|
||||
// addDeclarationToSymbol is only needed for things that could be further containers, because it makes the intermediate namespace symbol.
|
||||
iterateEntityNameExpression(propertyAccess.expression, (id, original) => {
|
||||
// make symbols are add declarations for intermediate containers
|
||||
forEachIdentifierInEntityName(propertyAccess.expression, (id, original) => {
|
||||
if (original) {
|
||||
// Note: add declaration to original symbol, not the special-syntax's symbol, so that namespaces work for type lookup
|
||||
addDeclarationToSymbol(original, id, flags);
|
||||
@ -2460,12 +2451,12 @@ namespace ts {
|
||||
declareSymbol(symbolTable, symbol, propertyAccess, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
|
||||
}
|
||||
|
||||
function iterateEntityNameExpression(e: EntityNameExpression, action: (e: Identifier, symbol: Symbol) => Symbol): Symbol {
|
||||
function forEachIdentifierInEntityName(e: EntityNameExpression, action: (e: Identifier, symbol: Symbol) => Symbol): Symbol {
|
||||
if (isIdentifier(e)) {
|
||||
return action(e, lookupSymbolForPropertyAccess(e));
|
||||
}
|
||||
else {
|
||||
const s = follow(iterateEntityNameExpression(e.expression, action));
|
||||
const s = getJSInitializerSymbol(forEachIdentifierInEntityName(e.expression, action));
|
||||
Debug.assert(!!s, "lost the chant");
|
||||
Debug.assert(!!s.exports, "has no exports");
|
||||
return action(e.name, s.exports.get(e.name.escapedText));
|
||||
|
||||
@ -858,11 +858,11 @@ namespace ts {
|
||||
mergeSymbolTable(target.exports, source.exports);
|
||||
}
|
||||
if ((source.flags | target.flags) & SymbolFlags.JSContainer) {
|
||||
const fs = follow(source);
|
||||
const ft = follow(target);
|
||||
const fs = getJSInitializerSymbol(source);
|
||||
const ft = getJSInitializerSymbol(target);
|
||||
if (fs !== source || ft !== target) {
|
||||
// also follow the source's valueDeclaration and merge its symbol
|
||||
mergeSymbol(follow(target), follow(source));
|
||||
mergeSymbol(getJSInitializerSymbol(target), getJSInitializerSymbol(source));
|
||||
}
|
||||
}
|
||||
recordMergedSymbol(target, source);
|
||||
@ -18987,7 +18987,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkBinaryExpression(node: BinaryExpression, checkMode?: CheckMode) {
|
||||
if (node.operatorToken.kind === SyntaxKind.BarBarToken && isInJavaScriptFile(node) && getAssignedJavascriptInitializer(node)) {
|
||||
if (isInJavaScriptFile(node) && getAssignedJavascriptInitializer(node)) {
|
||||
return checkExpression(node.right, checkMode);
|
||||
}
|
||||
return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, checkMode, node);
|
||||
|
||||
@ -1472,21 +1472,19 @@ 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.
|
||||
*/
|
||||
export function isDeclarationOfFunctionOrClassExpression(s: Symbol) {
|
||||
if (s.valueDeclaration && s.valueDeclaration.kind === SyntaxKind.VariableDeclaration) {
|
||||
const declaration = s.valueDeclaration as VariableDeclaration;
|
||||
return declaration.initializer &&
|
||||
(declaration.initializer.kind === SyntaxKind.FunctionExpression || declaration.initializer.kind === SyntaxKind.ClassExpression);
|
||||
if (s.valueDeclaration && isVariableDeclaration(s.valueDeclaration)) {
|
||||
return s.valueDeclaration.initializer &&
|
||||
(s.valueDeclaration.initializer.kind === SyntaxKind.FunctionExpression || s.valueDeclaration.initializer.kind === SyntaxKind.ClassExpression);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function follow(symbol: Symbol) {
|
||||
export function getJSInitializerSymbol(symbol: Symbol) {
|
||||
if (!symbol || !symbol.valueDeclaration) {
|
||||
return symbol;
|
||||
}
|
||||
@ -1495,10 +1493,6 @@ namespace ts {
|
||||
return e ? e.symbol : symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the node is a variable declaration whose initializer is a function or class expression, or an empty object literal.
|
||||
* This function does not test if the node is in a JavaScript file or not.
|
||||
*/
|
||||
export function getDeclaredJavascriptInitializer(node: Node) {
|
||||
if (node && isVariableDeclaration(node) && node.initializer) {
|
||||
return getJavascriptInitializer(node.initializer) ||
|
||||
@ -1513,11 +1507,15 @@ namespace ts {
|
||||
(getJavascriptInitializer(node.parent.right) || getDefaultedJavascriptInitializer(node.parent.left as EntityNameExpression, node.parent.right));
|
||||
}
|
||||
|
||||
function getJavascriptInitializer(e: Expression) {
|
||||
if(e.kind === SyntaxKind.FunctionExpression ||
|
||||
e.kind === SyntaxKind.ClassExpression ||
|
||||
isObjectLiteralExpression(e) && e.properties.length === 0) {
|
||||
return e;
|
||||
export function getJavascriptInitializer(initializer: Expression) {
|
||||
if (isCallExpression(initializer)) {
|
||||
const e = skipParentheses(initializer.expression);
|
||||
return e.kind === SyntaxKind.FunctionExpression || e.kind === SyntaxKind.ArrowFunction ? initializer : undefined;
|
||||
}
|
||||
if(initializer.kind === SyntaxKind.FunctionExpression ||
|
||||
initializer.kind === SyntaxKind.ClassExpression ||
|
||||
isObjectLiteralExpression(initializer) && initializer.properties.length === 0) {
|
||||
return initializer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user