Merge branch 'master' into builderApi

This commit is contained in:
Sheetal Nandi
2017-12-06 15:33:34 -08:00
20 changed files with 2108 additions and 32 deletions
+6
View File
@@ -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
View File
@@ -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);
}
+8 -9
View File
@@ -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());
+1 -1
View File
@@ -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)
+45 -4
View File
@@ -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));
}
/**
+3 -3
View File
@@ -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;
}