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:
+27
-11
@@ -6564,7 +6564,7 @@ namespace ts {
|
||||
// b) It references `arguments` somewhere
|
||||
const lastParam = lastOrUndefined(declaration.parameters);
|
||||
const lastParamTags = lastParam && getJSDocParameterTags(lastParam);
|
||||
const lastParamVariadicType = lastParamTags && firstDefined(lastParamTags, p =>
|
||||
const lastParamVariadicType = firstDefined(lastParamTags, p =>
|
||||
p.typeExpression && isJSDocVariadicType(p.typeExpression.type) ? p.typeExpression.type : undefined);
|
||||
if (!lastParamVariadicType && !containsArgumentsReference(declaration)) {
|
||||
return false;
|
||||
@@ -9639,7 +9639,7 @@ namespace ts {
|
||||
}
|
||||
else if (target.flags & TypeFlags.IndexedAccess) {
|
||||
// A type S is related to a type T[K] if S is related to A[K], where K is string-like and
|
||||
// A is the apparent type of T.
|
||||
// A is the constraint of T.
|
||||
const constraint = getConstraintOfIndexedAccess(<IndexedAccessType>target);
|
||||
if (constraint) {
|
||||
if (result = isRelatedTo(source, constraint, reportErrors)) {
|
||||
@@ -9675,7 +9675,7 @@ namespace ts {
|
||||
}
|
||||
else if (source.flags & TypeFlags.IndexedAccess) {
|
||||
// A type S[K] is related to a type T if A[K] is related to T, where K is string-like and
|
||||
// A is the apparent type of S.
|
||||
// A is the constraint of S.
|
||||
const constraint = getConstraintOfIndexedAccess(<IndexedAccessType>source);
|
||||
if (constraint) {
|
||||
if (result = isRelatedTo(constraint, target, reportErrors)) {
|
||||
@@ -9683,10 +9683,11 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (target.flags & TypeFlags.IndexedAccess && (<IndexedAccessType>source).indexType === (<IndexedAccessType>target).indexType) {
|
||||
// if we have indexed access types with identical index types, see if relationship holds for
|
||||
// the two object types.
|
||||
else if (target.flags & TypeFlags.IndexedAccess) {
|
||||
if (result = isRelatedTo((<IndexedAccessType>source).objectType, (<IndexedAccessType>target).objectType, reportErrors)) {
|
||||
result &= isRelatedTo((<IndexedAccessType>source).indexType, (<IndexedAccessType>target).indexType, reportErrors);
|
||||
}
|
||||
if (result) {
|
||||
errorInfo = saveErrorInfo;
|
||||
return result;
|
||||
}
|
||||
@@ -10967,7 +10968,7 @@ namespace ts {
|
||||
return type === typeParameter || type.flags & TypeFlags.UnionOrIntersection && forEach((<UnionOrIntersectionType>type).types, t => isTypeParameterAtTopLevel(t, typeParameter));
|
||||
}
|
||||
|
||||
/** Create an object with properties named in the string literal type. Every property has type `{}` */
|
||||
/** Create an object with properties named in the string literal type. Every property has type `any` */
|
||||
function createEmptyObjectTypeFromStringLiteral(type: Type) {
|
||||
const members = createSymbolTable();
|
||||
forEachType(type, t => {
|
||||
@@ -10976,7 +10977,7 @@ namespace ts {
|
||||
}
|
||||
const name = escapeLeadingUnderscores((t as StringLiteralType).value);
|
||||
const literalProp = createSymbol(SymbolFlags.Property, name);
|
||||
literalProp.type = emptyObjectType;
|
||||
literalProp.type = anyType;
|
||||
if (t.symbol) {
|
||||
literalProp.declarations = t.symbol.declarations;
|
||||
literalProp.valueDeclaration = t.symbol.valueDeclaration;
|
||||
@@ -11031,7 +11032,9 @@ namespace ts {
|
||||
const templateType = getTemplateTypeFromMappedType(target);
|
||||
const inference = createInferenceInfo(typeParameter);
|
||||
inferTypes([inference], sourceType, templateType);
|
||||
return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : emptyObjectType;
|
||||
return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) :
|
||||
inference.contraCandidates ? getCommonSubtype(inference.contraCandidates) :
|
||||
emptyObjectType;
|
||||
}
|
||||
|
||||
function getUnmatchedProperty(source: Type, target: Type, requireOptionalProperties: boolean) {
|
||||
@@ -18377,6 +18380,9 @@ namespace ts {
|
||||
|
||||
function checkObjectLiteralAssignment(node: ObjectLiteralExpression, sourceType: Type): Type {
|
||||
const properties = node.properties;
|
||||
if (strictNullChecks && properties.length === 0) {
|
||||
return checkNonNullType(sourceType, node);
|
||||
}
|
||||
for (const p of properties) {
|
||||
checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, properties);
|
||||
}
|
||||
@@ -21446,7 +21452,13 @@ namespace ts {
|
||||
if (isBindingPattern(node.name)) {
|
||||
// Don't validate for-in initializer as it is already an error
|
||||
if (node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) {
|
||||
checkTypeAssignableTo(checkExpressionCached(node.initializer), getWidenedTypeForVariableLikeDeclaration(node), node, /*headMessage*/ undefined);
|
||||
const initializerType = checkExpressionCached(node.initializer);
|
||||
if (strictNullChecks && node.name.elements.length === 0) {
|
||||
checkNonNullType(initializerType, node);
|
||||
}
|
||||
else {
|
||||
checkTypeAssignableTo(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, /*headMessage*/ undefined);
|
||||
}
|
||||
checkParameterInitializer(node);
|
||||
}
|
||||
return;
|
||||
@@ -26196,7 +26208,7 @@ namespace ts {
|
||||
function checkGrammarBindingElement(node: BindingElement) {
|
||||
if (node.dotDotDotToken) {
|
||||
const elements = (<BindingPattern>node.parent).elements;
|
||||
if (node !== lastOrUndefined(elements)) {
|
||||
if (node !== last(elements)) {
|
||||
return grammarErrorOnNode(node, Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
|
||||
}
|
||||
|
||||
@@ -26204,6 +26216,10 @@ namespace ts {
|
||||
return grammarErrorOnNode(node.name, Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
|
||||
}
|
||||
|
||||
if (node.propertyName) {
|
||||
return grammarErrorOnNode(node.name, Diagnostics.A_rest_element_cannot_have_a_property_name);
|
||||
}
|
||||
|
||||
if (node.initializer) {
|
||||
// Error on equals token which immediately precedes the initializer
|
||||
return grammarErrorAtPos(node, node.initializer.pos - 1, 1, Diagnostics.A_rest_element_cannot_have_an_initializer);
|
||||
|
||||
@@ -183,6 +183,10 @@ namespace ts {
|
||||
|
||||
/** Like `forEach`, but suitable for use with numbers and strings (which may be falsy). */
|
||||
export function firstDefined<T, U>(array: ReadonlyArray<T> | undefined, callback: (element: T, index: number) => U | undefined): U | undefined {
|
||||
if (array === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const result = callback(array[i], i);
|
||||
if (result !== undefined) {
|
||||
|
||||
@@ -1976,6 +1976,10 @@
|
||||
"category": "Error",
|
||||
"code": 2565
|
||||
},
|
||||
"A rest element cannot have a property name.": {
|
||||
"category": "Error",
|
||||
"code": 2566
|
||||
},
|
||||
"JSX element attributes type '{0}' may not be a union type.": {
|
||||
"category": "Error",
|
||||
"code": 2600
|
||||
@@ -3893,10 +3897,6 @@
|
||||
"category": "Message",
|
||||
"code": 95002
|
||||
},
|
||||
"Extract symbol": {
|
||||
"category": "Message",
|
||||
"code": 95003
|
||||
},
|
||||
"Extract to {0} in {1}": {
|
||||
"category": "Message",
|
||||
"code": 95004
|
||||
|
||||
@@ -1268,12 +1268,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitBindingElement(node: BindingElement) {
|
||||
emitIfPresent(node.dotDotDotToken);
|
||||
if (node.propertyName) {
|
||||
emit(node.propertyName);
|
||||
writePunctuation(":");
|
||||
writeSpace();
|
||||
}
|
||||
emitIfPresent(node.dotDotDotToken);
|
||||
emit(node.name);
|
||||
emitInitializer(node.initializer);
|
||||
}
|
||||
|
||||
+13
-4
@@ -126,8 +126,8 @@ namespace ts {
|
||||
case SyntaxKind.BindingElement:
|
||||
return visitNodes(cbNode, cbNodes, node.decorators) ||
|
||||
visitNodes(cbNode, cbNodes, node.modifiers) ||
|
||||
visitNode(cbNode, (<BindingElement>node).propertyName) ||
|
||||
visitNode(cbNode, (<BindingElement>node).dotDotDotToken) ||
|
||||
visitNode(cbNode, (<BindingElement>node).propertyName) ||
|
||||
visitNode(cbNode, (<BindingElement>node).name) ||
|
||||
visitNode(cbNode, (<BindingElement>node).initializer);
|
||||
case SyntaxKind.FunctionType:
|
||||
@@ -6830,7 +6830,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseTemplateTag(atToken: AtToken, tagName: Identifier): JSDocTemplateTag | undefined {
|
||||
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTemplateTag)) {
|
||||
if (some(tags, isJSDocTemplateTag)) {
|
||||
parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, Diagnostics._0_tag_already_specified, tagName.escapedText);
|
||||
}
|
||||
|
||||
@@ -6839,14 +6839,14 @@ namespace ts {
|
||||
const typeParametersPos = getNodePos();
|
||||
|
||||
while (true) {
|
||||
const name = parseJSDocIdentifierName();
|
||||
const typeParameter = <TypeParameterDeclaration>createNode(SyntaxKind.TypeParameter);
|
||||
const name = parseJSDocIdentifierNameWithOptionalBraces();
|
||||
skipWhitespace();
|
||||
if (!name) {
|
||||
parseErrorAtPosition(scanner.getStartPos(), 0, Diagnostics.Identifier_expected);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const typeParameter = <TypeParameterDeclaration>createNode(SyntaxKind.TypeParameter, name.pos);
|
||||
typeParameter.name = name;
|
||||
finishNode(typeParameter);
|
||||
|
||||
@@ -6869,6 +6869,15 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseJSDocIdentifierNameWithOptionalBraces(): Identifier | undefined {
|
||||
const parsedBrace = parseOptional(SyntaxKind.OpenBraceToken);
|
||||
const res = parseJSDocIdentifierName();
|
||||
if (parsedBrace) {
|
||||
parseExpected(SyntaxKind.CloseBraceToken);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function nextJSDocToken(): JsDocSyntaxKind {
|
||||
return currentToken = scanner.scanJSDocToken();
|
||||
}
|
||||
|
||||
@@ -474,11 +474,6 @@ namespace ts {
|
||||
cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
|
||||
}
|
||||
|
||||
// Ignore emits from the program
|
||||
if (isEmittedFileOfProgram(resolutionHost.getCurrentProgram(), fileOrDirectory)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the files are added to project root or node_modules directory, always run through the invalidation process
|
||||
// Otherwise run through invalidation only if adding to the immediate directory
|
||||
if (!allFilesHaveInvalidatedResolution &&
|
||||
@@ -582,6 +577,10 @@ namespace ts {
|
||||
if (!isPathWithDefaultFailedLookupExtension(fileOrDirectoryPath) && !customFailedLookupPaths.has(fileOrDirectoryPath)) {
|
||||
return false;
|
||||
}
|
||||
// Ignore emits from the program
|
||||
if (isEmittedFileOfProgram(resolutionHost.getCurrentProgram(), fileOrDirectoryPath)) {
|
||||
return false;
|
||||
}
|
||||
// Resolution need to be invalidated if failed lookup location is same as the file or directory getting created
|
||||
isChangedFailedLookupLocation = location => resolutionHost.toPath(location) === fileOrDirectoryPath;
|
||||
}
|
||||
|
||||
@@ -2029,7 +2029,13 @@ namespace ts {
|
||||
return token !== undefined && isNonContextualKeyword(token);
|
||||
}
|
||||
|
||||
export function isTrivia(token: SyntaxKind) {
|
||||
export type TriviaKind = SyntaxKind.SingleLineCommentTrivia
|
||||
| SyntaxKind.MultiLineCommentTrivia
|
||||
| SyntaxKind.NewLineTrivia
|
||||
| SyntaxKind.WhitespaceTrivia
|
||||
| SyntaxKind.ShebangTrivia
|
||||
| SyntaxKind.ConflictMarkerTrivia;
|
||||
export function isTrivia(token: SyntaxKind): token is TriviaKind {
|
||||
return SyntaxKind.FirstTriviaToken <= token && token <= SyntaxKind.LastTriviaToken;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,12 +33,15 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
|
||||
});
|
||||
}
|
||||
private runTest(directoryName: string) {
|
||||
describe(directoryName, () => {
|
||||
// tslint:disable-next-line:no-this-assignment
|
||||
const cls = this;
|
||||
const timeout = 600_000; // 10 minutes
|
||||
describe(directoryName, function(this: Mocha.ISuiteCallbackContext) {
|
||||
this.timeout(timeout);
|
||||
const cp = require("child_process");
|
||||
|
||||
it("should build successfully", () => {
|
||||
let cwd = path.join(__dirname, "../../", this.testDir, directoryName);
|
||||
const timeout = 600000; // 600s = 10 minutes
|
||||
let cwd = path.join(__dirname, "../../", cls.testDir, directoryName);
|
||||
const stdio = isWorker ? "pipe" : "inherit";
|
||||
let types: string[];
|
||||
if (fs.existsSync(path.join(cwd, "test.json"))) {
|
||||
@@ -61,9 +64,9 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
|
||||
fs.unlinkSync(path.join(cwd, "package-lock.json"));
|
||||
}
|
||||
if (fs.existsSync(path.join(cwd, "node_modules"))) {
|
||||
require("del").sync(path.join(cwd, "node_modules"));
|
||||
require("del").sync(path.join(cwd, "node_modules"), { force: true });
|
||||
}
|
||||
const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout, shell: true, stdio });
|
||||
const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout: timeout / 2, shell: true, stdio }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
|
||||
if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed: ${install.stderr.toString()}`);
|
||||
}
|
||||
const args = [path.join(__dirname, "tsc.js")];
|
||||
@@ -71,8 +74,8 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
|
||||
args.push("--types", types.join(","));
|
||||
}
|
||||
args.push("--noEmit");
|
||||
Harness.Baseline.runBaseline(`${this.kind()}/${directoryName}.log`, () => {
|
||||
return this.report(cp.spawnSync(`node`, args, { cwd, timeout, shell: true }), cwd);
|
||||
Harness.Baseline.runBaseline(`${cls.kind()}/${directoryName}.log`, () => {
|
||||
return cls.report(cp.spawnSync(`node`, args, { cwd, timeout, shell: true }), cwd);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+29
-14
@@ -1102,20 +1102,30 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
public verifyReferenceGroups(startRanges: Range | Range[], parts: FourSlashInterface.ReferenceGroup[]): void {
|
||||
const fullExpected = ts.map(parts, ({ definition, ranges }) => ({ definition, ranges: ranges.map(rangeToReferenceEntry) }));
|
||||
interface ReferenceGroupJson {
|
||||
definition: string | { text: string, range: ts.TextSpan };
|
||||
references: ts.ReferenceEntry[];
|
||||
}
|
||||
const fullExpected = ts.map<FourSlashInterface.ReferenceGroup, ReferenceGroupJson>(parts, ({ definition, ranges }) => ({
|
||||
definition: typeof definition === "string" ? definition : { ...definition, range: textSpanFromRange(definition.range) },
|
||||
references: ranges.map(rangeToReferenceEntry),
|
||||
}));
|
||||
|
||||
for (const startRange of toArray(startRanges)) {
|
||||
this.goToRangeStart(startRange);
|
||||
const fullActual = ts.map(this.findReferencesAtCaret(), ({ definition, references }) => ({
|
||||
definition: definition.displayParts.map(d => d.text).join(""),
|
||||
ranges: references
|
||||
}));
|
||||
const fullActual = ts.map<ts.ReferencedSymbol, ReferenceGroupJson>(this.findReferencesAtCaret(), ({ definition, references }, i) => {
|
||||
const text = definition.displayParts.map(d => d.text).join("");
|
||||
return {
|
||||
definition: typeof fullExpected[i].definition === "string" ? text : { text, range: definition.textSpan },
|
||||
references,
|
||||
};
|
||||
});
|
||||
this.assertObjectsEqual(fullActual, fullExpected);
|
||||
}
|
||||
|
||||
function rangeToReferenceEntry(r: Range): ts.ReferenceEntry {
|
||||
const { isWriteAccess, isDefinition, isInString } = (r.marker && r.marker.data) || { isWriteAccess: false, isDefinition: false, isInString: undefined };
|
||||
const result: ts.ReferenceEntry = { fileName: r.fileName, textSpan: { start: r.start, length: r.end - r.start }, isWriteAccess: !!isWriteAccess, isDefinition: !!isDefinition };
|
||||
const result: ts.ReferenceEntry = { fileName: r.fileName, textSpan: textSpanFromRange(r), isWriteAccess: !!isWriteAccess, isDefinition: !!isDefinition };
|
||||
if (isInString !== undefined) {
|
||||
result.isInString = isInString;
|
||||
}
|
||||
@@ -1139,7 +1149,7 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public verifySingleReferenceGroup(definition: string, ranges?: Range[]) {
|
||||
public verifySingleReferenceGroup(definition: FourSlashInterface.ReferenceGroupDefinition, ranges?: Range[]) {
|
||||
ranges = ranges || this.getRanges();
|
||||
this.verifyReferenceGroups(ranges, [{ definition, ranges }]);
|
||||
}
|
||||
@@ -1305,8 +1315,13 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
|
||||
public verifyRangesAreRenameLocations(options?: Range[] | { findInStrings?: boolean, findInComments?: boolean, ranges?: Range[] }) {
|
||||
const ranges = ts.isArray(options) ? options : options && options.ranges || this.getRanges();
|
||||
this.verifyRenameLocations(ranges, { ranges, ...options });
|
||||
if (ts.isArray(options)) {
|
||||
this.verifyRenameLocations(options, options);
|
||||
}
|
||||
else {
|
||||
const ranges = options && options.ranges || this.getRanges();
|
||||
this.verifyRenameLocations(ranges, { ranges, ...options });
|
||||
}
|
||||
}
|
||||
|
||||
public verifyRenameLocations(startRanges: Range | Range[], options: Range[] | { findInStrings?: boolean, findInComments?: boolean, ranges: Range[] }) {
|
||||
@@ -2568,9 +2583,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
const originalContent = scriptInfo.content;
|
||||
for (const codeFix of codeFixes) {
|
||||
this.applyEdits(codeFix.changes[0].fileName, codeFix.changes[0].textChanges, /*isFormattingEdit*/ false);
|
||||
let text = this.rangeText(ranges[0]);
|
||||
// TODO:GH#18445 (remove this line to see errors in many `importNameCodeFix` tests)
|
||||
text = text.replace(/\r\n/g, "\n");
|
||||
const text = this.rangeText(ranges[0]);
|
||||
actualTextArray.push(text);
|
||||
scriptInfo.updateContent(originalContent);
|
||||
}
|
||||
@@ -4077,7 +4090,7 @@ namespace FourSlashInterface {
|
||||
this.state.verifyNoReferences(markerNameOrRange);
|
||||
}
|
||||
|
||||
public singleReferenceGroup(definition: string, ranges?: FourSlash.Range[]) {
|
||||
public singleReferenceGroup(definition: ReferenceGroupDefinition, ranges?: FourSlash.Range[]) {
|
||||
this.state.verifySingleReferenceGroup(definition, ranges);
|
||||
}
|
||||
|
||||
@@ -4589,10 +4602,12 @@ namespace FourSlashInterface {
|
||||
}
|
||||
|
||||
export interface ReferenceGroup {
|
||||
definition: string;
|
||||
definition: ReferenceGroupDefinition;
|
||||
ranges: FourSlash.Range[];
|
||||
}
|
||||
|
||||
export type ReferenceGroupDefinition = string | { text: string, range: FourSlash.Range };
|
||||
|
||||
export interface ApplyRefactorOptions {
|
||||
refactorName: string;
|
||||
actionName: string;
|
||||
|
||||
@@ -121,7 +121,6 @@ namespace ts {
|
||||
const sourceFile = program.getSourceFile(path);
|
||||
const context: RefactorContext = {
|
||||
cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse },
|
||||
newLineCharacter,
|
||||
program,
|
||||
file: sourceFile,
|
||||
startPosition: selectionRange.start,
|
||||
@@ -185,7 +184,6 @@ namespace ts {
|
||||
const sourceFile = program.getSourceFile(f.path);
|
||||
const context: RefactorContext = {
|
||||
cancellationToken: { throwIfCancellationRequested: noop, isCancellationRequested: returnFalse },
|
||||
newLineCharacter,
|
||||
program,
|
||||
file: sourceFile,
|
||||
startPosition: selectionRange.start,
|
||||
|
||||
@@ -888,6 +888,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[将异步修饰符添加到包含函数]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -4620,6 +4623,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[映射的对象类型隐式地含有 "any" 模板类型。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
||||
@@ -888,6 +888,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[將 async 修飾詞新增至包含的函式]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -4620,6 +4623,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[對應的物件類型隱含具有 'any' 範本類型。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
||||
@@ -897,6 +897,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Přidat modifikátor async do obsahující funkce]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -4629,6 +4632,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Typu mapovaného objektu má implicitně typ šablony any.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
||||
@@ -885,6 +885,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Async-Modifizierer zur enthaltenden Funktion hinzufügen]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -4617,6 +4620,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Der zugeordnete Objekttyp weist implizit einen any-Vorlagentyp auf.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
||||
@@ -897,6 +897,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Agregar el modificador async a la función contenedora]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -4629,6 +4632,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[El tipo de objeto asignado tiene implícitamente un tipo de plantilla "any".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
||||
@@ -897,6 +897,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ajouter le modificateur async dans la fonction conteneur]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -4629,6 +4632,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Le type d'objet mappé a implicitement un type de modèle 'any'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
||||
@@ -888,6 +888,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Aggiungere il modificatore async alla funzione contenitore]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -4620,6 +4623,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Il tipo di oggetto con mapping contiene implicitamente un tipo di modello 'any'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
||||
@@ -888,6 +888,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[含まれている関数に async 修飾子を追加します]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -4620,6 +4623,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[マップされたオブジェクト型のテンプレートの型は暗黙的に 'any' になります。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
||||
@@ -888,6 +888,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[포함된 함수에 async 한정자 추가]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -4620,6 +4623,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[매핑된 개체 형식에는 'any' 템플릿 형식이 암시적으로 포함됩니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
||||
@@ -878,6 +878,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Dodaj modyfikator asynchroniczny do funkcji zawierającej]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -4610,6 +4613,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Zmapowany typ obiektu niejawnie ma typ szablonu „any”.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
||||
@@ -878,6 +878,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Adicione o modificador assíncrono que contém a função]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -4610,6 +4613,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[O tipo de objeto mapeado implicitamente tem um tipo de modelo 'any'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
||||
@@ -887,6 +887,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Добавьте модификатор async в содержащую функцию]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -4619,6 +4622,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Сопоставленный объект неявно имеет тип шаблона "любой".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
||||
@@ -881,6 +881,9 @@
|
||||
<Item ItemId=";Add_async_modifier_to_containing_function_90029" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add async modifier to containing function]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[İçeren işleve zaman uyumsuz değiştirici ekle]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -4613,6 +4616,9 @@
|
||||
<Item ItemId=";Mapped_object_type_implicitly_has_an_any_template_type_7039" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Mapped object type implicitly has an 'any' template type.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Eşleştirilmiş nesne türü örtük olarak 'any' şablon türüne sahip.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
|
||||
@@ -1810,9 +1810,9 @@ namespace ts.server {
|
||||
let info = this.getScriptInfoForPath(path);
|
||||
if (!info) {
|
||||
const isDynamic = isDynamicFileName(fileName);
|
||||
Debug.assert(isRootedDiskPath(fileName) || isDynamic || openedByClient, "Script info with non-dynamic relative file name can only be open script info");
|
||||
Debug.assert(!isRootedDiskPath(fileName) || this.currentDirectory === currentDirectory || !this.openFilesWithNonRootedDiskPath.has(this.toCanonicalFileName(fileName)), "Open script files with non rooted disk path opened with current directory context cannot have same canonical names");
|
||||
Debug.assert(!isDynamic || this.currentDirectory === currentDirectory, "Dynamic files must always have current directory context since containing external project name will always match the script info name.");
|
||||
Debug.assert(isRootedDiskPath(fileName) || isDynamic || openedByClient, "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nScript info with non-dynamic relative file name can only be open script info`);
|
||||
Debug.assert(!isRootedDiskPath(fileName) || this.currentDirectory === currentDirectory || !this.openFilesWithNonRootedDiskPath.has(this.toCanonicalFileName(fileName)), "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nOpen script files with non rooted disk path opened with current directory context cannot have same canonical names`);
|
||||
Debug.assert(!isDynamic || this.currentDirectory === currentDirectory, "", () => `${JSON.stringify({ fileName, currentDirectory, hostCurrentDirectory: this.currentDirectory, openKeys: arrayFrom(this.openFilesWithNonRootedDiskPath.keys()) })}\nDynamic files must always have current directory context since containing external project name will always match the script info name.`);
|
||||
// If the file is not opened by client and the file doesnot exist on the disk, return
|
||||
if (!openedByClient && !isDynamic && !(hostToQueryFileExistsOn || this.host).fileExists(fileName)) {
|
||||
return;
|
||||
|
||||
@@ -1665,9 +1665,9 @@ namespace ts.server {
|
||||
return { startPosition, endPosition };
|
||||
}
|
||||
|
||||
private mapCodeAction(project: Project, { description, changes: unmappedChanges, commands }: CodeAction): protocol.CodeAction {
|
||||
private mapCodeAction(project: Project, { description, changes: unmappedChanges, commands, fixId }: CodeFixAction): protocol.CodeFixAction {
|
||||
const changes = unmappedChanges.map(change => this.mapTextChangesToCodeEditsUsingScriptinfo(change, project.getScriptInfoForNormalizedPath(toNormalizedPath(change.fileName))));
|
||||
return { description, changes, commands };
|
||||
return { description, changes, commands, fixId };
|
||||
}
|
||||
|
||||
private mapTextChangesToCodeEdits(project: Project, textChanges: ReadonlyArray<FileTextChanges>): protocol.FileCodeEdits[] {
|
||||
|
||||
+38
-29
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ namespace ts {
|
||||
export interface CodeFixContextBase extends textChanges.TextChangesContext {
|
||||
sourceFile: SourceFile;
|
||||
program: Program;
|
||||
host: LanguageServiceHost;
|
||||
cancellationToken: CancellationToken;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -627,7 +627,6 @@ namespace ts.Completions {
|
||||
host,
|
||||
program,
|
||||
checker,
|
||||
newLineCharacter: host.getNewLine(),
|
||||
compilerOptions,
|
||||
sourceFile,
|
||||
formatContext,
|
||||
|
||||
@@ -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) });
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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[] {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
]
|
||||
|
||||
@@ -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
|
||||
}
|
||||
]
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
],
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
],
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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[] {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user