refactorConvertToGetAccessAndSetAccess: Don't trigger on leading trivia (#25054)

* refactorConvertToGetAccessAndSetAccess: Don't trigger on leading trivia

* Update API (#24966)
This commit is contained in:
Andy
2018-06-19 13:46:03 -07:00
committed by GitHub
parent db85f37669
commit 7f553f4f93
6 changed files with 37 additions and 16 deletions

View File

@@ -3045,6 +3045,10 @@ Actual: ${stringify(fullActual)}`);
}
}
public verifyRefactorsAvailable(names: ReadonlyArray<string>): void {
assert.deepEqual(unique(this.getApplicableRefactors(this.getSelection()), r => r.name), names);
}
public verifyRefactor({ name, actionName, refactors }: FourSlashInterface.VerifyRefactorOptions) {
const actualRefactors = this.getApplicableRefactors(this.getSelection()).filter(r => r.name === name && r.actions.some(a => a.name === actionName));
this.assertObjectsEqual(actualRefactors, refactors);
@@ -3815,7 +3819,7 @@ ${code}
}
/** Collects an array of unique outputs. */
function unique<T>(inputs: T[], getOutput: (t: T) => string): string[] {
function unique<T>(inputs: ReadonlyArray<T>, getOutput: (t: T) => string): string[] {
const set = ts.createMap<true>();
for (const input of inputs) {
const out = getOutput(input);
@@ -4106,6 +4110,10 @@ namespace FourSlashInterface {
this.state.verifyApplicableRefactorAvailableForRange(this.negative);
}
public refactorsAvailable(names: ReadonlyArray<string>): void {
this.state.verifyRefactorsAvailable(names);
}
public refactor(options: VerifyRefactorOptions) {
this.state.verifyRefactor(options);
}

View File

@@ -9,20 +9,19 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
type ContainerDeclaration = ClassLikeDeclaration | ObjectLiteralExpression;
interface Info {
container: ContainerDeclaration;
isStatic: boolean;
isReadonly: boolean;
type: TypeNode | undefined;
declaration: AcceptedDeclaration;
fieldName: AcceptedNameType;
accessorName: AcceptedNameType;
originalName: AcceptedNameType;
renameAccessor: boolean;
readonly container: ContainerDeclaration;
readonly isStatic: boolean;
readonly isReadonly: boolean;
readonly type: TypeNode | undefined;
readonly declaration: AcceptedDeclaration;
readonly fieldName: AcceptedNameType;
readonly accessorName: AcceptedNameType;
readonly originalName: AcceptedNameType;
readonly renameAccessor: boolean;
}
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
const { file } = context;
if (!getConvertibleFieldAtPosition(context, file)) return undefined;
if (!getConvertibleFieldAtPosition(context)) return undefined;
return [{
name: actionName,
@@ -39,7 +38,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
function getEditsForAction(context: RefactorContext, _actionName: string): RefactorEditInfo | undefined {
const { file } = context;
const fieldInfo = getConvertibleFieldAtPosition(context, file);
const fieldInfo = getConvertibleFieldAtPosition(context);
if (!fieldInfo) return undefined;
const isJS = isSourceFileJavaScript(file);
@@ -117,14 +116,14 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
return name.charCodeAt(0) === CharacterCodes._;
}
function getConvertibleFieldAtPosition(context: RefactorContext, file: SourceFile): Info | undefined {
const { startPosition, endPosition } = context;
function getConvertibleFieldAtPosition(context: RefactorContext): Info | undefined {
const { file, startPosition, endPosition } = context;
const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
const declaration = findAncestor(node.parent, isAcceptedDeclaration);
// make sure declaration have AccessibilityModifier or Static Modifier or Readonly Modifier
const meaning = ModifierFlags.AccessibilityModifier | ModifierFlags.Static | ModifierFlags.Readonly;
if (!declaration || !rangeOverlapsWithStartEnd(declaration.name, startPosition, endPosition!) // TODO: GH#18217
if (!declaration || !nodeOverlapsWithStartEnd(declaration.name, file, startPosition, endPosition!) // TODO: GH#18217
|| !isConvertibleName(declaration.name) || (getModifierFlags(declaration) | meaning) !== meaning) return undefined;
const name = declaration.name.text;

View File

@@ -439,6 +439,10 @@ namespace ts {
return startEndOverlapsWithStartEnd(r1.pos, r1.end, start, end);
}
export function nodeOverlapsWithStartEnd(node: Node, sourceFile: SourceFile, start: number, end: number) {
return startEndOverlapsWithStartEnd(node.getStart(sourceFile), node.end, start, end);
}
export function startEndOverlapsWithStartEnd(start1: number, end1: number, start2: number, end2: number) {
const start = Math.max(start1, start2);
const end = Math.min(end1, end2);