Merge branch 'master' into builderApi

This commit is contained in:
Sheetal Nandi
2018-01-19 15:56:40 -08:00
199 changed files with 17079 additions and 6234 deletions

View File

@@ -619,37 +619,46 @@ namespace ts {
return start;
}
// Don't bother with newlines/whitespace.
if (kind === SyntaxKind.NewLineTrivia || kind === SyntaxKind.WhitespaceTrivia) {
continue;
}
// Only bother with the trivia if it at least intersects the span of interest.
if (isComment(kind)) {
classifyComment(token, kind, start, width);
// Classifying a comment might cause us to reuse the trivia scanner
// (because of jsdoc comments). So after we classify the comment make
// sure we set the scanner position back to where it needs to be.
triviaScanner.setTextPos(end);
continue;
}
if (kind === SyntaxKind.ConflictMarkerTrivia) {
const text = sourceFile.text;
const ch = text.charCodeAt(start);
// for the <<<<<<< and >>>>>>> markers, we just add them in as comments
// in the classification stream.
if (ch === CharacterCodes.lessThan || ch === CharacterCodes.greaterThan) {
pushClassification(start, width, ClassificationType.comment);
switch (kind) {
case SyntaxKind.NewLineTrivia:
case SyntaxKind.WhitespaceTrivia:
// Don't bother with newlines/whitespace.
continue;
}
// for the ||||||| and ======== markers, add a comment for the first line,
// and then lex all subsequent lines up until the end of the conflict marker.
Debug.assert(ch === CharacterCodes.bar || ch === CharacterCodes.equals);
classifyDisabledMergeCode(text, start, end);
case SyntaxKind.SingleLineCommentTrivia:
case SyntaxKind.MultiLineCommentTrivia:
// Only bother with the trivia if it at least intersects the span of interest.
classifyComment(token, kind, start, width);
// Classifying a comment might cause us to reuse the trivia scanner
// (because of jsdoc comments). So after we classify the comment make
// sure we set the scanner position back to where it needs to be.
triviaScanner.setTextPos(end);
continue;
case SyntaxKind.ConflictMarkerTrivia:
const text = sourceFile.text;
const ch = text.charCodeAt(start);
// for the <<<<<<< and >>>>>>> markers, we just add them in as comments
// in the classification stream.
if (ch === CharacterCodes.lessThan || ch === CharacterCodes.greaterThan) {
pushClassification(start, width, ClassificationType.comment);
continue;
}
// for the ||||||| and ======== markers, add a comment for the first line,
// and then lex all subsequent lines up until the end of the conflict marker.
Debug.assert(ch === CharacterCodes.bar || ch === CharacterCodes.equals);
classifyDisabledMergeCode(text, start, end);
break;
case SyntaxKind.ShebangTrivia:
// TODO: Maybe we should classify these.
break;
default:
Debug.assertNever(kind);
}
}
}

View File

@@ -10,7 +10,6 @@ namespace ts {
export interface CodeFixContextBase extends textChanges.TextChangesContext {
sourceFile: SourceFile;
program: Program;
host: LanguageServiceHost;
cancellationToken: CancellationToken;
}

View File

@@ -9,12 +9,14 @@ namespace ts.codefix {
registerCodeFix({
errorCodes,
getCodeActions(context) {
const { sourceFile, program, newLineCharacter, span } = context;
const { sourceFile, program, span } = context;
if (!isInJavaScriptFile(sourceFile) || !isCheckJsEnabledForFile(sourceFile, program.getCompilerOptions())) {
return undefined;
}
const newLineCharacter = getNewLineOrDefaultFromHost(context.host, context.formatContext.options);
return [{
description: getLocaleSpecificMessage(Diagnostics.Ignore_this_error_message),
changes: [createFileTextChanges(sourceFile.fileName, [getIgnoreCommentLocationForLocation(sourceFile, span.start, newLineCharacter)])],
@@ -36,7 +38,7 @@ namespace ts.codefix {
fixIds: [fixId], // No point applying as a group, doing it once will fix all errors
getAllCodeActions: context => codeFixAllWithTextChanges(context, errorCodes, (changes, err) => {
if (err.start !== undefined) {
changes.push(getIgnoreCommentLocationForLocation(err.file!, err.start, context.newLineCharacter));
changes.push(getIgnoreCommentLocationForLocation(err.file!, err.start, getNewLineOrDefaultFromHost(context.host, context.formatContext.options)));
}
}),
});

View File

@@ -142,7 +142,7 @@ namespace ts.codefix {
return typeNode || createKeywordTypeNode(SyntaxKind.AnyKeyword);
}
function createAddPropertyDeclarationAction(context: textChanges.TextChangesContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, makeStatic: boolean, tokenName: string, typeNode: TypeNode): CodeFixAction {
function createAddPropertyDeclarationAction(context: CodeFixContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, makeStatic: boolean, tokenName: string, typeNode: TypeNode): CodeFixAction {
const description = formatStringFromArgs(getLocaleSpecificMessage(makeStatic ? Diagnostics.Declare_static_property_0 : Diagnostics.Declare_property_0), [tokenName]);
const changes = textChanges.ChangeTracker.with(context, t => addPropertyDeclaration(t, classDeclarationSourceFile, classDeclaration, tokenName, typeNode, makeStatic));
return { description, changes, fixId };
@@ -159,7 +159,7 @@ namespace ts.codefix {
changeTracker.insertNodeAtClassStart(classDeclarationSourceFile, classDeclaration, property);
}
function createAddIndexSignatureAction(context: textChanges.TextChangesContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, tokenName: string, typeNode: TypeNode): CodeFixAction {
function createAddIndexSignatureAction(context: CodeFixContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, tokenName: string, typeNode: TypeNode): CodeFixAction {
// Index signatures cannot have the static modifier.
const stringTypeNode = createKeywordTypeNode(SyntaxKind.StringKeyword);
const indexingParameter = createParameter(
@@ -181,7 +181,7 @@ namespace ts.codefix {
return { description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_index_signature_for_property_0), [tokenName]), changes, fixId: undefined };
}
function getActionForMethodDeclaration(context: textChanges.TextChangesContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, token: Identifier, callExpression: CallExpression, makeStatic: boolean, inJs: boolean): CodeFixAction | undefined {
function getActionForMethodDeclaration(context: CodeFixContext, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, token: Identifier, callExpression: CallExpression, makeStatic: boolean, inJs: boolean): CodeFixAction | undefined {
const description = formatStringFromArgs(getLocaleSpecificMessage(makeStatic ? Diagnostics.Declare_static_method_0 : Diagnostics.Declare_method_0), [token.text]);
const changes = textChanges.ChangeTracker.with(context, t => addMethodDeclaration(t, classDeclarationSourceFile, classDeclaration, token, callExpression, makeStatic, inJs));
return { description, changes, fixId };

View File

@@ -29,12 +29,8 @@ namespace ts.codefix {
symbolName: string;
}
interface SymbolAndTokenContext extends SymbolContext {
interface ImportCodeFixContext extends SymbolContext {
symbolToken: Identifier | undefined;
}
interface ImportCodeFixContext extends SymbolAndTokenContext {
host: LanguageServiceHost;
program: Program;
checker: TypeChecker;
compilerOptions: CompilerOptions;
@@ -173,7 +169,6 @@ namespace ts.codefix {
const symbolToken = cast(getTokenAtPosition(context.sourceFile, context.span.start, /*includeJsDocComment*/ false), isIdentifier);
return {
host: context.host,
newLineCharacter: context.newLineCharacter,
formatContext: context.formatContext,
sourceFile: context.sourceFile,
program,
@@ -472,7 +467,7 @@ namespace ts.codefix {
addJsExtension: boolean,
): string | undefined {
const roots = getEffectiveTypeRoots(options, host);
return roots && firstDefined(roots, unNormalizedTypeRoot => {
return firstDefined(roots, unNormalizedTypeRoot => {
const typeRoot = toPath(unNormalizedTypeRoot, /*basePath*/ undefined, getCanonicalFileName);
if (startsWith(moduleFileName, typeRoot)) {
return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1), options, addJsExtension);

View File

@@ -627,7 +627,6 @@ namespace ts.Completions {
host,
program,
checker,
newLineCharacter: host.getNewLine(),
compilerOptions,
sourceFile,
formatContext,

View File

@@ -44,7 +44,7 @@ namespace ts.FindAllReferences {
export function findReferencedSymbols(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray<SourceFile>, sourceFile: SourceFile, position: number): ReferencedSymbol[] | undefined {
const referencedSymbols = findAllReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position);
const checker = program.getTypeChecker();
return !referencedSymbols || !referencedSymbols.length ? undefined : mapDefined(referencedSymbols, ({ definition, references }) =>
return !referencedSymbols || !referencedSymbols.length ? undefined : mapDefined<SymbolAndEntries, ReferencedSymbol>(referencedSymbols, ({ definition, references }) =>
// Only include referenced symbols that have a valid definition.
definition && { definition: definitionToReferencedSymbolDefinitionInfo(definition, checker), references: references.map(toReferenceEntry) });
}

View File

@@ -14,10 +14,14 @@ namespace ts.formatting {
kind: SyntaxKind;
}
export interface TextRangeWithTriviaKind extends TextRange {
kind: TriviaKind;
}
export interface TokenInfo {
leadingTrivia: TextRangeWithKind[];
leadingTrivia: TextRangeWithTriviaKind[];
token: TextRangeWithKind;
trailingTrivia: TextRangeWithKind[];
trailingTrivia: TextRangeWithTriviaKind[];
}
const enum Constants {
@@ -66,11 +70,6 @@ namespace ts.formatting {
recomputeIndentation(lineAddedByFormatting: boolean): void;
}
interface Indentation {
indentation: number;
delta: number;
}
export function formatOnEnter(position: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] {
const line = sourceFile.getLineAndCharacterOfPosition(position).line;
if (line === 0) {
@@ -469,39 +468,35 @@ namespace ts.formatting {
inheritedIndentation: number,
parent: Node,
parentDynamicIndentation: DynamicIndentation,
effectiveParentStartLine: number): Indentation {
let indentation = inheritedIndentation;
let delta = SmartIndenter.shouldIndentChildNode(node) ? options.indentSize : 0;
effectiveParentStartLine: number
): { indentation: number, delta: number } {
const delta = SmartIndenter.shouldIndentChildNode(node) ? options.indentSize : 0;
if (effectiveParentStartLine === startLine) {
// if node is located on the same line with the parent
// - inherit indentation from the parent
// - push children if either parent of node itself has non-zero delta
indentation = startLine === lastIndentedLine
? indentationOnLastIndentedLine
: parentDynamicIndentation.getIndentation();
delta = Math.min(options.indentSize, parentDynamicIndentation.getDelta(node) + delta);
return {
indentation: startLine === lastIndentedLine ? indentationOnLastIndentedLine : parentDynamicIndentation.getIndentation(),
delta: Math.min(options.indentSize, parentDynamicIndentation.getDelta(node) + delta)
};
}
else if (indentation === Constants.Unknown) {
else if (inheritedIndentation === Constants.Unknown) {
if (node.kind === SyntaxKind.OpenParenToken && startLine === lastIndentedLine) {
// the is used for chaining methods formatting
// - we need to get the indentation on last line and the delta of parent
indentation = indentationOnLastIndentedLine;
delta = parentDynamicIndentation.getDelta(node);
return { indentation: indentationOnLastIndentedLine, delta: parentDynamicIndentation.getDelta(node) };
}
else if (SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) {
indentation = parentDynamicIndentation.getIndentation();
return { indentation: parentDynamicIndentation.getIndentation(), delta };
}
else {
indentation = parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta(node);
return { indentation: parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta(node), delta };
}
}
return {
indentation,
delta
};
else {
return { indentation: inheritedIndentation, delta };
}
}
function getFirstNonDecoratorTokenOfNode(node: Node) {

View File

@@ -31,8 +31,8 @@ namespace ts.formatting {
scanner.setTextPos(startPos);
let wasNewLine = true;
let leadingTrivia: TextRangeWithKind[] | undefined;
let trailingTrivia: TextRangeWithKind[] | undefined;
let leadingTrivia: TextRangeWithTriviaKind[] | undefined;
let trailingTrivia: TextRangeWithTriviaKind[] | undefined;
let savedPos: number;
let lastScanAction: ScanAction | undefined;
@@ -77,7 +77,7 @@ namespace ts.formatting {
// consume leading trivia
scanner.scan();
const item = {
const item: TextRangeWithTriviaKind = {
pos,
end: scanner.getStartPos(),
kind: t
@@ -188,7 +188,7 @@ namespace ts.formatting {
if (!isTrivia(currentToken)) {
break;
}
const trivia = {
const trivia: TextRangeWithTriviaKind = {
pos: scanner.getStartPos(),
end: scanner.getTextPos(),
kind: currentToken

View File

@@ -127,30 +127,16 @@ namespace ts.GoToDefinition {
}
const symbol = typeChecker.getSymbolAtLocation(node);
if (!symbol) {
return undefined;
}
const type = typeChecker.getTypeOfSymbolAtLocation(symbol, node);
const type = symbol && typeChecker.getTypeOfSymbolAtLocation(symbol, node);
if (!type) {
return undefined;
}
if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Enum)) {
const result: DefinitionInfo[] = [];
forEach((<UnionType>type).types, t => {
if (t.symbol) {
addRange(/*to*/ result, /*from*/ getDefinitionFromSymbol(typeChecker, t.symbol, node));
}
});
return result;
return flatMap((<UnionType>type).types, t => t.symbol && getDefinitionFromSymbol(typeChecker, t.symbol, node));
}
if (!type.symbol) {
return undefined;
}
return getDefinitionFromSymbol(typeChecker, type.symbol, node);
return type.symbol && getDefinitionFromSymbol(typeChecker, type.symbol, node);
}
export function getDefinitionAndBoundSpan(program: Program, sourceFile: SourceFile, position: number): DefinitionInfoAndBoundSpan {
@@ -199,66 +185,32 @@ namespace ts.GoToDefinition {
}
function getDefinitionFromSymbol(typeChecker: TypeChecker, symbol: Symbol, node: Node): DefinitionInfo[] {
const result: DefinitionInfo[] = [];
const declarations = symbol.getDeclarations();
const { symbolName, symbolKind, containerName } = getSymbolInfo(typeChecker, symbol, node);
return getConstructSignatureDefinition() || getCallSignatureDefinition() || map(symbol.declarations, declaration => createDefinitionInfo(declaration, symbolKind, symbolName, containerName));
if (!tryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) &&
!tryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) {
// Just add all the declarations.
forEach(declarations, declaration => {
result.push(createDefinitionInfo(declaration, symbolKind, symbolName, containerName));
});
}
return result;
function tryAddConstructSignature(symbol: Symbol, location: Node, symbolKind: ScriptElementKind, symbolName: string, containerName: string, result: DefinitionInfo[]) {
function getConstructSignatureDefinition(): DefinitionInfo[] | undefined {
// Applicable only if we are in a new expression, or we are on a constructor declaration
// and in either case the symbol has a construct signature definition, i.e. class
if (isNewExpressionTarget(location) || location.kind === SyntaxKind.ConstructorKeyword) {
if (symbol.flags & SymbolFlags.Class) {
// Find the first class-like declaration and try to get the construct signature.
for (const declaration of symbol.getDeclarations()) {
if (isClassLike(declaration)) {
return tryAddSignature(
declaration.members, /*selectConstructors*/ true, symbolKind, symbolName, containerName, result);
}
}
Debug.fail("Expected declaration to have at least one class-like declaration");
}
if (isNewExpressionTarget(node) || node.kind === SyntaxKind.ConstructorKeyword && symbol.flags & SymbolFlags.Class) {
const cls = find(symbol.declarations, isClassLike) || Debug.fail("Expected declaration to have at least one class-like declaration");
return getSignatureDefinition(cls.members, /*selectConstructors*/ true);
}
return false;
}
function tryAddCallSignature(symbol: Symbol, location: Node, symbolKind: ScriptElementKind, symbolName: string, containerName: string, result: DefinitionInfo[]) {
if (isCallExpressionTarget(location) || isNewExpressionTarget(location) || isNameOfFunctionDeclaration(location)) {
return tryAddSignature(symbol.declarations, /*selectConstructors*/ false, symbolKind, symbolName, containerName, result);
}
return false;
function getCallSignatureDefinition(): DefinitionInfo[] | undefined {
return isCallExpressionTarget(node) || isNewExpressionTarget(node) || isNameOfFunctionDeclaration(node)
? getSignatureDefinition(symbol.declarations, /*selectConstructors*/ false)
: undefined;
}
function tryAddSignature(signatureDeclarations: ReadonlyArray<Declaration> | undefined, selectConstructors: boolean, symbolKind: ScriptElementKind, symbolName: string, containerName: string, result: DefinitionInfo[]) {
function getSignatureDefinition(signatureDeclarations: ReadonlyArray<Declaration> | undefined, selectConstructors: boolean): DefinitionInfo[] | undefined {
if (!signatureDeclarations) {
return false;
return undefined;
}
const declarations: Declaration[] = [];
let definition: Declaration | undefined;
for (const d of signatureDeclarations) {
if (selectConstructors ? d.kind === SyntaxKind.Constructor : isSignatureDeclaration(d)) {
declarations.push(d);
if ((<FunctionLikeDeclaration>d).body) definition = d;
}
}
if (declarations.length) {
result.push(createDefinitionInfo(definition || lastOrUndefined(declarations), symbolKind, symbolName, containerName));
return true;
}
return false;
const declarations = signatureDeclarations.filter(selectConstructors ? isConstructorDeclaration : isSignatureDeclaration);
return declarations.length
? [createDefinitionInfo(find(declarations, d => !!(<FunctionLikeDeclaration>d).body) || last(declarations), symbolKind, symbolName, containerName)]
: undefined;
}
}

View File

@@ -1,12 +1,6 @@
/* @internal */
namespace ts {
export interface Refactor {
/** An unique code associated with each refactor */
name: string;
/** Description of the refactor to display in the UI of the editor */
description: string;
/** Compute the associated code actions */
getEditsForAction(context: RefactorContext, actionName: string): RefactorEditInfo | undefined;
@@ -19,7 +13,6 @@ namespace ts {
startPosition: number;
endPosition?: number;
program: Program;
host: LanguageServiceHost;
cancellationToken?: CancellationToken;
}
@@ -28,8 +21,9 @@ namespace ts {
// e.g. nonSuggestableRefactors[refactorCode] -> the refactor you want
const refactors: Map<Refactor> = createMap<Refactor>();
export function registerRefactor(refactor: Refactor) {
refactors.set(refactor.name, refactor);
/** @param name An unique code associated with each refactor. Does not have to be human-readable. */
export function registerRefactor(name: string, refactor: Refactor) {
refactors.set(name, refactor);
}
export function getApplicableRefactors(context: RefactorContext): ApplicableRefactorInfo[] {

View File

@@ -1,13 +1,10 @@
/* @internal */
namespace ts.refactor.annotateWithTypeFromJSDoc {
const refactorName = "Annotate with type from JSDoc";
const actionName = "annotate";
const description = Diagnostics.Annotate_with_type_from_JSDoc.message;
registerRefactor(refactorName, { getEditsForAction, getAvailableActions });
const annotateTypeFromJSDoc: Refactor = {
name: "Annotate with type from JSDoc",
description: Diagnostics.Annotate_with_type_from_JSDoc.message,
getEditsForAction,
getAvailableActions
};
type DeclarationWithType =
| FunctionLikeDeclaration
| VariableDeclaration
@@ -15,8 +12,6 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
| PropertySignature
| PropertyDeclaration;
registerRefactor(annotateTypeFromJSDoc);
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
if (isInJavaScriptFile(context.file)) {
return undefined;
@@ -25,11 +20,11 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
const node = getTokenAtPosition(context.file, context.startPosition, /*includeJsDocComment*/ false);
if (hasUsableJSDoc(findAncestor(node, isDeclarationWithType))) {
return [{
name: annotateTypeFromJSDoc.name,
description: annotateTypeFromJSDoc.description,
name: refactorName,
description,
actions: [
{
description: annotateTypeFromJSDoc.description,
description,
name: actionName
}
]

View File

@@ -1,16 +1,10 @@
/* @internal */
namespace ts.refactor.convertFunctionToES6Class {
const refactorName = "Convert to ES2015 class";
const actionName = "convert";
const convertFunctionToES6Class: Refactor = {
name: "Convert to ES2015 class",
description: Diagnostics.Convert_function_to_an_ES2015_class.message,
getEditsForAction,
getAvailableActions
};
registerRefactor(convertFunctionToES6Class);
const description = Diagnostics.Convert_function_to_an_ES2015_class.message;
registerRefactor(refactorName, { getEditsForAction, getAvailableActions });
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
if (!isInJavaScriptFile(context.file)) {
@@ -29,11 +23,11 @@ namespace ts.refactor.convertFunctionToES6Class {
if ((symbol.flags & SymbolFlags.Function) && symbol.members && (symbol.members.size > 0)) {
return [
{
name: convertFunctionToES6Class.name,
description: convertFunctionToES6Class.description,
name: refactorName,
description,
actions: [
{
description: convertFunctionToES6Class.description,
description,
name: actionName
}
]

View File

@@ -1,15 +1,8 @@
/* @internal */
namespace ts.refactor {
const actionName = "Convert to ES6 module";
const convertToEs6Module: Refactor = {
name: actionName,
description: getLocaleSpecificMessage(Diagnostics.Convert_to_ES6_module),
getEditsForAction,
getAvailableActions,
};
registerRefactor(convertToEs6Module);
const description = getLocaleSpecificMessage(Diagnostics.Convert_to_ES6_module);
registerRefactor(actionName, { getEditsForAction, getAvailableActions });
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
const { file, startPosition } = context;
@@ -20,11 +13,11 @@ namespace ts.refactor {
const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
return !isAtTriggerLocation(file, node) ? undefined : [
{
name: convertToEs6Module.name,
description: convertToEs6Module.description,
name: actionName,
description,
actions: [
{
description: convertToEs6Module.description,
description,
name: actionName,
},
],

View File

@@ -3,14 +3,8 @@
/* @internal */
namespace ts.refactor.extractSymbol {
const extractSymbol: Refactor = {
name: "Extract Symbol",
description: getLocaleSpecificMessage(Diagnostics.Extract_symbol),
getAvailableActions,
getEditsForAction,
};
registerRefactor(extractSymbol);
const refactorName = "Extract Symbol";
registerRefactor(refactorName, { getAvailableActions, getEditsForAction });
/**
* Compute the associated code actions
@@ -77,7 +71,7 @@ namespace ts.refactor.extractSymbol {
if (functionActions.length) {
infos.push({
name: extractSymbol.name,
name: refactorName,
description: getLocaleSpecificMessage(Diagnostics.Extract_function),
actions: functionActions
});
@@ -85,7 +79,7 @@ namespace ts.refactor.extractSymbol {
if (constantActions.length) {
infos.push({
name: extractSymbol.name,
name: refactorName,
description: getLocaleSpecificMessage(Diagnostics.Extract_constant),
actions: constantActions
});

View File

@@ -1,15 +1,9 @@
/* @internal */
namespace ts.refactor.installTypesForPackage {
const refactorName = "Install missing types package";
const actionName = "install";
const installTypesForPackage: Refactor = {
name: "Install missing types package",
description: "Install missing types package",
getEditsForAction,
getAvailableActions,
};
registerRefactor(installTypesForPackage);
const description = "Install missing types package";
registerRefactor(refactorName, { getEditsForAction, getAvailableActions });
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
if (getStrictOptionValue(context.program.getCompilerOptions(), "noImplicitAny")) {
@@ -20,8 +14,8 @@ namespace ts.refactor.installTypesForPackage {
const action = getAction(context);
return action && [
{
name: installTypesForPackage.name,
description: installTypesForPackage.description,
name: refactorName,
description,
actions: [
{
description: action.description,

View File

@@ -1,15 +1,8 @@
/* @internal */
namespace ts.refactor.installTypesForPackage {
const actionName = "Convert to default import";
const useDefaultImport: Refactor = {
name: actionName,
description: getLocaleSpecificMessage(Diagnostics.Convert_to_default_import),
getEditsForAction,
getAvailableActions,
};
registerRefactor(useDefaultImport);
const description = getLocaleSpecificMessage(Diagnostics.Convert_to_default_import);
registerRefactor(actionName, { getEditsForAction, getAvailableActions });
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
const { file, startPosition, program } = context;
@@ -31,11 +24,11 @@ namespace ts.refactor.installTypesForPackage {
return [
{
name: useDefaultImport.name,
description: useDefaultImport.description,
name: actionName,
description,
actions: [
{
description: useDefaultImport.description,
description,
name: actionName,
},
],

View File

@@ -1887,12 +1887,11 @@ namespace ts {
synchronizeHostData();
const sourceFile = getValidSourceFile(fileName);
const span = createTextSpanFromBounds(start, end);
const newLineCharacter = getNewLineOrDefaultFromHost(host);
const formatContext = formatting.getFormatContext(formatOptions);
return flatMap(deduplicate(errorCodes, equateValues, compareValues), errorCode => {
cancellationToken.throwIfCancellationRequested();
return codefix.getFixes({ errorCode, sourceFile, span, program, newLineCharacter, host, cancellationToken, formatContext });
return codefix.getFixes({ errorCode, sourceFile, span, program, host, cancellationToken, formatContext });
});
}
@@ -1900,10 +1899,9 @@ namespace ts {
synchronizeHostData();
Debug.assert(scope.type === "file");
const sourceFile = getValidSourceFile(scope.fileName);
const newLineCharacter = getNewLineOrDefaultFromHost(host);
const formatContext = formatting.getFormatContext(formatOptions);
return codefix.getAllFixes({ fixId, sourceFile, program, newLineCharacter, host, cancellationToken, formatContext });
return codefix.getAllFixes({ fixId, sourceFile, program, host, cancellationToken, formatContext });
}
function applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
@@ -2134,7 +2132,6 @@ namespace ts {
startPosition,
endPosition,
program: getProgram(),
newLineCharacter: formatOptions ? formatOptions.newLineCharacter : host.getNewLine(),
host,
formatContext: formatting.getFormatContext(formatOptions),
cancellationToken,

View File

@@ -187,7 +187,7 @@ namespace ts.textChanges {
}
export interface TextChangesContext {
newLineCharacter: string;
host: LanguageServiceHost;
formatContext: ts.formatting.FormatContext;
}
@@ -199,7 +199,7 @@ namespace ts.textChanges {
private readonly nodesInsertedAtClassStarts = createMap<{ sourceFile: SourceFile, cls: ClassLikeDeclaration, members: ClassElement[] }>();
public static fromContext(context: TextChangesContext): ChangeTracker {
return new ChangeTracker(context.newLineCharacter === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed, context.formatContext);
return new ChangeTracker(getNewLineOrDefaultFromHost(context.host, context.formatContext.options) === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed, context.formatContext);
}
public static with(context: TextChangesContext, cb: (tracker: ChangeTracker) => void): FileTextChanges[] {

View File

@@ -1259,8 +1259,10 @@ namespace ts {
/**
* The default is CRLF.
*/
export function getNewLineOrDefaultFromHost(host: LanguageServiceHost | LanguageServiceShimHost) {
return host.getNewLine ? host.getNewLine() : carriageReturnLineFeed;
export function getNewLineOrDefaultFromHost(host: LanguageServiceHost | LanguageServiceShimHost, formatSettings?: FormatCodeSettings) {
return (formatSettings && formatSettings.newLineCharacter) ||
(host.getNewLine && host.getNewLine()) ||
carriageReturnLineFeed;
}
export function lineBreakPart() {