mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into builderApi
This commit is contained in:
@@ -749,6 +749,10 @@ namespace ts {
|
||||
return expr1.kind === SyntaxKind.TypeOfExpression && isNarrowableOperand((<TypeOfExpression>expr1).expression) && expr2.kind === SyntaxKind.StringLiteral;
|
||||
}
|
||||
|
||||
function isNarrowableInOperands(left: Expression, right: Expression) {
|
||||
return left.kind === SyntaxKind.StringLiteral && isNarrowingExpression(right);
|
||||
}
|
||||
|
||||
function isNarrowingBinaryExpression(expr: BinaryExpression) {
|
||||
switch (expr.operatorToken.kind) {
|
||||
case SyntaxKind.EqualsToken:
|
||||
@@ -761,6 +765,8 @@ namespace ts {
|
||||
isNarrowingTypeofOperands(expr.right, expr.left) || isNarrowingTypeofOperands(expr.left, expr.right);
|
||||
case SyntaxKind.InstanceOfKeyword:
|
||||
return isNarrowableOperand(expr.left);
|
||||
case SyntaxKind.InKeyword:
|
||||
return isNarrowableInOperands(expr.left, expr.right);
|
||||
case SyntaxKind.CommaToken:
|
||||
return isNarrowingExpression(expr.right);
|
||||
}
|
||||
|
||||
+28
-6
@@ -1022,7 +1022,7 @@ namespace ts {
|
||||
|
||||
// It's an external module. First see if the module has an export default and if the local
|
||||
// name of that export default matches.
|
||||
if (result = moduleExports.get("default" as __String)) {
|
||||
if (result = moduleExports.get(InternalSymbolName.Default)) {
|
||||
const localSymbol = getLocalSymbolForExportDefault(result);
|
||||
if (localSymbol && (result.flags & meaning) && localSymbol.escapedName === name) {
|
||||
break loop;
|
||||
@@ -1476,8 +1476,8 @@ namespace ts {
|
||||
else {
|
||||
const exportValue = moduleSymbol.exports.get("export=" as __String);
|
||||
exportDefaultSymbol = exportValue
|
||||
? getPropertyOfType(getTypeOfSymbol(exportValue), "default" as __String)
|
||||
: resolveSymbol(moduleSymbol.exports.get("default" as __String), dontResolveAlias);
|
||||
? getPropertyOfType(getTypeOfSymbol(exportValue), InternalSymbolName.Default)
|
||||
: resolveSymbol(moduleSymbol.exports.get(InternalSymbolName.Default), dontResolveAlias);
|
||||
}
|
||||
|
||||
if (!exportDefaultSymbol && !allowSyntheticDefaultImports) {
|
||||
@@ -1566,7 +1566,7 @@ namespace ts {
|
||||
symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias);
|
||||
let symbolFromModule = getExportOfModule(targetSymbol, name.escapedText, dontResolveAlias);
|
||||
// If the export member we're looking for is default, and there is no real default but allowSyntheticDefaultImports is on, return the entire module as the default
|
||||
if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === "default") {
|
||||
if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === InternalSymbolName.Default) {
|
||||
symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
|
||||
}
|
||||
const symbol = symbolFromModule && symbolFromVariable ?
|
||||
@@ -1953,7 +1953,7 @@ namespace ts {
|
||||
function extendExportSymbols(target: SymbolTable, source: SymbolTable | undefined, lookupTable?: ExportCollisionTrackerTable, exportNode?: ExportDeclaration) {
|
||||
if (!source) return;
|
||||
source.forEach((sourceSymbol, id) => {
|
||||
if (id === "default") return;
|
||||
if (id === InternalSymbolName.Default) return;
|
||||
|
||||
const targetSymbol = target.get(id);
|
||||
if (!targetSymbol) {
|
||||
@@ -3223,7 +3223,7 @@ namespace ts {
|
||||
* ensuring that any names written with literals use element accesses.
|
||||
*/
|
||||
function appendPropertyOrElementAccessForSymbol(symbol: Symbol, writer: SymbolWriter): void {
|
||||
const symbolName = symbol.escapedName === "default" ? "default" : getNameOfSymbolAsWritten(symbol);
|
||||
const symbolName = symbol.escapedName === InternalSymbolName.Default ? InternalSymbolName.Default : getNameOfSymbolAsWritten(symbol);
|
||||
const firstChar = symbolName.charCodeAt(0);
|
||||
const needsElementAccess = !isIdentifierStart(firstChar, languageVersion);
|
||||
|
||||
@@ -12724,6 +12724,22 @@ namespace ts {
|
||||
return type;
|
||||
}
|
||||
|
||||
function isTypePresencePossible(type: Type, propName: __String, assumeTrue: boolean) {
|
||||
const prop = getPropertyOfType(type, propName);
|
||||
if (prop) {
|
||||
return (prop.flags & SymbolFlags.Optional) ? true : assumeTrue;
|
||||
}
|
||||
return !assumeTrue;
|
||||
}
|
||||
|
||||
function narrowByInKeyword(type: Type, literal: LiteralExpression, assumeTrue: boolean) {
|
||||
if ((type.flags & (TypeFlags.Union | TypeFlags.Object)) || (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType)) {
|
||||
const propName = escapeLeadingUnderscores(literal.text);
|
||||
return filterType(type, t => isTypePresencePossible(t, propName, /* assumeTrue */ assumeTrue));
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function narrowTypeByBinaryExpression(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
|
||||
switch (expr.operatorToken.kind) {
|
||||
case SyntaxKind.EqualsToken:
|
||||
@@ -12759,6 +12775,12 @@ namespace ts {
|
||||
break;
|
||||
case SyntaxKind.InstanceOfKeyword:
|
||||
return narrowTypeByInstanceof(type, expr, assumeTrue);
|
||||
case SyntaxKind.InKeyword:
|
||||
const target = getReferenceCandidate(expr.right);
|
||||
if (expr.left.kind === SyntaxKind.StringLiteral && isMatchingReference(reference, target)) {
|
||||
return narrowByInKeyword(type, <LiteralExpression>expr.left, assumeTrue);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.CommaToken:
|
||||
return narrowType(type, expr.right, assumeTrue);
|
||||
}
|
||||
|
||||
@@ -1571,15 +1571,15 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private applyCodeActionCommand(commandName: string, requestSeq: number, args: protocol.ApplyCodeActionCommandRequestArgs): void {
|
||||
private applyCodeActionCommand(args: protocol.ApplyCodeActionCommandRequestArgs): {} {
|
||||
const commands = args.command as CodeActionCommand | CodeActionCommand[]; // They should be sending back the command we sent them.
|
||||
for (const command of toArray(commands)) {
|
||||
const { project } = this.getFileAndProject(command);
|
||||
const output = (success: boolean, message: string) => this.doOutput({}, commandName, requestSeq, success, message);
|
||||
project.getLanguageService().applyCodeActionCommand(command).then(
|
||||
result => { output(/*success*/ true, result.successMessage); },
|
||||
error => { output(/*success*/ false, error); });
|
||||
_result => { /* TODO: GH#20447 report success message? */ },
|
||||
_error => { /* TODO: GH#20447 report errors */ });
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
private getStartAndEndPosition(args: protocol.FileRangeRequestArgs, scriptInfo: ScriptInfo) {
|
||||
@@ -1705,17 +1705,17 @@ namespace ts.server {
|
||||
private handlers = createMapFromTemplate<(request: protocol.Request) => HandlerResponse>({
|
||||
[CommandNames.OpenExternalProject]: (request: protocol.OpenExternalProjectRequest) => {
|
||||
this.projectService.openExternalProject(request.arguments, /*suppressRefreshOfInferredProjects*/ false);
|
||||
// TODO: report errors
|
||||
// TODO: GH#20447 report errors
|
||||
return this.requiredResponse(/*response*/ true);
|
||||
},
|
||||
[CommandNames.OpenExternalProjects]: (request: protocol.OpenExternalProjectsRequest) => {
|
||||
this.projectService.openExternalProjects(request.arguments.projects);
|
||||
// TODO: report errors
|
||||
// TODO: GH#20447 report errors
|
||||
return this.requiredResponse(/*response*/ true);
|
||||
},
|
||||
[CommandNames.CloseExternalProject]: (request: protocol.CloseExternalProjectRequest) => {
|
||||
this.projectService.closeExternalProject(request.arguments.projectFileName);
|
||||
// TODO: report errors
|
||||
// TODO: GH#20447 report errors
|
||||
return this.requiredResponse(/*response*/ true);
|
||||
},
|
||||
[CommandNames.SynchronizeProjectList]: (request: protocol.SynchronizeProjectListRequest) => {
|
||||
@@ -1957,8 +1957,7 @@ namespace ts.server {
|
||||
return this.requiredResponse(this.getCodeFixes(request.arguments, /*simplifiedResult*/ false));
|
||||
},
|
||||
[CommandNames.ApplyCodeActionCommand]: (request: protocol.ApplyCodeActionCommandRequest) => {
|
||||
this.applyCodeActionCommand(request.command, request.seq, request.arguments);
|
||||
return this.notRequired(); // Response will come asynchronously.
|
||||
return this.requiredResponse(this.applyCodeActionCommand(request.arguments));
|
||||
},
|
||||
[CommandNames.GetSupportedCodeFixes]: () => {
|
||||
return this.requiredResponse(this.getSupportedCodeFixes());
|
||||
|
||||
@@ -746,7 +746,7 @@ namespace ts.codefix {
|
||||
forEachExternalModuleToImportFrom(checker, sourceFile, allSourceFiles, moduleSymbol => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
// check the default export
|
||||
const defaultExport = checker.tryGetMemberInModuleExports("default", moduleSymbol);
|
||||
const defaultExport = checker.tryGetMemberInModuleExports(InternalSymbolName.Default, moduleSymbol);
|
||||
if (defaultExport) {
|
||||
const localSymbol = getLocalSymbolForExportDefault(defaultExport);
|
||||
if ((localSymbol && localSymbol.escapedName === symbolName || moduleSymbolToValidIdentifier(moduleSymbol, context.compilerOptions.target) === symbolName)
|
||||
|
||||
@@ -39,6 +39,12 @@ namespace ts.Completions {
|
||||
return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log);
|
||||
}
|
||||
|
||||
const contextToken = findPrecedingToken(position, sourceFile);
|
||||
if (contextToken && isBreakOrContinueStatement(contextToken.parent)
|
||||
&& (contextToken.kind === SyntaxKind.BreakKeyword || contextToken.kind === SyntaxKind.ContinueKeyword || contextToken.kind === SyntaxKind.Identifier)) {
|
||||
return getLabelCompletionAtPosition(contextToken.parent);
|
||||
}
|
||||
|
||||
const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, options, compilerOptions.target);
|
||||
if (!completionData) {
|
||||
return undefined;
|
||||
@@ -223,6 +229,13 @@ namespace ts.Completions {
|
||||
return uniques;
|
||||
}
|
||||
|
||||
function getLabelCompletionAtPosition(node: BreakOrContinueStatement): CompletionInfo | undefined {
|
||||
const entries = getLabelStatementCompletions(node);
|
||||
if (entries.length) {
|
||||
return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries };
|
||||
}
|
||||
}
|
||||
|
||||
function getStringLiteralCompletionEntries(sourceFile: SourceFile, position: number, typeChecker: TypeChecker, compilerOptions: CompilerOptions, host: LanguageServiceHost, log: Log): CompletionInfo | undefined {
|
||||
const node = findPrecedingToken(position, sourceFile);
|
||||
if (!node || node.kind !== SyntaxKind.StringLiteral) {
|
||||
@@ -358,6 +371,32 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getLabelStatementCompletions(node: Node): CompletionEntry[] {
|
||||
const entries: CompletionEntry[] = [];
|
||||
const uniques = createMap<true>();
|
||||
let current = node;
|
||||
|
||||
while (current) {
|
||||
if (isFunctionLike(current)) {
|
||||
break;
|
||||
}
|
||||
if (isLabeledStatement(current)) {
|
||||
const name = current.label.text;
|
||||
if (!uniques.has(name)) {
|
||||
uniques.set(name, true);
|
||||
entries.push({
|
||||
name,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
kind: ScriptElementKind.label,
|
||||
sortText: "0"
|
||||
});
|
||||
}
|
||||
}
|
||||
current = current.parent;
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
function addStringLiteralCompletionsFromType(type: Type, result: Push<CompletionEntry>, typeChecker: TypeChecker, uniques = createMap<true>()): void {
|
||||
if (type && type.flags & TypeFlags.TypeParameter) {
|
||||
type = typeChecker.getBaseConstraintOfType(type);
|
||||
@@ -416,7 +455,9 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
function getSymbolName(symbol: Symbol, origin: SymbolOriginInfo | undefined, target: ScriptTarget): string {
|
||||
return origin && origin.isDefaultExport && symbol.name === "default" ? codefix.moduleSymbolToValidIdentifier(origin.moduleSymbol, target) : symbol.name;
|
||||
return origin && origin.isDefaultExport && symbol.escapedName === InternalSymbolName.Default
|
||||
? codefix.moduleSymbolToValidIdentifier(origin.moduleSymbol, target)
|
||||
: symbol.name;
|
||||
}
|
||||
|
||||
export interface CompletionEntryIdentifier {
|
||||
@@ -1076,7 +1117,7 @@ namespace ts.Completions {
|
||||
continue;
|
||||
}
|
||||
|
||||
const isDefaultExport = name === "default";
|
||||
const isDefaultExport = name === InternalSymbolName.Default;
|
||||
if (isDefaultExport) {
|
||||
const localSymbol = getLocalSymbolForExportDefault(symbol);
|
||||
if (localSymbol) {
|
||||
@@ -1756,10 +1797,10 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
if (existingImportsOrExports.size === 0) {
|
||||
return filter(exportsOfModule, e => e.escapedName !== "default");
|
||||
return filter(exportsOfModule, e => e.escapedName !== InternalSymbolName.Default);
|
||||
}
|
||||
|
||||
return filter(exportsOfModule, e => e.escapedName !== "default" && !existingImportsOrExports.get(e.escapedName));
|
||||
return filter(exportsOfModule, e => e.escapedName !== InternalSymbolName.Default && !existingImportsOrExports.get(e.escapedName));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -290,7 +290,7 @@ namespace ts.FindAllReferences {
|
||||
|
||||
function isNameMatch(name: __String): boolean {
|
||||
// Use name of "default" even in `export =` case because we may have allowSyntheticDefaultImports
|
||||
return name === exportSymbol.escapedName || exportKind !== ExportKind.Named && name === "default";
|
||||
return name === exportSymbol.escapedName || exportKind !== ExportKind.Named && name === InternalSymbolName.Default;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -534,7 +534,7 @@ namespace ts.FindAllReferences {
|
||||
// If `importedName` is undefined, do continue searching as the export is anonymous.
|
||||
// (All imports returned from this function will be ignored anyway if we are in rename and this is a not a named export.)
|
||||
const importedName = symbolName(importedSymbol);
|
||||
if (importedName === undefined || importedName === "default" || importedName === symbol.escapedName) {
|
||||
if (importedName === undefined || importedName === InternalSymbolName.Default || importedName === symbol.escapedName) {
|
||||
return { kind: ImportExport.Import, symbol: importedSymbol, ...isImport };
|
||||
}
|
||||
}
|
||||
@@ -604,7 +604,7 @@ namespace ts.FindAllReferences {
|
||||
}
|
||||
|
||||
function symbolName(symbol: Symbol): __String | undefined {
|
||||
if (symbol.escapedName !== "default") {
|
||||
if (symbol.escapedName !== InternalSymbolName.Default) {
|
||||
return symbol.escapedName;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user