From bed084f8586607b20b2f10a6e0139ffaf594ba92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Fri, 23 Feb 2018 17:42:39 +0800 Subject: [PATCH 1/9] add refactor of convert private field to getter and setter --- src/compiler/diagnosticMessages.json | 4 + .../refactors/GenerateGetterAndSetter.ts | 151 ++++++++++++++++++ src/services/refactors/refactors.ts | 6 + ...refactorConvertToGetAccessAndSetAccess1.ts | 21 +++ ...efactorConvertToGetAccessAndSetAccess10.ts | 23 +++ ...efactorConvertToGetAccessAndSetAccess11.ts | 21 +++ ...refactorConvertToGetAccessAndSetAccess2.ts | 21 +++ ...refactorConvertToGetAccessAndSetAccess3.ts | 21 +++ ...refactorConvertToGetAccessAndSetAccess4.ts | 21 +++ ...refactorConvertToGetAccessAndSetAccess5.ts | 21 +++ ...refactorConvertToGetAccessAndSetAccess6.ts | 21 +++ ...refactorConvertToGetAccessAndSetAccess7.ts | 21 +++ ...refactorConvertToGetAccessAndSetAccess8.ts | 21 +++ ...refactorConvertToGetAccessAndSetAccess9.ts | 23 +++ 14 files changed, 396 insertions(+) create mode 100644 src/services/refactors/GenerateGetterAndSetter.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess1.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess10.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess11.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess2.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess3.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess4.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess5.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess6.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess7.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess8.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess9.ts diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index bbc00e6fbc621..17847eac5dc84 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4134,5 +4134,9 @@ "Convert all constructor functions to classes": { "category": "Message", "code": 95045 + }, + "Generate 'get' and 'set' accessors": { + "category": "Message", + "code": 95046 } } diff --git a/src/services/refactors/GenerateGetterAndSetter.ts b/src/services/refactors/GenerateGetterAndSetter.ts new file mode 100644 index 0000000000000..f3aeaeeaaffb9 --- /dev/null +++ b/src/services/refactors/GenerateGetterAndSetter.ts @@ -0,0 +1,151 @@ +/* @internal */ +namespace ts.refactor.GenerateGetterAndSetter { + const actionName = "Generate 'get' and 'set' accessors"; + const actionDescription = Diagnostics.Generate_get_and_set_accessors.message; + + registerRefactor(actionName, { getEditsForAction, getAvailableActions }); + + function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined { + const { file, startPosition } = context; + + const fieldInfo = getConvertibleFieldAtPosition(file, startPosition); + if (!fieldInfo) return undefined; + + return [ + { + name: actionName, + description: actionDescription, + actions: [ + { + name: actionName, + description: actionDescription + } + ] + } + ]; + } + + function getEditsForAction(context: RefactorContext, _actionName: string): RefactorEditInfo | undefined { + const { file, startPosition } = context; + + const fieldInfo = getConvertibleFieldAtPosition(file, startPosition); + if (!fieldInfo) return undefined; + + const changeTracker = textChanges.ChangeTracker.fromContext(context); + const newLineCharacter = getNewLineOrDefaultFromHost(context.host, context.formatContext.options); + + const { fieldName, accessorName, propertyDeclaration, needUpdateName, hasModifiers, needUpdateModifiers } = fieldInfo; + const accessorModifiers = hasModifiers ? createNodeArray([createToken(SyntaxKind.PublicKeyword)]) : undefined; + + const getAccessor = generateGetAccessor(propertyDeclaration, fieldName, accessorName, accessorModifiers); + const setAccessor = generateSetAccessor(propertyDeclaration, fieldName, accessorName, accessorModifiers); + + const modifiers = needUpdateModifiers ? createNodeArray([createToken(SyntaxKind.PrivateKeyword)]) : propertyDeclaration.modifiers; + if (needUpdateName || needUpdateModifiers) { + changeTracker.replaceNode(file, propertyDeclaration, updateOriginPropertyDeclaration(propertyDeclaration, fieldName, modifiers), { + suffix: newLineCharacter + }); + } + + changeTracker.insertNodeAfter(file, propertyDeclaration, getAccessor); + changeTracker.insertNodeAfter(file, propertyDeclaration, setAccessor); + + return { + edits: changeTracker.getChanges(), + renameFilename: undefined, + renameLocation: undefined, + }; + } + + interface Info { originName: string; fieldName: string; accessorName: string; propertyDeclaration: PropertyDeclaration; needUpdateName: boolean; hasModifiers: boolean; needUpdateModifiers: boolean; } + function getConvertibleFieldAtPosition(file: SourceFile, startPosition: number): Info | undefined { + const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); + const propertyDeclaration = findAncestor(node.parent, isPropertyDeclaration); + + if (!(propertyDeclaration && propertyDeclaration.name.kind === SyntaxKind.Identifier && + (getModifierFlags(propertyDeclaration) | ModifierFlags.AccessibilityModifier) === ModifierFlags.AccessibilityModifier)) return undefined; + + const containerClass = getContainingClass(propertyDeclaration); + if (!containerClass) return undefined; + + const members = getMembersOfDeclaration(containerClass); + if (!members) return undefined; + + const needUpdateName = propertyDeclaration.name.text.charCodeAt(0) !== CharacterCodes._; + + const accessorName = needUpdateName ? propertyDeclaration.name.text : propertyDeclaration.name.text.substring(1); + const fieldName = `_${accessorName}`; + + if (find(members, member => needUpdateName ? member.name.getText() === fieldName : member.name.getText() === accessorName)) return undefined; + + const hasModifiers = !!find(members, member => !!member.modifiers); + const needUpdateModifiers = hasModifiers && (!propertyDeclaration.modifiers || hasModifier(propertyDeclaration, ModifierFlags.Public)); + + return { + originName: propertyDeclaration.name.text, + fieldName, + accessorName, + propertyDeclaration, + needUpdateName, + hasModifiers, + needUpdateModifiers + }; + } + + function generateGetAccessor (propertyDeclaration: PropertyDeclaration, fieldName: string, name: string, modifiers: ModifiersArray) { + return createGetAccessor( + /*decorators*/ undefined, + modifiers, + name, + /*parameters*/ undefined, + propertyDeclaration.type, + createBlock([ + createReturn( + createPropertyAccess( + createThis(), + fieldName + ) + ) + ], /*multiLine*/ true) + ); + } + + function generateSetAccessor (propertyDeclaration: PropertyDeclaration, fieldName: string, name: string, modifiers: ModifiersArray) { + return createSetAccessor( + /*decorators*/ undefined, + modifiers, + name, + [createParameter( + /*decorators*/ undefined, + /*modifies*/ undefined, + /*dotDotDotToken*/ undefined, + createIdentifier("value"), + /*questionToken*/ undefined, + propertyDeclaration.type + )], + createBlock([ + createStatement( + createAssignment( + createPropertyAccess( + createThis(), + fieldName + ), + createIdentifier("value") + ) + ) + ], /*multiLine*/ true) + ); + } + + function updateOriginPropertyDeclaration (propertyDeclaration: PropertyDeclaration, fieldName: string, modifiers: ModifiersArray) { + return updateProperty( + propertyDeclaration, + /*decorators*/ undefined, + modifiers, + fieldName, + /*questionOrExclamationToken*/ undefined, + propertyDeclaration.type, + propertyDeclaration.initializer, + ); + } +} diff --git a/src/services/refactors/refactors.ts b/src/services/refactors/refactors.ts index da2f08a8e9fcf..7f6faf986bcb4 100644 --- a/src/services/refactors/refactors.ts +++ b/src/services/refactors/refactors.ts @@ -1 +1,7 @@ /// +<<<<<<< HEAD +======= +/// +/// +/// +>>>>>>> add refactor of convert private field to getter and setter diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess1.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess1.ts new file mode 100644 index 0000000000000..90b6dce8aa10a --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess1.ts @@ -0,0 +1,21 @@ +/// + +//// class A { +//// /*a*/public a: string;/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private _a: string; + public get a(): string { + return this._a; + } + public set a(value: string) { + this._a = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess10.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess10.ts new file mode 100644 index 0000000000000..8fa18e861b480 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess10.ts @@ -0,0 +1,23 @@ +/// + +//// class A { +//// public a: string; +//// /*a*/b: number;/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + public a: string; + private _b: number; + public get b(): number { + return this._b; + } + public set b(value: number) { + this._b = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess11.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess11.ts new file mode 100644 index 0000000000000..91e209a5d263f --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess11.ts @@ -0,0 +1,21 @@ +/// + +//// class A { +//// /*a*/public a: string = "foo";/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private _a: string = "foo"; + public get a(): string { + return this._a; + } + public set a(value: string) { + this._a = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess2.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess2.ts new file mode 100644 index 0000000000000..aa8c77313dd97 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess2.ts @@ -0,0 +1,21 @@ +/// + +//// class A { +//// /*a*/protected a: string;/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + protected _a: string; + public get a(): string { + return this._a; + } + public set a(value: string) { + this._a = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess3.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess3.ts new file mode 100644 index 0000000000000..4f26ed33366cf --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess3.ts @@ -0,0 +1,21 @@ +/// + +//// class A { +//// /*a*/private a: string;/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private _a: string; + public get a(): string { + return this._a; + } + public set a(value: string) { + this._a = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess4.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess4.ts new file mode 100644 index 0000000000000..1597244e29f4a --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess4.ts @@ -0,0 +1,21 @@ +/// + +//// class A { +//// /*a*/private _a: string;/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private _a: string; + public get a(): string { + return this._a; + } + public set a(value: string) { + this._a = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess5.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess5.ts new file mode 100644 index 0000000000000..16edc3515d379 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess5.ts @@ -0,0 +1,21 @@ +/// + +//// class A { +//// /*a*/protected _a: string;/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + protected _a: string; + public get a(): string { + return this._a; + } + public set a(value: string) { + this._a = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess6.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess6.ts new file mode 100644 index 0000000000000..476a1f851e05b --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess6.ts @@ -0,0 +1,21 @@ +/// + +//// class A { +//// /*a*/public _a: string;/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private _a: string; + public get a(): string { + return this._a; + } + public set a(value: string) { + this._a = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess7.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess7.ts new file mode 100644 index 0000000000000..e2f2022db8c63 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess7.ts @@ -0,0 +1,21 @@ +/// + +//// class A { +//// /*a*/_a: string;/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + _a: string; + get a(): string { + return this._a; + } + set a(value: string) { + this._a = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess8.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess8.ts new file mode 100644 index 0000000000000..c6bfda108664c --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess8.ts @@ -0,0 +1,21 @@ +/// + +//// class A { +//// /*a*/a: string;/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + _a: string; + get a(): string { + return this._a; + } + set a(value: string) { + this._a = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess9.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess9.ts new file mode 100644 index 0000000000000..be4c47967a570 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess9.ts @@ -0,0 +1,23 @@ +/// + +//// class A { +//// a: string; +//// /*a*/b: number;/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + a: string; + _b: number; + get b(): number { + return this._b; + } + set b(value: number) { + this._b = value; + } +}`, +}); From 0e4d513aa33d24c7e17dc8abd2a8088281f668db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Mon, 26 Feb 2018 15:45:00 +0800 Subject: [PATCH 2/9] fix refactor --- .../codefixes/fixStrictClassInitialization.ts | 5 +- ...s => generateGetAccessorAndSetAccessor.ts} | 56 ++++++++++++------- src/services/refactors/refactors.ts | 7 +-- src/services/utilities.ts | 4 ++ ...efactorConvertToGetAccessAndSetAccess12.ts | 23 ++++++++ ...efactorConvertToGetAccessAndSetAccess13.ts | 21 +++++++ ...efactorConvertToGetAccessAndSetAccess14.ts | 21 +++++++ ...efactorConvertToGetAccessAndSetAccess15.ts | 16 ++++++ ...efactorConvertToGetAccessAndSetAccess16.ts | 9 +++ ...efactorConvertToGetAccessAndSetAccess17.ts | 11 ++++ ...refactorConvertToGetAccessAndSetAccess2.ts | 6 +- ...refactorConvertToGetAccessAndSetAccess5.ts | 6 +- 12 files changed, 149 insertions(+), 36 deletions(-) rename src/services/refactors/{GenerateGetterAndSetter.ts => generateGetAccessorAndSetAccessor.ts} (63%) create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess12.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess13.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess14.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess15.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess16.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess17.ts diff --git a/src/services/codefixes/fixStrictClassInitialization.ts b/src/services/codefixes/fixStrictClassInitialization.ts index 2f51cedbe8277..8e39f4b565e70 100644 --- a/src/services/codefixes/fixStrictClassInitialization.ts +++ b/src/services/codefixes/fixStrictClassInitialization.ts @@ -75,9 +75,8 @@ namespace ts.codefix { } function addUndefinedType(changeTracker: textChanges.ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration): void { - const undefinedTypeNode = createKeywordTypeNode(SyntaxKind.UndefinedKeyword); - const types = isUnionTypeNode(propertyDeclaration.type) ? propertyDeclaration.type.types.concat(undefinedTypeNode) : [propertyDeclaration.type, undefinedTypeNode]; - changeTracker.replaceNode(propertyDeclarationSourceFile, propertyDeclaration.type, createUnionTypeNode(types)); + const type = mergeTypeNodeToUnion(propertyDeclaration.type, createKeywordTypeNode(SyntaxKind.UndefinedKeyword)); + changeTracker.replaceNode(propertyDeclarationSourceFile, propertyDeclaration.type, type); } function getActionForAddMissingInitializer(context: CodeFixContext, propertyDeclaration: PropertyDeclaration): CodeFixAction | undefined { diff --git a/src/services/refactors/GenerateGetterAndSetter.ts b/src/services/refactors/generateGetAccessorAndSetAccessor.ts similarity index 63% rename from src/services/refactors/GenerateGetterAndSetter.ts rename to src/services/refactors/generateGetAccessorAndSetAccessor.ts index f3aeaeeaaffb9..96ce19809e90b 100644 --- a/src/services/refactors/GenerateGetterAndSetter.ts +++ b/src/services/refactors/generateGetAccessorAndSetAccessor.ts @@ -1,10 +1,20 @@ /* @internal */ -namespace ts.refactor.GenerateGetterAndSetter { +namespace ts.refactor.generateGetAccessorAndSetAccessor { const actionName = "Generate 'get' and 'set' accessors"; const actionDescription = Diagnostics.Generate_get_and_set_accessors.message; - registerRefactor(actionName, { getEditsForAction, getAvailableActions }); + interface Info { + originalName: string; + fieldName: string; + accessorName: string; + accessorType: TypeNode; + propertyDeclaration: PropertyDeclaration; + needUpdateName: boolean; + hasModifiers: boolean; + needUpdateModifiers: boolean; + } + function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined { const { file, startPosition } = context; @@ -34,15 +44,17 @@ namespace ts.refactor.GenerateGetterAndSetter { const changeTracker = textChanges.ChangeTracker.fromContext(context); const newLineCharacter = getNewLineOrDefaultFromHost(context.host, context.formatContext.options); - const { fieldName, accessorName, propertyDeclaration, needUpdateName, hasModifiers, needUpdateModifiers } = fieldInfo; - const accessorModifiers = hasModifiers ? createNodeArray([createToken(SyntaxKind.PublicKeyword)]) : undefined; + const { fieldName, accessorName, accessorType, propertyDeclaration, needUpdateName, hasModifiers, needUpdateModifiers } = fieldInfo; + const accessorModifiers = hasModifiers ? ( + (getModifierFlags(propertyDeclaration) & ModifierFlags.Private || !propertyDeclaration.modifiers) ? createNodeArray([createToken(SyntaxKind.PublicKeyword)]) : propertyDeclaration.modifiers + ) : undefined; - const getAccessor = generateGetAccessor(propertyDeclaration, fieldName, accessorName, accessorModifiers); - const setAccessor = generateSetAccessor(propertyDeclaration, fieldName, accessorName, accessorModifiers); + const getAccessor = generateGetAccessor(fieldName, accessorName, accessorType, accessorModifiers); + const setAccessor = generateSetAccessor(fieldName, accessorName, accessorType, accessorModifiers); - const modifiers = needUpdateModifiers ? createNodeArray([createToken(SyntaxKind.PrivateKeyword)]) : propertyDeclaration.modifiers; + const modifiers = hasModifiers ? createNodeArray([createToken(SyntaxKind.PrivateKeyword)]) : undefined; if (needUpdateName || needUpdateModifiers) { - changeTracker.replaceNode(file, propertyDeclaration, updateOriginPropertyDeclaration(propertyDeclaration, fieldName, modifiers), { + changeTracker.replaceNode(file, propertyDeclaration, updateoriginalPropertyDeclaration(propertyDeclaration, fieldName, modifiers), { suffix: newLineCharacter }); } @@ -57,13 +69,13 @@ namespace ts.refactor.GenerateGetterAndSetter { }; } - interface Info { originName: string; fieldName: string; accessorName: string; propertyDeclaration: PropertyDeclaration; needUpdateName: boolean; hasModifiers: boolean; needUpdateModifiers: boolean; } function getConvertibleFieldAtPosition(file: SourceFile, startPosition: number): Info | undefined { const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); const propertyDeclaration = findAncestor(node.parent, isPropertyDeclaration); - if (!(propertyDeclaration && propertyDeclaration.name.kind === SyntaxKind.Identifier && - (getModifierFlags(propertyDeclaration) | ModifierFlags.AccessibilityModifier) === ModifierFlags.AccessibilityModifier)) return undefined; + if (!propertyDeclaration || propertyDeclaration.name.kind !== SyntaxKind.Identifier) return undefined; + // make sure propertyDeclaration have only AccessibilityModifier + if ((getModifierFlags(propertyDeclaration) | ModifierFlags.AccessibilityModifier) !== ModifierFlags.AccessibilityModifier) return undefined; const containerClass = getContainingClass(propertyDeclaration); if (!containerClass) return undefined; @@ -79,12 +91,14 @@ namespace ts.refactor.GenerateGetterAndSetter { if (find(members, member => needUpdateName ? member.name.getText() === fieldName : member.name.getText() === accessorName)) return undefined; const hasModifiers = !!find(members, member => !!member.modifiers); - const needUpdateModifiers = hasModifiers && (!propertyDeclaration.modifiers || hasModifier(propertyDeclaration, ModifierFlags.Public)); + const needUpdateModifiers = hasModifiers && (!propertyDeclaration.modifiers || !hasModifier(propertyDeclaration, ModifierFlags.Private)); + const accessorType = propertyDeclaration.questionToken ? mergeTypeNodeToUnion(propertyDeclaration.type, createKeywordTypeNode(SyntaxKind.UndefinedKeyword)) : propertyDeclaration.type; return { - originName: propertyDeclaration.name.text, + originalName: propertyDeclaration.name.text, fieldName, accessorName, + accessorType, propertyDeclaration, needUpdateName, hasModifiers, @@ -92,13 +106,13 @@ namespace ts.refactor.GenerateGetterAndSetter { }; } - function generateGetAccessor (propertyDeclaration: PropertyDeclaration, fieldName: string, name: string, modifiers: ModifiersArray) { + function generateGetAccessor (fieldName: string, name: string, type: TypeNode, modifiers: ModifiersArray) { return createGetAccessor( /*decorators*/ undefined, modifiers, name, /*parameters*/ undefined, - propertyDeclaration.type, + type, createBlock([ createReturn( createPropertyAccess( @@ -110,7 +124,7 @@ namespace ts.refactor.GenerateGetterAndSetter { ); } - function generateSetAccessor (propertyDeclaration: PropertyDeclaration, fieldName: string, name: string, modifiers: ModifiersArray) { + function generateSetAccessor (fieldName: string, name: string, type: TypeNode, modifiers: ModifiersArray) { return createSetAccessor( /*decorators*/ undefined, modifiers, @@ -121,7 +135,7 @@ namespace ts.refactor.GenerateGetterAndSetter { /*dotDotDotToken*/ undefined, createIdentifier("value"), /*questionToken*/ undefined, - propertyDeclaration.type + type )], createBlock([ createStatement( @@ -137,15 +151,15 @@ namespace ts.refactor.GenerateGetterAndSetter { ); } - function updateOriginPropertyDeclaration (propertyDeclaration: PropertyDeclaration, fieldName: string, modifiers: ModifiersArray) { + function updateoriginalPropertyDeclaration (propertyDeclaration: PropertyDeclaration, fieldName: string, modifiers: ModifiersArray) { return updateProperty( propertyDeclaration, - /*decorators*/ undefined, + propertyDeclaration.decorators, modifiers, fieldName, - /*questionOrExclamationToken*/ undefined, + propertyDeclaration.questionToken || propertyDeclaration.exclamationToken, propertyDeclaration.type, - propertyDeclaration.initializer, + propertyDeclaration.initializer ); } } diff --git a/src/services/refactors/refactors.ts b/src/services/refactors/refactors.ts index 7f6faf986bcb4..f5ef4da86a47c 100644 --- a/src/services/refactors/refactors.ts +++ b/src/services/refactors/refactors.ts @@ -1,7 +1,2 @@ /// -<<<<<<< HEAD -======= -/// -/// -/// ->>>>>>> add refactor of convert private field to getter and setter +/// diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 0ee06139ea1f9..6e787cf968e36 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -269,6 +269,10 @@ namespace ts { getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node; } + export function mergeTypeNodeToUnion(target: TypeNode, ...types: TypeNode[]) { + return createUnionTypeNode(isUnionTypeNode(target) ? target.types.concat(types) : [target].concat(types)); + } + export function getContainerNode(node: Node): Declaration { if (node.kind === SyntaxKind.JSDocTypedefTag) { // This doesn't just apply to the node immediately under the comment, but to everything in its parent's scope. diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess12.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess12.ts new file mode 100644 index 0000000000000..76afb375de1be --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess12.ts @@ -0,0 +1,23 @@ +/// + +//// class A { +//// @foo +//// /*a*/public a: string = "foo";/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + @foo + private _a: string = "foo"; + public get a(): string { + return this._a; + } + public set a(value: string) { + this._a = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess13.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess13.ts new file mode 100644 index 0000000000000..b374bb1589bbb --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess13.ts @@ -0,0 +1,21 @@ +/// + +//// class A { +//// /*a*/public a?: string = "foo";/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private _a?: string = "foo"; + public get a(): string | undefined { + return this._a; + } + public set a(value: string | undefined) { + this._a = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess14.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess14.ts new file mode 100644 index 0000000000000..39fda7a49f3f1 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess14.ts @@ -0,0 +1,21 @@ +/// + +//// class A { +//// /*a*/public a!: string = "foo";/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private _a!: string = "foo"; + public get a(): string { + return this._a; + } + public set a(value: string) { + this._a = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess15.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess15.ts new file mode 100644 index 0000000000000..3cd29710fa4be --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess15.ts @@ -0,0 +1,16 @@ +/// + +//// class A { +//// /*a*/public "a": string = "foo";/*b*/ +//// /*c*/public get b/*d*/ () { return 1; } +//// /*e*/public set b/*f*/ (v) { } +//// } + +goTo.select("a", "b"); +verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); + +goTo.select("c", "d"); +verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); + +goTo.select("e", "f"); +verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess16.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess16.ts new file mode 100644 index 0000000000000..d1a8e23838429 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess16.ts @@ -0,0 +1,9 @@ +/// + +//// class A { +//// /*a*/public readonly a: string = "foo";/*b*/ +//// /*c*/public static a: string = "foo";/*d*/ +//// } + +goTo.select("a", "b"); +verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess17.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess17.ts new file mode 100644 index 0000000000000..5bbe0b62e785a --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess17.ts @@ -0,0 +1,11 @@ +/// + +//// class A { +//// public _a: number = 1; +//// /*a*/public a: string = "foo";/*b*/ +//// public b: number = 2; +//// /*c*/public _b: string = "foo";/*d*/ +//// } + +goTo.select("a", "b"); +verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess2.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess2.ts index aa8c77313dd97..fe3e06c996d54 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess2.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess2.ts @@ -10,11 +10,11 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - protected _a: string; - public get a(): string { + private _a: string; + protected get a(): string { return this._a; } - public set a(value: string) { + protected set a(value: string) { this._a = value; } }`, diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess5.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess5.ts index 16edc3515d379..19e3f55ad20bb 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess5.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess5.ts @@ -10,11 +10,11 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - protected _a: string; - public get a(): string { + private _a: string; + protected get a(): string { return this._a; } - public set a(value: string) { + protected set a(value: string) { this._a = value; } }`, From 507e804613e4b8f957033c810ba0cfdeebe29aae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Fri, 30 Mar 2018 18:05:54 +0800 Subject: [PATCH 3/9] stash --- src/compiler/utilities.ts | 2 +- .../generateGetAccessorAndSetAccessor.ts | 133 +++++++++--------- ...refactorConvertToGetAccessAndSetAccess1.ts | 6 +- ...efactorConvertToGetAccessAndSetAccess10.ts | 14 +- ...efactorConvertToGetAccessAndSetAccess11.ts | 8 +- ...efactorConvertToGetAccessAndSetAccess12.ts | 27 ++-- ...efactorConvertToGetAccessAndSetAccess13.ts | 12 +- ...efactorConvertToGetAccessAndSetAccess14.ts | 17 +-- ...efactorConvertToGetAccessAndSetAccess15.ts | 46 ++++-- ...efactorConvertToGetAccessAndSetAccess16.ts | 18 ++- ...efactorConvertToGetAccessAndSetAccess17.ts | 11 -- ...refactorConvertToGetAccessAndSetAccess2.ts | 6 +- ...refactorConvertToGetAccessAndSetAccess3.ts | 6 +- ...refactorConvertToGetAccessAndSetAccess4.ts | 10 +- ...refactorConvertToGetAccessAndSetAccess5.ts | 12 +- ...refactorConvertToGetAccessAndSetAccess6.ts | 10 +- ...refactorConvertToGetAccessAndSetAccess7.ts | 12 +- ...refactorConvertToGetAccessAndSetAccess8.ts | 12 +- ...refactorConvertToGetAccessAndSetAccess9.ts | 16 +-- 19 files changed, 194 insertions(+), 184 deletions(-) delete mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess17.ts diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index b85c7dfe3cf1e..71f4e73ff185b 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4238,7 +4238,7 @@ namespace ts { } } - export function isParameterPropertyDeclaration(node: Node): boolean { + export function isParameterPropertyDeclaration(node: Node): node is ParameterDeclaration { return hasModifier(node, ModifierFlags.ParameterPropertyModifier) && node.parent.kind === SyntaxKind.Constructor && isClassLike(node.parent.parent); } diff --git a/src/services/refactors/generateGetAccessorAndSetAccessor.ts b/src/services/refactors/generateGetAccessorAndSetAccessor.ts index 96ce19809e90b..c48e2ae9035eb 100644 --- a/src/services/refactors/generateGetAccessorAndSetAccessor.ts +++ b/src/services/refactors/generateGetAccessorAndSetAccessor.ts @@ -5,14 +5,11 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { registerRefactor(actionName, { getEditsForAction, getAvailableActions }); interface Info { - originalName: string; - fieldName: string; + isStatic?: boolean; + fieldName: Identifier; accessorName: string; - accessorType: TypeNode; - propertyDeclaration: PropertyDeclaration; - needUpdateName: boolean; - hasModifiers: boolean; - needUpdateModifiers: boolean; + classLikeContainer?: ClassLikeDeclaration; + declaration: PropertyDeclaration; } function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined { @@ -21,18 +18,16 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { const fieldInfo = getConvertibleFieldAtPosition(file, startPosition); if (!fieldInfo) return undefined; - return [ - { - name: actionName, - description: actionDescription, - actions: [ - { - name: actionName, - description: actionDescription - } - ] - } - ]; + return [{ + name: actionName, + description: actionDescription, + actions: [ + { + name: actionName, + description: actionDescription + } + ] + }]; } function getEditsForAction(context: RefactorContext, _actionName: string): RefactorEditInfo | undefined { @@ -42,22 +37,21 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { if (!fieldInfo) return undefined; const changeTracker = textChanges.ChangeTracker.fromContext(context); - const newLineCharacter = getNewLineOrDefaultFromHost(context.host, context.formatContext.options); - const { fieldName, accessorName, accessorType, propertyDeclaration, needUpdateName, hasModifiers, needUpdateModifiers } = fieldInfo; - const accessorModifiers = hasModifiers ? ( - (getModifierFlags(propertyDeclaration) & ModifierFlags.Private || !propertyDeclaration.modifiers) ? createNodeArray([createToken(SyntaxKind.PublicKeyword)]) : propertyDeclaration.modifiers - ) : undefined; + const { isStatic, fieldName, accessorName, classLikeContainer, propertyDeclaration } = fieldInfo; + const accessorModifiers = (!propertyDeclaration.modifiers || getModifierFlags(propertyDeclaration) & ModifierFlags.Private) + ? createNodeArray([createToken(SyntaxKind.PublicKeyword)]) + : propertyDeclaration.modifiers; - const getAccessor = generateGetAccessor(fieldName, accessorName, accessorType, accessorModifiers); - const setAccessor = generateSetAccessor(fieldName, accessorName, accessorType, accessorModifiers); + const getAccessor = generateGetAccessor(fieldName, accessorName, accessorModifiers, propertyDeclaration, isStatic, classLikeContainer); + const setAccessor = generateSetAccessor(fieldName, accessorName, accessorModifiers, propertyDeclaration, isStatic, classLikeContainer); - const modifiers = hasModifiers ? createNodeArray([createToken(SyntaxKind.PrivateKeyword)]) : undefined; - if (needUpdateName || needUpdateModifiers) { - changeTracker.replaceNode(file, propertyDeclaration, updateoriginalPropertyDeclaration(propertyDeclaration, fieldName, modifiers), { - suffix: newLineCharacter - }); - } + const fieldModifiers = createNodeArray([createToken(SyntaxKind.PrivateKeyword)]); + if (isStatic) append(fieldModifiers, createToken(SyntaxKind.StaticKeyword)); + + changeTracker.replaceNode(file, propertyDeclaration, updateoriginalPropertyDeclaration(propertyDeclaration, fieldName, fieldModifiers), { + suffix: changeTracker.newLineCharacter + }); changeTracker.insertNodeAfter(file, propertyDeclaration, getAccessor); changeTracker.insertNodeAfter(file, propertyDeclaration, setAccessor); @@ -69,54 +63,61 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { }; } - function getConvertibleFieldAtPosition(file: SourceFile, startPosition: number): Info | undefined { - const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); - const propertyDeclaration = findAncestor(node.parent, isPropertyDeclaration); - + function getPropertyDeclarationInfo(propertyDeclaration: PropertyDeclaration): Info | undefined { if (!propertyDeclaration || propertyDeclaration.name.kind !== SyntaxKind.Identifier) return undefined; - // make sure propertyDeclaration have only AccessibilityModifier - if ((getModifierFlags(propertyDeclaration) | ModifierFlags.AccessibilityModifier) !== ModifierFlags.AccessibilityModifier) return undefined; - - const containerClass = getContainingClass(propertyDeclaration); - if (!containerClass) return undefined; + // make sure propertyDeclaration have AccessibilityModifier or Static Modifier + const meaning = ModifierFlags.AccessibilityModifier | ModifierFlags.Static; + if ((getModifierFlags(propertyDeclaration) | meaning) !== meaning) return undefined; - const members = getMembersOfDeclaration(containerClass); - if (!members) return undefined; + if(!isClassLike(propertyDeclaration.parent) || !propertyDeclaration.parent.members) return undefined; - const needUpdateName = propertyDeclaration.name.text.charCodeAt(0) !== CharacterCodes._; + const accessorName = propertyDeclaration.name.text; - const accessorName = needUpdateName ? propertyDeclaration.name.text : propertyDeclaration.name.text.substring(1); - const fieldName = `_${accessorName}`; + return { + accessorName, + propertyDeclaration, + fieldName: createUniqueName(accessorName), + isStatic: hasStaticModifier(propertyDeclaration), + classLikeContainer: propertyDeclaration.parent + }; + } - if (find(members, member => needUpdateName ? member.name.getText() === fieldName : member.name.getText() === accessorName)) return undefined; + function getParameterPropertyDeclarationInfo(parameterDeclaration: ParameterDeclaration): Info | undefined { + if (!parameterDeclaration || !isIdentifier(parameterDeclaration.name) || (parameterDeclaration.parent.parent).members) return undefined; - const hasModifiers = !!find(members, member => !!member.modifiers); - const needUpdateModifiers = hasModifiers && (!propertyDeclaration.modifiers || !hasModifier(propertyDeclaration, ModifierFlags.Private)); - const accessorType = propertyDeclaration.questionToken ? mergeTypeNodeToUnion(propertyDeclaration.type, createKeywordTypeNode(SyntaxKind.UndefinedKeyword)) : propertyDeclaration.type; + const accessorName = parameterDeclaration.name.text; return { - originalName: propertyDeclaration.name.text, - fieldName, accessorName, - accessorType, propertyDeclaration, - needUpdateName, - hasModifiers, - needUpdateModifiers + fieldName: createUniqueName(accessorName), + isStatic: hasStaticModifier(propertyDeclaration), + classLikeContainer: propertyDeclaration.parent }; + return undefined + } + + function getConvertibleFieldAtPosition(file: SourceFile, startPosition: number): Info | undefined { + const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); + + const declaration = findAncestor(node.parent, or(isParameterPropertyDeclaration, isPropertyDeclaration)); + + if (isPropertyDeclaration(declaration)) return getPropertyDeclarationInfo(declaration); + + return getParameterPropertyDeclarationInfo(declaration); } - function generateGetAccessor (fieldName: string, name: string, type: TypeNode, modifiers: ModifiersArray) { + function generateGetAccessor (fieldName: Identifier, accessorName: string, modifiers: ModifiersArray, propertyDeclaration: PropertyDeclaration, isStatic: boolean, classLikeContainer: ClassLikeDeclaration) { return createGetAccessor( /*decorators*/ undefined, modifiers, - name, + accessorName, /*parameters*/ undefined, - type, + propertyDeclaration.type, createBlock([ createReturn( createPropertyAccess( - createThis(), + isStatic ? classLikeContainer.name : createThis(), fieldName ) ) @@ -124,24 +125,24 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { ); } - function generateSetAccessor (fieldName: string, name: string, type: TypeNode, modifiers: ModifiersArray) { + function generateSetAccessor (fieldName: Identifier, accessorName: string, modifiers: ModifiersArray, propertyDeclaration: PropertyDeclaration, isStatic: boolean, classLikeContainer: ClassLikeDeclaration) { return createSetAccessor( /*decorators*/ undefined, modifiers, - name, + accessorName, [createParameter( /*decorators*/ undefined, - /*modifies*/ undefined, + /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, createIdentifier("value"), /*questionToken*/ undefined, - type + propertyDeclaration.type )], createBlock([ createStatement( createAssignment( createPropertyAccess( - createThis(), + isStatic ? classLikeContainer.name : createThis(), fieldName ), createIdentifier("value") @@ -151,7 +152,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { ); } - function updateoriginalPropertyDeclaration (propertyDeclaration: PropertyDeclaration, fieldName: string, modifiers: ModifiersArray) { + function updateoriginalPropertyDeclaration (propertyDeclaration: PropertyDeclaration, fieldName: Identifier, modifiers: ModifiersArray) { return updateProperty( propertyDeclaration, propertyDeclaration.decorators, diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess1.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess1.ts index 90b6dce8aa10a..c5fd5d6d7e0c4 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess1.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess1.ts @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private _a: string; + private a_1: string; public get a(): string { - return this._a; + return this.a_1; } public set a(value: string) { - this._a = value; + this.a_1 = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess10.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess10.ts index 8fa18e861b480..c21ea7eb97467 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess10.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess10.ts @@ -1,8 +1,7 @@ /// //// class A { -//// public a: string; -//// /*a*/b: number;/*b*/ +//// /*a*/public a?: string = "foo";/*b*/ //// } goTo.select("a", "b"); @@ -11,13 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - public a: string; - private _b: number; - public get b(): number { - return this._b; + private a_1?: string = "foo"; + public get a(): string { + return this.a_1; } - public set b(value: number) { - this._b = value; + public set a(value: string) { + this.a_1 = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess11.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess11.ts index 91e209a5d263f..a1b2b80a20ebd 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess11.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess11.ts @@ -1,7 +1,7 @@ /// //// class A { -//// /*a*/public a: string = "foo";/*b*/ +//// /*a*/public a!: string = "foo";/*b*/ //// } goTo.select("a", "b"); @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private _a: string = "foo"; + private a_1!: string = "foo"; public get a(): string { - return this._a; + return this.a_1; } public set a(value: string) { - this._a = value; + this.a_1 = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess12.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess12.ts index 76afb375de1be..3cd29710fa4be 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess12.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess12.ts @@ -1,23 +1,16 @@ /// //// class A { -//// @foo -//// /*a*/public a: string = "foo";/*b*/ +//// /*a*/public "a": string = "foo";/*b*/ +//// /*c*/public get b/*d*/ () { return 1; } +//// /*e*/public set b/*f*/ (v) { } //// } goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Generate 'get' and 'set' accessors", - actionName: "Generate 'get' and 'set' accessors", - actionDescription: "Generate 'get' and 'set' accessors", - newContent: `class A { - @foo - private _a: string = "foo"; - public get a(): string { - return this._a; - } - public set a(value: string) { - this._a = value; - } -}`, -}); +verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); + +goTo.select("c", "d"); +verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); + +goTo.select("e", "f"); +verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess13.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess13.ts index b374bb1589bbb..18653df403856 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess13.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess13.ts @@ -1,7 +1,7 @@ /// //// class A { -//// /*a*/public a?: string = "foo";/*b*/ +//// /*a*/public static a: string = "foo";/*b*/ //// } goTo.select("a", "b"); @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private _a?: string = "foo"; - public get a(): string | undefined { - return this._a; + private static a_1: string = "foo"; + public static get a(): string { + return A.a_1; } - public set a(value: string | undefined) { - this._a = value; + public static set a(value: string) { + A.a_1 = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess14.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess14.ts index 39fda7a49f3f1..36789b29826ee 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess14.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess14.ts @@ -1,21 +1,8 @@ /// //// class A { -//// /*a*/public a!: string = "foo";/*b*/ +//// /*a*/public readonly a: string = "foo";/*b*/ //// } goTo.select("a", "b"); -edit.applyRefactor({ - refactorName: "Generate 'get' and 'set' accessors", - actionName: "Generate 'get' and 'set' accessors", - actionDescription: "Generate 'get' and 'set' accessors", - newContent: `class A { - private _a!: string = "foo"; - public get a(): string { - return this._a; - } - public set a(value: string) { - this._a = value; - } -}`, -}); +verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess15.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess15.ts index 3cd29710fa4be..4283ecd316de5 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess15.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess15.ts @@ -1,16 +1,46 @@ /// //// class A { -//// /*a*/public "a": string = "foo";/*b*/ -//// /*c*/public get b/*d*/ () { return 1; } -//// /*e*/public set b/*f*/ (v) { } +//// /*a*/public _a: number = 1;/*b*/ +//// /*c*/public a: string = "foo";/*d*/ //// } goTo.select("a", "b"); -verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private _a_1: number = 1; + public get _a(): number { + return this._a_1; + } + public set _a(value: number) { + this._a_1 = value; + } + public a: string = "foo"; +}`, +}); goTo.select("c", "d"); -verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); - -goTo.select("e", "f"); -verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); \ No newline at end of file +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private _a_1: number = 1; + public get _a(): number { + return this._a_1; + } + public set _a(value: number) { + this._a_1 = value; + } + private a_1: string = "foo"; + public get a(): string { + return this.a_1; + } + public set a(value: string) { + this.a_1 = value; + } +}`, +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess16.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess16.ts index d1a8e23838429..f119d7c21c4dd 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess16.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess16.ts @@ -1,9 +1,21 @@ /// //// class A { -//// /*a*/public readonly a: string = "foo";/*b*/ -//// /*c*/public static a: string = "foo";/*d*/ +//// constructor(public /*a*/message/*b*/: string) { } //// } goTo.select("a", "b"); -verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); \ No newline at end of file +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private a_1: string; + public get a(): string { + return this.a_1; + } + public set a(value: string) { + this.a_1 = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess17.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess17.ts deleted file mode 100644 index 5bbe0b62e785a..0000000000000 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess17.ts +++ /dev/null @@ -1,11 +0,0 @@ -/// - -//// class A { -//// public _a: number = 1; -//// /*a*/public a: string = "foo";/*b*/ -//// public b: number = 2; -//// /*c*/public _b: string = "foo";/*d*/ -//// } - -goTo.select("a", "b"); -verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess2.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess2.ts index fe3e06c996d54..79638640ceb84 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess2.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess2.ts @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private _a: string; + private a_1: string; protected get a(): string { - return this._a; + return this.a_1; } protected set a(value: string) { - this._a = value; + this.a_1 = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess3.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess3.ts index 4f26ed33366cf..e3af9967f6a79 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess3.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess3.ts @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private _a: string; + private a_1: string; public get a(): string { - return this._a; + return this.a_1; } public set a(value: string) { - this._a = value; + this.a_1 = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess4.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess4.ts index 1597244e29f4a..08dc42c6fe763 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess4.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess4.ts @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private _a: string; - public get a(): string { - return this._a; + private _a_1: string; + public get _a(): string { + return this._a_1; } - public set a(value: string) { - this._a = value; + public set _a(value: string) { + this._a_1 = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess5.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess5.ts index 19e3f55ad20bb..3f57c6406bb1a 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess5.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess5.ts @@ -1,7 +1,7 @@ /// //// class A { -//// /*a*/protected _a: string;/*b*/ +//// /*a*/_a: string;/*b*/ //// } goTo.select("a", "b"); @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private _a: string; - protected get a(): string { - return this._a; + private _a_1: string; + public get _a(): string { + return this._a_1; } - protected set a(value: string) { - this._a = value; + public set _a(value: string) { + this._a_1 = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess6.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess6.ts index 476a1f851e05b..dca53fbd8c5a7 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess6.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess6.ts @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private _a: string; - public get a(): string { - return this._a; + private _a_1: string; + public get _a(): string { + return this._a_1; } - public set a(value: string) { - this._a = value; + public set _a(value: string) { + this._a_1 = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess7.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess7.ts index e2f2022db8c63..f39c8147eda41 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess7.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess7.ts @@ -1,7 +1,7 @@ /// //// class A { -//// /*a*/_a: string;/*b*/ +//// /*a*/protected _a: string;/*b*/ //// } goTo.select("a", "b"); @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - _a: string; - get a(): string { - return this._a; + private _a_1: string; + protected get _a(): string { + return this._a_1; } - set a(value: string) { - this._a = value; + protected set _a(value: string) { + this._a_1 = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess8.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess8.ts index c6bfda108664c..e681a1e6bd44c 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess8.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess8.ts @@ -1,7 +1,7 @@ /// //// class A { -//// /*a*/a: string;/*b*/ +//// /*a*/public a: string = "foo";/*b*/ //// } goTo.select("a", "b"); @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - _a: string; - get a(): string { - return this._a; + private a_1: string = "foo"; + public get a(): string { + return this.a_1; } - set a(value: string) { - this._a = value; + public set a(value: string) { + this.a_1 = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess9.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess9.ts index be4c47967a570..8f74abc6ef7c7 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess9.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess9.ts @@ -1,8 +1,8 @@ /// //// class A { -//// a: string; -//// /*a*/b: number;/*b*/ +//// @foo +//// /*a*/public a: string = "foo";/*b*/ //// } goTo.select("a", "b"); @@ -11,13 +11,13 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - a: string; - _b: number; - get b(): number { - return this._b; + @foo + private a_1: string = "foo"; + public get a(): string { + return this.a_1; } - set b(value: number) { - this._b = value; + public set a(value: string) { + this.a_1 = value; } }`, }); From 1af3f46d33dc547d9f2a2e9fc0264dd0959386a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Mon, 2 Apr 2018 18:13:33 +0800 Subject: [PATCH 4/9] refactor accessor generate --- .../generateGetAccessorAndSetAccessor.ts | 181 ++++++++++++------ ...refactorConvertToGetAccessAndSetAccess1.ts | 6 +- ...efactorConvertToGetAccessAndSetAccess10.ts | 6 +- ...efactorConvertToGetAccessAndSetAccess11.ts | 6 +- ...efactorConvertToGetAccessAndSetAccess13.ts | 6 +- ...efactorConvertToGetAccessAndSetAccess15.ts | 18 +- ...efactorConvertToGetAccessAndSetAccess16.ts | 9 +- ...efactorConvertToGetAccessAndSetAccess17.ts | 22 +++ ...efactorConvertToGetAccessAndSetAccess18.ts | 22 +++ ...efactorConvertToGetAccessAndSetAccess19.ts | 8 + ...refactorConvertToGetAccessAndSetAccess2.ts | 6 +- ...efactorConvertToGetAccessAndSetAccess20.ts | 23 +++ ...efactorConvertToGetAccessAndSetAccess21.ts | 23 +++ ...efactorConvertToGetAccessAndSetAccess22.ts | 25 +++ ...efactorConvertToGetAccessAndSetAccess23.ts | 46 +++++ ...efactorConvertToGetAccessAndSetAccess24.ts | 27 +++ ...refactorConvertToGetAccessAndSetAccess3.ts | 6 +- ...refactorConvertToGetAccessAndSetAccess4.ts | 6 +- ...refactorConvertToGetAccessAndSetAccess5.ts | 6 +- ...refactorConvertToGetAccessAndSetAccess6.ts | 6 +- ...refactorConvertToGetAccessAndSetAccess7.ts | 6 +- ...refactorConvertToGetAccessAndSetAccess8.ts | 6 +- ...refactorConvertToGetAccessAndSetAccess9.ts | 6 +- 23 files changed, 372 insertions(+), 104 deletions(-) create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess17.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess18.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess19.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess20.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess21.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess22.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess23.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess24.ts diff --git a/src/services/refactors/generateGetAccessorAndSetAccessor.ts b/src/services/refactors/generateGetAccessorAndSetAccessor.ts index c48e2ae9035eb..24151f4aff07a 100644 --- a/src/services/refactors/generateGetAccessorAndSetAccessor.ts +++ b/src/services/refactors/generateGetAccessorAndSetAccessor.ts @@ -4,12 +4,17 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { const actionDescription = Diagnostics.Generate_get_and_set_accessors.message; registerRefactor(actionName, { getEditsForAction, getAvailableActions }); - interface Info { - isStatic?: boolean; - fieldName: Identifier; + type AccepedDeclaration = ParameterDeclaration | PropertyDeclaration; + + interface DeclarationInfo { + classLikeContainer: ClassLikeDeclaration; + isStatic: boolean; + } + + interface Info extends DeclarationInfo { + declaration: AccepedDeclaration; + fieldName: string; accessorName: string; - classLikeContainer?: ClassLikeDeclaration; - declaration: PropertyDeclaration; } function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined { @@ -37,77 +42,114 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { if (!fieldInfo) return undefined; const changeTracker = textChanges.ChangeTracker.fromContext(context); + const { isStatic, fieldName, accessorName, classLikeContainer, declaration } = fieldInfo; - const { isStatic, fieldName, accessorName, classLikeContainer, propertyDeclaration } = fieldInfo; - const accessorModifiers = (!propertyDeclaration.modifiers || getModifierFlags(propertyDeclaration) & ModifierFlags.Private) - ? createNodeArray([createToken(SyntaxKind.PublicKeyword)]) - : propertyDeclaration.modifiers; + const accessorModifiers = getAccessorModifiers(declaration, isStatic); + const fieldModifiers = getFieldModifiers(isStatic); - const getAccessor = generateGetAccessor(fieldName, accessorName, accessorModifiers, propertyDeclaration, isStatic, classLikeContainer); - const setAccessor = generateSetAccessor(fieldName, accessorName, accessorModifiers, propertyDeclaration, isStatic, classLikeContainer); + const getAccessor = generateGetAccessor(fieldName, accessorName, accessorModifiers, declaration, isStatic, classLikeContainer); + const setAccessor = generateSetAccessor(fieldName, accessorName, accessorModifiers, declaration, isStatic, classLikeContainer); - const fieldModifiers = createNodeArray([createToken(SyntaxKind.PrivateKeyword)]); - if (isStatic) append(fieldModifiers, createToken(SyntaxKind.StaticKeyword)); + updateFieldDeclaration(changeTracker, file, declaration, fieldName, fieldModifiers, classLikeContainer); - changeTracker.replaceNode(file, propertyDeclaration, updateoriginalPropertyDeclaration(propertyDeclaration, fieldName, fieldModifiers), { - suffix: changeTracker.newLineCharacter - }); + insertAccessor(changeTracker, file, getAccessor, declaration, classLikeContainer); + insertAccessor(changeTracker, file, setAccessor, declaration, classLikeContainer); - changeTracker.insertNodeAfter(file, propertyDeclaration, getAccessor); - changeTracker.insertNodeAfter(file, propertyDeclaration, setAccessor); + const edits = changeTracker.getChanges(); + const renameFilename = file.fileName; + const renameLocation = getRenameLocation(edits, renameFilename, fieldName, /*isDeclaredBeforeUse*/ false); + return { renameFilename, renameLocation, edits }; + } - return { - edits: changeTracker.getChanges(), - renameFilename: undefined, - renameLocation: undefined, - }; + function getUniqueName(baseName: string, fileText: string): string { + let nameText = baseName; + for (let i = 1; stringContains(fileText, nameText); i++) { + nameText = `${baseName}_${i}`; + } + return nameText; } - function getPropertyDeclarationInfo(propertyDeclaration: PropertyDeclaration): Info | undefined { - if (!propertyDeclaration || propertyDeclaration.name.kind !== SyntaxKind.Identifier) return undefined; - // make sure propertyDeclaration have AccessibilityModifier or Static Modifier - const meaning = ModifierFlags.AccessibilityModifier | ModifierFlags.Static; - if ((getModifierFlags(propertyDeclaration) | meaning) !== meaning) return undefined; + function getRenameLocation(edits: ReadonlyArray, renameFilename: string, fieldName: string, isDeclaredBeforeUse: boolean): number { + let delta = 0; + let lastPos = -1; + for (const { fileName, textChanges } of edits) { + Debug.assert(fileName === renameFilename); + for (const change of textChanges) { + const { span, newText } = change; + const index = newText.indexOf(fieldName); + if (index !== -1) { + lastPos = span.start + delta + index; + + // If the reference comes first, return immediately. + if (!isDeclaredBeforeUse) { + return lastPos; + } + } + delta += newText.length - span.length; + } + } + + // If the declaration comes first, return the position of the last occurrence. + Debug.assert(isDeclaredBeforeUse); + Debug.assert(lastPos >= 0); + return lastPos; + } + + function getAccessorModifiers(declaration: AccepedDeclaration, isStatic: boolean): NodeArray { + if (!declaration.modifiers || getModifierFlags(declaration) & ModifierFlags.Private) { + return createNodeArray( + append([createToken(SyntaxKind.PublicKeyword)], + isStatic ? createToken(SyntaxKind.StaticKeyword) : undefined)); + } + return declaration.modifiers; + } - if(!isClassLike(propertyDeclaration.parent) || !propertyDeclaration.parent.members) return undefined; + function getFieldModifiers(isStatic: boolean): NodeArray { + return createNodeArray( + append([createToken(SyntaxKind.PrivateKeyword)], + isStatic ? createToken(SyntaxKind.StaticKeyword) : undefined)); + } - const accessorName = propertyDeclaration.name.text; + function getPropertyDeclarationInfo(propertyDeclaration: PropertyDeclaration): DeclarationInfo | undefined { + if (!propertyDeclaration || propertyDeclaration.name.kind !== SyntaxKind.Identifier) return undefined; + if (!isClassLike(propertyDeclaration.parent) || !propertyDeclaration.parent.members) return undefined; return { - accessorName, - propertyDeclaration, - fieldName: createUniqueName(accessorName), isStatic: hasStaticModifier(propertyDeclaration), classLikeContainer: propertyDeclaration.parent }; } - function getParameterPropertyDeclarationInfo(parameterDeclaration: ParameterDeclaration): Info | undefined { - if (!parameterDeclaration || !isIdentifier(parameterDeclaration.name) || (parameterDeclaration.parent.parent).members) return undefined; - - const accessorName = parameterDeclaration.name.text; + function getParameterPropertyDeclarationInfo(parameterDeclaration: ParameterDeclaration): DeclarationInfo | undefined { + if (!parameterDeclaration || !isIdentifier(parameterDeclaration.name) || !isClassLike(parameterDeclaration.parent.parent) || !parameterDeclaration.parent.parent.members) return undefined; return { - accessorName, - propertyDeclaration, - fieldName: createUniqueName(accessorName), - isStatic: hasStaticModifier(propertyDeclaration), - classLikeContainer: propertyDeclaration.parent + isStatic: false, + classLikeContainer: parameterDeclaration.parent.parent }; - return undefined } function getConvertibleFieldAtPosition(file: SourceFile, startPosition: number): Info | undefined { const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); - const declaration = findAncestor(node.parent, or(isParameterPropertyDeclaration, isPropertyDeclaration)); + // make sure propertyDeclaration have AccessibilityModifier or Static Modifier + const meaning = ModifierFlags.AccessibilityModifier | ModifierFlags.Static; + if (!declaration || !isIdentifier(declaration.name) || (getModifierFlags(declaration) | meaning) !== meaning) return undefined; + + const accessorName = declaration.name.text; + const fieldName = getUniqueName(`_${accessorName}`, file.text); - if (isPropertyDeclaration(declaration)) return getPropertyDeclarationInfo(declaration); + const info = isPropertyDeclaration(declaration) ? getPropertyDeclarationInfo(declaration) : getParameterPropertyDeclarationInfo(declaration); - return getParameterPropertyDeclarationInfo(declaration); + return { + ...info, + fieldName, + declaration, + accessorName + }; } - function generateGetAccessor (fieldName: Identifier, accessorName: string, modifiers: ModifiersArray, propertyDeclaration: PropertyDeclaration, isStatic: boolean, classLikeContainer: ClassLikeDeclaration) { + function generateGetAccessor(fieldName: string, accessorName: string, modifiers: ModifiersArray, propertyDeclaration: AccepedDeclaration, isStatic: boolean, classLikeContainer: ClassLikeDeclaration) { return createGetAccessor( /*decorators*/ undefined, modifiers, @@ -125,7 +167,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { ); } - function generateSetAccessor (fieldName: Identifier, accessorName: string, modifiers: ModifiersArray, propertyDeclaration: PropertyDeclaration, isStatic: boolean, classLikeContainer: ClassLikeDeclaration) { + function generateSetAccessor(fieldName: string, accessorName: string, modifiers: ModifiersArray, propertyDeclaration: AccepedDeclaration, isStatic: boolean, classLikeContainer: ClassLikeDeclaration) { return createSetAccessor( /*decorators*/ undefined, modifiers, @@ -152,15 +194,44 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { ); } - function updateoriginalPropertyDeclaration (propertyDeclaration: PropertyDeclaration, fieldName: Identifier, modifiers: ModifiersArray) { - return updateProperty( - propertyDeclaration, - propertyDeclaration.decorators, + function updatePropertyDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: PropertyDeclaration, fieldName: string, modifiers: ModifiersArray) { + const property = updateProperty( + declaration, + declaration.decorators, modifiers, fieldName, - propertyDeclaration.questionToken || propertyDeclaration.exclamationToken, - propertyDeclaration.type, - propertyDeclaration.initializer + declaration.questionToken || declaration.exclamationToken, + declaration.type, + declaration.initializer ); + + changeTracker.replaceNode(file, declaration, property, { + suffix: changeTracker.newLineCharacter + }); + } + + function updateParameterPropertyDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: ParameterDeclaration, fieldName: string, modifiers: ModifiersArray, classLikeContainer: ClassLikeDeclaration) { + const property = createProperty( + declaration.decorators, + modifiers, + fieldName, + declaration.questionToken, + declaration.type, + declaration.initializer + ); + + changeTracker.insertNodeAtClassStart(file, classLikeContainer, property); + changeTracker.deleteNodeInList(file, declaration); + } + + + function updateFieldDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: AccepedDeclaration, fieldName: string, modifiers: ModifiersArray, classLikeContainer: ClassLikeDeclaration) { + isPropertyDeclaration(declaration) + ? updatePropertyDeclaration(changeTracker, file, declaration, fieldName, modifiers) + : updateParameterPropertyDeclaration(changeTracker, file, declaration, fieldName, modifiers, classLikeContainer); + } + + function insertAccessor(changeTracker: textChanges.ChangeTracker, file: SourceFile, accessor: AccessorDeclaration, declaration: AccepedDeclaration, classLikeContainer: ClassLikeDeclaration) { + isPropertyDeclaration(declaration) ? changeTracker.insertNodeAfter(file, declaration, accessor) : changeTracker.insertNodeAtClassStart(file, classLikeContainer, accessor); } } diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess1.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess1.ts index c5fd5d6d7e0c4..93b4db47d502b 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess1.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess1.ts @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private a_1: string; + private /*RENAME*/_a: string; public get a(): string { - return this.a_1; + return this._a; } public set a(value: string) { - this.a_1 = value; + this._a = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess10.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess10.ts index c21ea7eb97467..7161dd18d7cfa 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess10.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess10.ts @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private a_1?: string = "foo"; + private /*RENAME*/_a?: string = "foo"; public get a(): string { - return this.a_1; + return this._a; } public set a(value: string) { - this.a_1 = value; + this._a = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess11.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess11.ts index a1b2b80a20ebd..51b5cc35b346a 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess11.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess11.ts @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private a_1!: string = "foo"; + private /*RENAME*/_a!: string = "foo"; public get a(): string { - return this.a_1; + return this._a; } public set a(value: string) { - this.a_1 = value; + this._a = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess13.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess13.ts index 18653df403856..6b66cfb043310 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess13.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess13.ts @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private static a_1: string = "foo"; + private static /*RENAME*/_a: string = "foo"; public static get a(): string { - return A.a_1; + return A._a; } public static set a(value: string) { - A.a_1 = value; + A._a = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess15.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess15.ts index 4283ecd316de5..172842ef27194 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess15.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess15.ts @@ -11,12 +11,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private _a_1: number = 1; + private /*RENAME*/__a: number = 1; public get _a(): number { - return this._a_1; + return this.__a; } public set _a(value: number) { - this._a_1 = value; + this.__a = value; } public a: string = "foo"; }`, @@ -28,19 +28,19 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private _a_1: number = 1; + private __a: number = 1; public get _a(): number { - return this._a_1; + return this.__a; } public set _a(value: number) { - this._a_1 = value; + this.__a = value; } - private a_1: string = "foo"; + private /*RENAME*/_a_1: string = "foo"; public get a(): string { - return this.a_1; + return this._a_1; } public set a(value: string) { - this.a_1 = value; + this._a_1 = value; } }`, }); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess16.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess16.ts index f119d7c21c4dd..dd2cc4cf848dd 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess16.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess16.ts @@ -1,7 +1,7 @@ /// //// class A { -//// constructor(public /*a*/message/*b*/: string) { } +//// constructor(public /*a*/a/*b*/: string) { } //// } goTo.select("a", "b"); @@ -10,12 +10,13 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private a_1: string; + private /*RENAME*/_a: string; public get a(): string { - return this.a_1; + return this._a; } public set a(value: string) { - this.a_1 = value; + this._a = value; } + constructor() { } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess17.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess17.ts new file mode 100644 index 0000000000000..ee212b63502a2 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess17.ts @@ -0,0 +1,22 @@ +/// + +//// class A { +//// constructor(protected /*a*/a/*b*/: string) { } +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private /*RENAME*/_a: string; + protected get a(): string { + return this._a; + } + protected set a(value: string) { + this._a = value; + } + constructor() { } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess18.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess18.ts new file mode 100644 index 0000000000000..37676a8a047d0 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess18.ts @@ -0,0 +1,22 @@ +/// + +//// class A { +//// constructor(private /*a*/a/*b*/: string) { } +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private /*RENAME*/_a: string; + public get a(): string { + return this._a; + } + public set a(value: string) { + this._a = value; + } + constructor() { } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess19.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess19.ts new file mode 100644 index 0000000000000..76779b4595098 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess19.ts @@ -0,0 +1,8 @@ +/// + +//// class A { +//// constructor(/*a*/a/*b*/: string) { } +//// } + +goTo.select("a", "b"); +verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess2.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess2.ts index 79638640ceb84..3776b347240c7 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess2.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess2.ts @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private a_1: string; + private /*RENAME*/_a: string; protected get a(): string { - return this.a_1; + return this._a; } protected set a(value: string) { - this.a_1 = value; + this._a = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess20.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess20.ts new file mode 100644 index 0000000000000..221fd54504c25 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess20.ts @@ -0,0 +1,23 @@ +/// + +//// class A { +//// public a_1: number; +//// /*a*/public a: string;/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + public a_1: number; + private /*RENAME*/_a: string; + public get a(): string { + return this._a; + } + public set a(value: string) { + this._a = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess21.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess21.ts new file mode 100644 index 0000000000000..ecd570783b8c2 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess21.ts @@ -0,0 +1,23 @@ +/// + +//// class A { +//// public a_2: number; +//// /*a*/public a_1: string;/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + public a_2: number; + private /*RENAME*/_a_1: string; + public get a_1(): string { + return this._a_1; + } + public set a_1(value: string) { + this._a_1 = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess22.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess22.ts new file mode 100644 index 0000000000000..0c6cd0f984492 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess22.ts @@ -0,0 +1,25 @@ +/// + +//// class A { +//// public a_1: number; +//// constructor(public /*a*/a/*b*/: string) { } +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private /*RENAME*/_a: string; + public get a(): string { + return this._a; + } + public set a(value: string) { + this._a = value; + } + public a_1: number; + constructor() { } +}`, +}); + diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess23.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess23.ts new file mode 100644 index 0000000000000..6be970539877b --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess23.ts @@ -0,0 +1,46 @@ +/// + +//// class A { +//// /*a*/public _a: number = 1;/*b*/ +//// /*c*/public a: string = "foo";/*d*/ +//// } + +goTo.select("c", "d"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + public _a: number = 1; + private /*RENAME*/_a_1: string = "foo"; + public get a(): string { + return this._a_1; + } + public set a(value: string) { + this._a_1 = value; + } +}`, +}); + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private /*RENAME*/__a: number = 1; + public get _a(): number { + return this.__a; + } + public set _a(value: number) { + this.__a = value; + } + private _a_1: string = "foo"; + public get a(): string { + return this._a_1; + } + public set a(value: string) { + this._a_1 = value; + } +}`, +}); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess24.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess24.ts new file mode 100644 index 0000000000000..3cb8f65cb35c9 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess24.ts @@ -0,0 +1,27 @@ +/// + +//// class A { +//// /*a*/public a: number = 1;/*b*/ +//// public _a: string = "foo"; +//// public _a_1: string = "bar"; +//// public _a_2: string = "baz"; +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private /*RENAME*/_a_3: number = 1; + public get a(): number { + return this._a_3; + } + public set a(value: number) { + this._a_3 = value; + } + public _a: string = "foo"; + public _a_1: string = "bar"; + public _a_2: string = "baz"; +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess3.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess3.ts index e3af9967f6a79..4ff6877270dd4 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess3.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess3.ts @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private a_1: string; + private /*RENAME*/_a: string; public get a(): string { - return this.a_1; + return this._a; } public set a(value: string) { - this.a_1 = value; + this._a = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess4.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess4.ts index 08dc42c6fe763..2b6ccbeaa1a61 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess4.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess4.ts @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private _a_1: string; + private /*RENAME*/__a: string; public get _a(): string { - return this._a_1; + return this.__a; } public set _a(value: string) { - this._a_1 = value; + this.__a = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess5.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess5.ts index 3f57c6406bb1a..6299cc0142946 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess5.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess5.ts @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private _a_1: string; + private /*RENAME*/__a: string; public get _a(): string { - return this._a_1; + return this.__a; } public set _a(value: string) { - this._a_1 = value; + this.__a = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess6.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess6.ts index dca53fbd8c5a7..5f713df203cdb 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess6.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess6.ts @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private _a_1: string; + private /*RENAME*/__a: string; public get _a(): string { - return this._a_1; + return this.__a; } public set _a(value: string) { - this._a_1 = value; + this.__a = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess7.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess7.ts index f39c8147eda41..4fc5641d65726 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess7.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess7.ts @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private _a_1: string; + private /*RENAME*/__a: string; protected get _a(): string { - return this._a_1; + return this.__a; } protected set _a(value: string) { - this._a_1 = value; + this.__a = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess8.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess8.ts index e681a1e6bd44c..cfbcd9fd76251 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess8.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess8.ts @@ -10,12 +10,12 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { - private a_1: string = "foo"; + private /*RENAME*/_a: string = "foo"; public get a(): string { - return this.a_1; + return this._a; } public set a(value: string) { - this.a_1 = value; + this._a = value; } }`, }); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess9.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess9.ts index 8f74abc6ef7c7..a5a402b99c06e 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess9.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess9.ts @@ -12,12 +12,12 @@ edit.applyRefactor({ actionDescription: "Generate 'get' and 'set' accessors", newContent: `class A { @foo - private a_1: string = "foo"; + private /*RENAME*/_a: string = "foo"; public get a(): string { - return this.a_1; + return this._a; } public set a(value: string) { - this.a_1 = value; + this._a = value; } }`, }); From f60e7b2c16629441d270a97b0869384620a1be9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Mon, 2 Apr 2018 18:32:00 +0800 Subject: [PATCH 5/9] revert merge union type --- src/services/codefixes/fixStrictClassInitialization.ts | 5 +++-- .../refactors/generateGetAccessorAndSetAccessor.ts | 8 ++------ src/services/utilities.ts | 4 ---- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/services/codefixes/fixStrictClassInitialization.ts b/src/services/codefixes/fixStrictClassInitialization.ts index 8e39f4b565e70..2f51cedbe8277 100644 --- a/src/services/codefixes/fixStrictClassInitialization.ts +++ b/src/services/codefixes/fixStrictClassInitialization.ts @@ -75,8 +75,9 @@ namespace ts.codefix { } function addUndefinedType(changeTracker: textChanges.ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration): void { - const type = mergeTypeNodeToUnion(propertyDeclaration.type, createKeywordTypeNode(SyntaxKind.UndefinedKeyword)); - changeTracker.replaceNode(propertyDeclarationSourceFile, propertyDeclaration.type, type); + const undefinedTypeNode = createKeywordTypeNode(SyntaxKind.UndefinedKeyword); + const types = isUnionTypeNode(propertyDeclaration.type) ? propertyDeclaration.type.types.concat(undefinedTypeNode) : [propertyDeclaration.type, undefinedTypeNode]; + changeTracker.replaceNode(propertyDeclarationSourceFile, propertyDeclaration.type, createUnionTypeNode(types)); } function getActionForAddMissingInitializer(context: CodeFixContext, propertyDeclaration: PropertyDeclaration): CodeFixAction | undefined { diff --git a/src/services/refactors/generateGetAccessorAndSetAccessor.ts b/src/services/refactors/generateGetAccessorAndSetAccessor.ts index 24151f4aff07a..ef7a29af00dc5 100644 --- a/src/services/refactors/generateGetAccessorAndSetAccessor.ts +++ b/src/services/refactors/generateGetAccessorAndSetAccessor.ts @@ -19,9 +19,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined { const { file, startPosition } = context; - - const fieldInfo = getConvertibleFieldAtPosition(file, startPosition); - if (!fieldInfo) return undefined; + if (!getConvertibleFieldAtPosition(file, startPosition)) return undefined; return [{ name: actionName, @@ -205,9 +203,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { declaration.initializer ); - changeTracker.replaceNode(file, declaration, property, { - suffix: changeTracker.newLineCharacter - }); + changeTracker.replaceNode(file, declaration, property); } function updateParameterPropertyDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: ParameterDeclaration, fieldName: string, modifiers: ModifiersArray, classLikeContainer: ClassLikeDeclaration) { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 6e787cf968e36..0ee06139ea1f9 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -269,10 +269,6 @@ namespace ts { getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node; } - export function mergeTypeNodeToUnion(target: TypeNode, ...types: TypeNode[]) { - return createUnionTypeNode(isUnionTypeNode(target) ? target.types.concat(types) : [target].concat(types)); - } - export function getContainerNode(node: Node): Declaration { if (node.kind === SyntaxKind.JSDocTypedefTag) { // This doesn't just apply to the node immediately under the comment, but to everything in its parent's scope. From 56d48348ad033d094d691252fe516b5e3db2c0a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Tue, 3 Apr 2018 09:52:32 +0800 Subject: [PATCH 6/9] refeactor and accept baseline --- src/services/refactors/extractSymbol.ts | 39 ---------------- .../generateGetAccessorAndSetAccessor.ts | 45 ++----------------- src/services/utilities.ts | 41 +++++++++++++++++ .../reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- 5 files changed, 46 insertions(+), 83 deletions(-) diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 7144265d11a5f..f74d03f779d4b 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -701,14 +701,6 @@ namespace ts.refactor.extractSymbol { Global, } - function getUniqueName(baseName: string, fileText: string): string { - let nameText = baseName; - for (let i = 1; stringContains(fileText, nameText); i++) { - nameText = `${baseName}_${i}`; - } - return nameText; - } - /** * Result of 'extractRange' operation for a specific scope. * Stores either a list of changes that should be applied to extract a range or a list of errors @@ -1129,37 +1121,6 @@ namespace ts.refactor.extractSymbol { } } - /** - * @return The index of the (only) reference to the extracted symbol. We want the cursor - * to be on the reference, rather than the declaration, because it's closer to where the - * user was before extracting it. - */ - function getRenameLocation(edits: ReadonlyArray, renameFilename: string, functionNameText: string, isDeclaredBeforeUse: boolean): number { - let delta = 0; - let lastPos = -1; - for (const { fileName, textChanges } of edits) { - Debug.assert(fileName === renameFilename); - for (const change of textChanges) { - const { span, newText } = change; - const index = newText.indexOf(functionNameText); - if (index !== -1) { - lastPos = span.start + delta + index; - - // If the reference comes first, return immediately. - if (!isDeclaredBeforeUse) { - return lastPos; - } - } - delta += newText.length - span.length; - } - } - - // If the declaration comes first, return the position of the last occurrence. - Debug.assert(isDeclaredBeforeUse); - Debug.assert(lastPos >= 0); - return lastPos; - } - function getFirstDeclaration(type: Type): Declaration | undefined { let firstDeclaration; diff --git a/src/services/refactors/generateGetAccessorAndSetAccessor.ts b/src/services/refactors/generateGetAccessorAndSetAccessor.ts index ef7a29af00dc5..882b239cd9411 100644 --- a/src/services/refactors/generateGetAccessorAndSetAccessor.ts +++ b/src/services/refactors/generateGetAccessorAndSetAccessor.ts @@ -59,40 +59,6 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { return { renameFilename, renameLocation, edits }; } - function getUniqueName(baseName: string, fileText: string): string { - let nameText = baseName; - for (let i = 1; stringContains(fileText, nameText); i++) { - nameText = `${baseName}_${i}`; - } - return nameText; - } - - function getRenameLocation(edits: ReadonlyArray, renameFilename: string, fieldName: string, isDeclaredBeforeUse: boolean): number { - let delta = 0; - let lastPos = -1; - for (const { fileName, textChanges } of edits) { - Debug.assert(fileName === renameFilename); - for (const change of textChanges) { - const { span, newText } = change; - const index = newText.indexOf(fieldName); - if (index !== -1) { - lastPos = span.start + delta + index; - - // If the reference comes first, return immediately. - if (!isDeclaredBeforeUse) { - return lastPos; - } - } - delta += newText.length - span.length; - } - } - - // If the declaration comes first, return the position of the last occurrence. - Debug.assert(isDeclaredBeforeUse); - Debug.assert(lastPos >= 0); - return lastPos; - } - function getAccessorModifiers(declaration: AccepedDeclaration, isStatic: boolean): NodeArray { if (!declaration.modifiers || getModifierFlags(declaration) & ModifierFlags.Private) { return createNodeArray( @@ -109,7 +75,6 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { } function getPropertyDeclarationInfo(propertyDeclaration: PropertyDeclaration): DeclarationInfo | undefined { - if (!propertyDeclaration || propertyDeclaration.name.kind !== SyntaxKind.Identifier) return undefined; if (!isClassLike(propertyDeclaration.parent) || !propertyDeclaration.parent.members) return undefined; return { @@ -119,7 +84,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { } function getParameterPropertyDeclarationInfo(parameterDeclaration: ParameterDeclaration): DeclarationInfo | undefined { - if (!parameterDeclaration || !isIdentifier(parameterDeclaration.name) || !isClassLike(parameterDeclaration.parent.parent) || !parameterDeclaration.parent.parent.members) return undefined; + if (!isClassLike(parameterDeclaration.parent.parent) || !parameterDeclaration.parent.parent.members) return undefined; return { isStatic: false, @@ -134,16 +99,12 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { const meaning = ModifierFlags.AccessibilityModifier | ModifierFlags.Static; if (!declaration || !isIdentifier(declaration.name) || (getModifierFlags(declaration) | meaning) !== meaning) return undefined; - const accessorName = declaration.name.text; - const fieldName = getUniqueName(`_${accessorName}`, file.text); - const info = isPropertyDeclaration(declaration) ? getPropertyDeclarationInfo(declaration) : getParameterPropertyDeclarationInfo(declaration); - return { ...info, - fieldName, declaration, - accessorName + fieldName: getUniqueName(`_${(declaration.name).text}`, file.text), + accessorName: (declaration.name).text }; } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 0ee06139ea1f9..a573d4d7c7865 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1519,4 +1519,45 @@ namespace ts { function getFirstChild(node: Node): Node | undefined { return node.forEachChild(child => child); } + + /* @internal */ + export function getUniqueName(baseName: string, fileText: string): string { + let nameText = baseName; + for (let i = 1; stringContains(fileText, nameText); i++) { + nameText = `${baseName}_${i}`; + } + return nameText; + } + + /** + * @return The index of the (only) reference to the extracted symbol. We want the cursor + * to be on the reference, rather than the declaration, because it's closer to where the + * user was before extracting it. + */ + /* @internal */ + export function getRenameLocation(edits: ReadonlyArray, renameFilename: string, name: string, isDeclaredBeforeUse: boolean): number { + let delta = 0; + let lastPos = -1; + for (const { fileName, textChanges } of edits) { + Debug.assert(fileName === renameFilename); + for (const change of textChanges) { + const { span, newText } = change; + const index = newText.indexOf(name); + if (index !== -1) { + lastPos = span.start + delta + index; + + // If the reference comes first, return immediately. + if (!isDeclaredBeforeUse) { + return lastPos; + } + } + delta += newText.length - span.length; + } + } + + // If the declaration comes first, return the position of the last occurrence. + Debug.assert(isDeclaredBeforeUse); + Debug.assert(lastPos >= 0); + return lastPos; + } } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index a8d31ef8fe913..03ea7110c524d 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2940,7 +2940,7 @@ declare namespace ts { */ function collapseTextChangeRangesAcrossMultipleVersions(changes: ReadonlyArray): TextChangeRange; function getTypeParameterOwner(d: Declaration): Declaration; - function isParameterPropertyDeclaration(node: Node): boolean; + function isParameterPropertyDeclaration(node: Node): node is ParameterDeclaration; function isEmptyBindingPattern(node: BindingName): node is BindingPattern; function isEmptyBindingElement(node: BindingElement): boolean; function getCombinedModifierFlags(node: Node): ModifierFlags; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 76dbc06058bce..9f507099c14a7 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2995,7 +2995,7 @@ declare namespace ts { */ function collapseTextChangeRangesAcrossMultipleVersions(changes: ReadonlyArray): TextChangeRange; function getTypeParameterOwner(d: Declaration): Declaration; - function isParameterPropertyDeclaration(node: Node): boolean; + function isParameterPropertyDeclaration(node: Node): node is ParameterDeclaration; function isEmptyBindingPattern(node: BindingName): node is BindingPattern; function isEmptyBindingElement(node: BindingElement): boolean; function getCombinedModifierFlags(node: Node): ModifierFlags; From e5daa8c46ea5b0ed3619c95ffd27f97893ccb87b Mon Sep 17 00:00:00 2001 From: kingwl Date: Sat, 7 Apr 2018 18:46:46 +0800 Subject: [PATCH 7/9] add support of PropertyAssignment and StringLiteral --- package-lock.json | 783 ++++++++---------- src/compiler/core.ts | 4 +- .../generateGetAccessorAndSetAccessor.ts | 121 ++- src/services/textChanges.ts | 9 + ...efactorConvertToGetAccessAndSetAccess12.ts | 10 +- ...efactorConvertToGetAccessAndSetAccess25.ts | 21 + ...efactorConvertToGetAccessAndSetAccess26.ts | 23 + ...efactorConvertToGetAccessAndSetAccess27.ts | 21 + ...efactorConvertToGetAccessAndSetAccess28.ts | 21 + ...efactorConvertToGetAccessAndSetAccess29.ts | 21 + 10 files changed, 576 insertions(+), 458 deletions(-) create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess25.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess26.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess27.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess28.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess29.ts diff --git a/package-lock.json b/package-lock.json index 990d3fbcb5a4b..2e1c6f6207e61 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,33 +1,16 @@ { "name": "typescript", - "version": "2.8.0", + "version": "2.9.0", "lockfileVersion": 1, "requires": true, "dependencies": { - "@browserify/acorn5-object-spread": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@browserify/acorn5-object-spread/-/acorn5-object-spread-5.0.1.tgz", - "integrity": "sha512-sFCUPzgeEjdq3rinwy4TFXtak2YZdhqpj6MdNusxkdTFr9TXAUEYK4YQSamR8Joqt/yii1drgl5hk8q/AtJDKA==", - "dev": true, - "requires": { - "acorn": "5.3.0" - }, - "dependencies": { - "acorn": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", - "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", - "dev": true - } - } - }, "@gulp-sourcemaps/identity-map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.1.tgz", "integrity": "sha1-z6I7xYQPkQTOMqZedNt+epdLvuE=", "dev": true, "requires": { - "acorn": "5.3.0", + "acorn": "5.5.3", "css": "2.2.1", "normalize-path": "2.1.1", "source-map": "0.5.7", @@ -35,9 +18,9 @@ }, "dependencies": { "acorn": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", - "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", + "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", "dev": true } } @@ -55,7 +38,7 @@ "@types/browserify": { "version": "12.0.33", "resolved": "https://registry.npmjs.org/@types/browserify/-/browserify-12.0.33.tgz", - "integrity": "sha512-mY6dYfq1Ns3Xqz/JFUcyoWaXtm0XDoNhkU1vCwM/ULM5zqNL+SbtacJhce/JCgPeCdbqdVqq77tJ4HwdtypSxg==", + "integrity": "sha1-5hlxwPmFvx93CQSDJkk/ELDdeL0=", "dev": true, "requires": { "@types/insert-module-globals": "7.0.0", @@ -71,22 +54,22 @@ "@types/convert-source-map": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/@types/convert-source-map/-/convert-source-map-1.5.1.tgz", - "integrity": "sha512-laiDIXqqthjJlyAMYAXOtN3N8+UlbM+KvZi4BaY5ZOekmVkBs/UxfK5O0HWeJVG2eW8F+Mu2ww13fTX+kY1FlQ==", + "integrity": "sha1-1NGA3WrcXLaK2ZvVbgPWN4gfRhY=", "dev": true }, "@types/del": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/del/-/del-3.0.0.tgz", - "integrity": "sha512-18mSs54BvzV8+TTQxt0ancig6tsuPZySnhp3cQkWFFDmDMavU4pmWwR+bHHqRBWODYqpzIzVkqKLuk/fP6yypQ==", + "integrity": "sha1-HIzYtuONo7VyNSyo6vVSeTFCYog=", "dev": true, "requires": { "@types/glob": "5.0.35" } }, "@types/events": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-1.1.0.tgz", - "integrity": "sha512-y3bR98mzYOo0pAZuiLari+cQyiKk3UXRuT45h1RjhfeCzqkjaVsfZJNaxdgtk7/3tzOm1ozLTqEqMP3VbI48jw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", + "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==", "dev": true }, "@types/glob": { @@ -95,7 +78,7 @@ "integrity": "sha512-wc+VveszMLyMWFvXLkloixT4n0harUIVZjnpzztaZ0nKLuul7Z32iMt2fUFGAaZ4y1XWjFRMtCI5ewvyh4aIeg==", "dev": true, "requires": { - "@types/events": "1.1.0", + "@types/events": "1.2.0", "@types/minimatch": "3.0.3", "@types/node": "8.5.5" } @@ -103,7 +86,7 @@ "@types/gulp": { "version": "3.8.36", "resolved": "https://registry.npmjs.org/@types/gulp/-/gulp-3.8.36.tgz", - "integrity": "sha512-u6/zWPzYRNPAtvyFJ3/RSXjmBaBM1dVs5kW22/jU6J786ZGLfSndhLoNOpFI6FGQvqTA+QzFHjSMhpkAN+wxcQ==", + "integrity": "sha1-Eer1g78FNGabT/qb/tUVV/qgCkw=", "dev": true, "requires": { "@types/node": "8.5.5", @@ -114,7 +97,7 @@ "@types/gulp-concat": { "version": "0.0.32", "resolved": "https://registry.npmjs.org/@types/gulp-concat/-/gulp-concat-0.0.32.tgz", - "integrity": "sha512-CUCFADlITzzBfBa2bdGzhKtvBr4eFh+evb+4igVbvPoO5RyPfHifmyQlZl6lM7q19+OKncRlFXDU7B4X9Ayo2g==", + "integrity": "sha1-ckhgKLHPX6qUyMHPNMYmUxzsrNY=", "dev": true, "requires": { "@types/node": "8.5.5" @@ -123,7 +106,7 @@ "@types/gulp-help": { "version": "0.0.34", "resolved": "https://registry.npmjs.org/@types/gulp-help/-/gulp-help-0.0.34.tgz", - "integrity": "sha512-MkW7psZznxxJg2MBk2P2qHE+T8jEZVFz3FG/qGjUYazkyJt7hBJWx5Nuewmay5RVNtUvSWPrdZLr/WTXY3T/6A==", + "integrity": "sha1-Dm1mcYySiWZPLtdaIaDmXXqIM+w=", "dev": true, "requires": { "@types/gulp": "3.8.36", @@ -134,7 +117,7 @@ "@types/gulp-newer": { "version": "0.0.31", "resolved": "https://registry.npmjs.org/@types/gulp-newer/-/gulp-newer-0.0.31.tgz", - "integrity": "sha512-e7J/Zv5Wd7CC0WpuA2syWVitgwrkG0u221e41w7r07XUR6hMH6kHPkq9tUrusHkbeW8QbuLbis5fODOwQCyggQ==", + "integrity": "sha1-818j0eT+DXuP9pnknRwhdmy546c=", "dev": true, "requires": { "@types/node": "8.5.5" @@ -143,7 +126,7 @@ "@types/gulp-sourcemaps": { "version": "0.0.32", "resolved": "https://registry.npmjs.org/@types/gulp-sourcemaps/-/gulp-sourcemaps-0.0.32.tgz", - "integrity": "sha512-+7BAmptW2bxyJnJcCEuie7vLoop3FwWgCdBMzyv7MYXED/HeNMeQuX7uPCkp4vfU1TTu4CYFH0IckNPvo0VePA==", + "integrity": "sha1-557mF+DLFXKYdL5FM/5ZwHeToXU=", "dev": true, "requires": { "@types/node": "8.5.5" @@ -152,7 +135,7 @@ "@types/insert-module-globals": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@types/insert-module-globals/-/insert-module-globals-7.0.0.tgz", - "integrity": "sha512-zudCJPwluh1VUDB6Gl/OQdRp+fYy3+47huJB/JMQubMS2p+sH18MCVK4WUz3FqaWLB12yh5ELxVR/+tqwlm/qA==", + "integrity": "sha1-jRWN5KY4To2qE7PWPuurbV9nd30=", "dev": true, "requires": { "@types/node": "8.5.5" @@ -161,7 +144,7 @@ "@types/merge2": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@types/merge2/-/merge2-1.1.4.tgz", - "integrity": "sha512-GjaXY4OultxbaOOk7lCLO7xvEcFpdjExC605YmfI6X29vhHKpJfMWKCDZd3x+BITrZaXKg97DgV/SdGVSwdzxA==", + "integrity": "sha1-CmUOHMIVove4BALqtraiNuYC96M=", "dev": true, "requires": { "@types/node": "8.5.5" @@ -182,7 +165,7 @@ "@types/mkdirp": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz", - "integrity": "sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg==", + "integrity": "sha1-UDqs/lzCcD1UhDJrGyfvpnoznB8=", "dev": true, "requires": { "@types/node": "8.5.5" @@ -197,29 +180,29 @@ "@types/node": { "version": "8.5.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-8.5.5.tgz", - "integrity": "sha512-JRnfoh0Ll4ElmIXKxbUfcOodkGvcNHljct6mO1X9hE/mlrMzAx0hYCLAD7sgT53YAY1HdlpzUcV0CkmDqUqTuA==", + "integrity": "sha1-b56BZK4aVam+sdJXHPt6z51yDGE=", "dev": true }, "@types/orchestrator": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@types/orchestrator/-/orchestrator-0.3.2.tgz", - "integrity": "sha512-cKB4yTX0wGaRCSkdHDX2fkGQbMAA8UOshC2U7DQky1CE5o+5q2iQQ8VkbPbE/88uaTtsusvBPMcCX7dgmjxBhQ==", + "integrity": "sha1-zRXGzql4oyuY5QVCOcvMeOVWcfE=", "dev": true, "requires": { "@types/node": "8.5.5", - "@types/q": "1.0.7" + "@types/q": "1.5.0" } }, "@types/q": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.0.7.tgz", - "integrity": "sha512-0WS7XU7sXzQ7J1nbnMKKYdjrrFoO3YtZYgUzeV8JFXffPnHfvSJQleR70I8BOAsOm14i4dyaAZ3YzqIl1YhkXQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.0.tgz", + "integrity": "sha512-sWj7AMiG0fYmta6ug1ublLjtj/tqn+CnCZeo7yswR1ykxel0FOWFGdWviTcGSNAMmtLbycDqbg6w98VPFKJmbw==", "dev": true }, "@types/run-sequence": { "version": "0.0.30", "resolved": "https://registry.npmjs.org/@types/run-sequence/-/run-sequence-0.0.30.tgz", - "integrity": "sha512-XwGr1b4yCGUILKeBkzmeWcxmGHQ0vFFFpA6D6y1yLO6gKmYorF+PHqdU5KG+nWt38OvtrkDptmrSmlHX/XtpLw==", + "integrity": "sha1-s6kMn9KaXu3lgTXdAl6zrEu7Vg4=", "dev": true, "requires": { "@types/gulp": "3.8.36", @@ -238,7 +221,7 @@ "@types/vinyl": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.2.tgz", - "integrity": "sha512-2iYpNuOl98SrLPBZfEN9Mh2JCJ2EI9HU35SfgBEb51DcmaHkhp8cKMblYeBqMQiwXMgAD3W60DbQ4i/UdLiXhw==", + "integrity": "sha1-TzuNro9YKNOADvcJsM/0iO6FLeM=", "dev": true, "requires": { "@types/node": "8.5.5" @@ -247,7 +230,7 @@ "@types/xml2js": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.2.tgz", - "integrity": "sha512-8aKUBSj3oGcnuiBmDLm3BIk09RYg01mz9HlQ2u4aS17oJ25DxjQrEUVGFSBVNOfM45pQW4OjcBPplq6r/exJdA==", + "integrity": "sha1-pLhLOHn/1HEJU/2Syr/emopOhFY=", "dev": true, "requires": { "@types/node": "8.5.5" @@ -275,6 +258,24 @@ "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", "dev": true }, + "acorn-node": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.3.0.tgz", + "integrity": "sha512-efP54n3d1aLfjL2UMdaXa6DsswwzJeI5rqhbFvXMrKiJ6eJFpf+7R0zN7t8IC+XKn2YOAFAv6xbBNgHUkoHWLw==", + "dev": true, + "requires": { + "acorn": "5.5.3", + "xtend": "4.0.1" + }, + "dependencies": { + "acorn": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", + "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", + "dev": true + } + } + }, "align-text": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", @@ -345,6 +346,15 @@ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, "ansi-wrap": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", @@ -384,7 +394,7 @@ "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=", "dev": true }, "arr-union": { @@ -426,7 +436,7 @@ "array-slice": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "integrity": "sha1-42jqFfibxwaff/uJrsOmx9SsItQ=", "dev": true }, "array-union": { @@ -457,9 +467,9 @@ "dev": true }, "asn1.js": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.2.tgz", - "integrity": "sha512-b/OsSjvWEo8Pi8H0zsDd2P6Uqo2TK2pH8gNLSJtNLM2Db0v2QaAZ0pBQJXVjAn4gBuugeVDr7s63ZogpUIwWDg==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, "requires": { "bn.js": "4.11.8", @@ -556,7 +566,7 @@ "base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=", "dev": true, "requires": { "cache-base": "1.0.1", @@ -569,9 +579,9 @@ } }, "base64-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", - "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz", + "integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w==", "dev": true }, "beeper": { @@ -599,7 +609,7 @@ "braces": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.0.tgz", - "integrity": "sha512-P4O8UQRdGiMLWSizsApmXVQDBS6KCt7dSexgLKBmH5Hr1CZq7vsnscFh8oR1sP1ab1Zj0uCHCEzZeV6SfUf3rA==", + "integrity": "sha1-pGlBy1+0khVrPWplbgbDU2Tj5m4=", "dev": true, "requires": { "arr-flatten": "1.1.0", @@ -622,16 +632,17 @@ "dev": true }, "browser-pack": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.0.2.tgz", - "integrity": "sha1-+GzWzvT1MAyOY+B6TVEvZfv/RTE=", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", + "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", "dev": true, "requires": { "JSONStream": "1.3.2", - "combine-source-map": "0.7.2", + "combine-source-map": "0.8.0", "defined": "1.0.0", + "safe-buffer": "5.1.1", "through2": "2.0.3", - "umd": "3.0.1" + "umd": "3.0.3" } }, "browser-resolve": { @@ -643,6 +654,12 @@ "resolve": "1.1.7" } }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, "browserify": { "version": "16.1.1", "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.1.1.tgz", @@ -651,10 +668,10 @@ "requires": { "JSONStream": "1.3.2", "assert": "1.4.1", - "browser-pack": "6.0.2", + "browser-pack": "6.1.0", "browser-resolve": "1.11.2", "browserify-zlib": "0.2.0", - "buffer": "5.0.8", + "buffer": "5.1.0", "cached-path-relative": "1.0.1", "concat-stream": "1.6.2", "console-browserify": "1.1.0", @@ -670,10 +687,10 @@ "htmlescape": "1.1.1", "https-browserify": "1.0.0", "inherits": "2.0.3", - "insert-module-globals": "7.0.1", - "labeled-stream-splicer": "2.0.0", + "insert-module-globals": "7.0.6", + "labeled-stream-splicer": "2.0.1", "mkdirp": "0.5.1", - "module-deps": "6.0.0", + "module-deps": "6.0.2", "os-browserify": "0.3.0", "parents": "1.0.1", "path-browserify": "0.0.0", @@ -686,10 +703,10 @@ "shasum": "1.0.2", "shell-quote": "1.6.1", "stream-browserify": "2.0.1", - "stream-http": "2.7.2", + "stream-http": "2.8.1", "string_decoder": "1.0.3", "subarg": "1.0.0", - "syntax-error": "1.3.0", + "syntax-error": "1.4.0", "through2": "2.0.3", "timers-browserify": "1.4.2", "tty-browserify": "0.0.1", @@ -697,78 +714,12 @@ "util": "0.10.3", "vm-browserify": "0.0.4", "xtend": "4.0.1" - }, - "dependencies": { - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "1.0.0", - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "typedarray": "0.0.6" - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "events": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-2.0.0.tgz", - "integrity": "sha512-r/M5YkNg9zwI8QbSf7tsDWWJvO3PGwZXyG7GpFAxtMASnHL2eblFd7iHiGPtyGKKFPZ59S63NeX10Ws6WqGDcg==", - "dev": true - }, - "module-deps": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.0.0.tgz", - "integrity": "sha512-BKsMhJJENEM4dTgqq2MDTTHXRHcNUFegoAwlG4HO4VMdUyMcJDKgfgI+MOv6tR5Iv8G3MKZFgsSiyP3ZoosRMw==", - "dev": true, - "requires": { - "JSONStream": "1.3.2", - "browser-resolve": "1.11.2", - "cached-path-relative": "1.0.1", - "concat-stream": "1.6.2", - "defined": "1.0.0", - "detective": "5.0.2", - "duplexer2": "0.1.4", - "inherits": "2.0.3", - "parents": "1.0.1", - "readable-stream": "2.3.3", - "resolve": "1.6.0", - "stream-combiner2": "1.1.1", - "subarg": "1.0.0", - "through2": "2.0.3", - "xtend": "4.0.1" - }, - "dependencies": { - "resolve": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.6.0.tgz", - "integrity": "sha512-mw7JQNu5ExIkcw4LPih0owX/TZXjD/ZUF/ZQ/pDnkw3ZKhDcZZw5klmBlj6gVMwjQ3Pz5Jgu7F3d0jcDVuEWdw==", - "dev": true, - "requires": { - "path-parse": "1.0.5" - } - } - } - }, - "tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "dev": true - } } }, "browserify-aes": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", - "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { "buffer-xor": "1.0.3", @@ -785,7 +736,7 @@ "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", "dev": true, "requires": { - "browserify-aes": "1.1.1", + "browserify-aes": "1.2.0", "browserify-des": "1.0.0", "evp_bytestokey": "1.0.3" } @@ -808,7 +759,7 @@ "dev": true, "requires": { "bn.js": "4.11.8", - "randombytes": "2.0.5" + "randombytes": "2.0.6" } }, "browserify-sign": { @@ -836,13 +787,13 @@ } }, "buffer": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.0.8.tgz", - "integrity": "sha512-xXvjQhVNz50v2nPeoOsNqWCLGfiv4ji/gXZM28jnVwdLJxH4mFyqgqCKfaK9zf1KUbG6zTkjLOy7ou+jSMarGA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.1.0.tgz", + "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==", "dev": true, "requires": { - "base64-js": "1.2.1", - "ieee754": "1.1.8" + "base64-js": "1.2.3", + "ieee754": "1.1.11" } }, "buffer-crc32": { @@ -884,7 +835,7 @@ "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "integrity": "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI=", "dev": true, "requires": { "collection-visit": "1.0.0", @@ -954,32 +905,6 @@ "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", "supports-color": "5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "1.9.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", - "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } - } } }, "check-error": { @@ -1063,7 +988,7 @@ "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", "dev": true, "requires": { "is-accessor-descriptor": "0.1.6", @@ -1074,7 +999,7 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", "dev": true } } @@ -1157,13 +1082,13 @@ "color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "integrity": "sha1-k4NDeaHMmgxh+C9S8NBDIiUb1aI=", "dev": true }, "combine-source-map": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz", - "integrity": "sha1-CHAxKFazB6h8xKxIbzqaYq7MwJ4=", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", "dev": true, "requires": { "convert-source-map": "1.1.3", @@ -1199,36 +1124,15 @@ "dev": true }, "concat-stream": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", - "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { + "buffer-from": "1.0.0", "inherits": "2.0.3", - "readable-stream": "2.0.6", + "readable-stream": "2.3.3", "typedarray": "0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "0.10.31", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } } }, "concat-with-sourcemaps": { @@ -1292,7 +1196,7 @@ "cipher-base": "1.0.4", "inherits": "2.0.3", "ripemd160": "2.0.1", - "sha.js": "2.4.9" + "sha.js": "2.4.11" } }, "create-hmac": { @@ -1306,7 +1210,7 @@ "inherits": "2.0.3", "ripemd160": "2.0.1", "safe-buffer": "5.1.1", - "sha.js": "2.4.9" + "sha.js": "2.4.11" } }, "crypto-browserify": { @@ -1324,8 +1228,8 @@ "inherits": "2.0.3", "pbkdf2": "3.0.14", "public-encrypt": "4.0.0", - "randombytes": "2.0.5", - "randomfill": "1.0.3" + "randombytes": "2.0.6", + "randomfill": "1.0.4" } }, "css": { @@ -1381,7 +1285,7 @@ "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "dev": true, "requires": { - "es5-ext": "0.10.37" + "es5-ext": "0.10.42" } }, "date-now": { @@ -1399,20 +1303,20 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" } }, "debug-fabulous": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.0.0.tgz", - "integrity": "sha512-dsd50qQ1atDeurcxL7XOjPp4nZCGZzWIONDujDXzl1atSyC3hMbZD+v6440etw+Vt0Pr8ce4TQzHfX3KZM05Mw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz", + "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==", "dev": true, "requires": { "debug": "3.1.0", - "memoizee": "0.4.11", + "memoizee": "0.4.12", "object-assign": "4.1.1" }, "dependencies": { @@ -1443,7 +1347,7 @@ "deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "integrity": "sha1-38lARACtHI/gI+faHfHBR8S0RN8=", "dev": true, "requires": { "type-detect": "4.0.5" @@ -1544,28 +1448,20 @@ "dev": true }, "detective": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/detective/-/detective-5.0.2.tgz", - "integrity": "sha512-NUsLoezj4wb9o7vpxS9F3L5vcO87ceyRBcl48op06YFNwkyIEY997JpSCA5lDlDuDc6JxOtaL5qfK3muoWxpMA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.1.0.tgz", + "integrity": "sha512-TFHMqfOvxlgrfVzTEkNBSh9SvSNX/HfF4OFI2QFGCyPm02EsyILqnUeb5P6q7JZ3SFNTBL5t2sePRgrN4epUWQ==", "dev": true, "requires": { - "@browserify/acorn5-object-spread": "5.0.1", - "acorn": "5.3.0", - "defined": "1.0.0" - }, - "dependencies": { - "acorn": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", - "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", - "dev": true - } + "acorn-node": "1.3.0", + "defined": "1.0.0", + "minimist": "1.2.0" } }, "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, "diffie-hellman": { @@ -1576,9 +1472,15 @@ "requires": { "bn.js": "4.11.8", "miller-rabin": "4.0.1", - "randombytes": "2.0.5" + "randombytes": "2.0.6" } }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, "duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", @@ -1588,6 +1490,29 @@ "readable-stream": "2.3.3" } }, + "duplexify": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.4.tgz", + "integrity": "sha512-JzYSLYMhoVVBe8+mbHQ4KgpvHpm0DZpJuL8PY93Vyv1fW7jYJ90LoXa1di/CVbJM+TgMs91rbDapE/RNIfnJsA==", + "dev": true, + "requires": { + "end-of-stream": "1.4.1", + "inherits": "2.0.3", + "readable-stream": "2.3.3", + "stream-shift": "1.0.0" + }, + "dependencies": { + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "1.4.0" + } + } + } + }, "elliptic": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", @@ -1624,13 +1549,14 @@ } }, "es5-ext": { - "version": "0.10.37", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.37.tgz", - "integrity": "sha1-DudB0Ui4AGm6J9AgOTdWryV978M=", + "version": "0.10.42", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.42.tgz", + "integrity": "sha512-AJxO1rmPe1bDEfSR6TJ/FgMFYuTBhR5R57KW58iCkYACMyFbrkqVyzXSurYoScDGvgyMpk7uRF/lPUPPTmsRSA==", "dev": true, "requires": { "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1" + "es6-symbol": "3.1.1", + "next-tick": "1.0.0" } }, "es6-iterator": { @@ -1640,7 +1566,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.37", + "es5-ext": "0.10.42", "es6-symbol": "3.1.1" } }, @@ -1657,7 +1583,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.37" + "es5-ext": "0.10.42" } }, "es6-weak-map": { @@ -1667,7 +1593,7 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.37", + "es5-ext": "0.10.42", "es6-iterator": "2.0.3", "es6-symbol": "3.1.1" } @@ -1728,9 +1654,15 @@ "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.37" + "es5-ext": "0.10.42" } }, + "events": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-2.0.0.tgz", + "integrity": "sha512-r/M5YkNg9zwI8QbSf7tsDWWJvO3PGwZXyG7GpFAxtMASnHL2eblFd7iHiGPtyGKKFPZ59S63NeX10Ws6WqGDcg==", + "dev": true + }, "evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", @@ -1808,7 +1740,7 @@ "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", "dev": true, "requires": { "is-accessor-descriptor": "0.1.6", @@ -1819,7 +1751,7 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", "dev": true } } @@ -1851,7 +1783,7 @@ "extglob": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.3.tgz", - "integrity": "sha512-AyptZexgu7qppEPq59DtN/XJGZDrLcVxSHai+4hdgMMS9EpF4GBvygcWWApno8lL9qSjVpYt7Raao28qzJX1ww==", + "integrity": "sha1-VeAZ0Mlb+HOUnHN7flFy26hOuyk=", "dev": true, "requires": { "array-unique": "0.3.2", @@ -2048,7 +1980,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "1.0.0", @@ -2161,7 +2093,7 @@ "global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "integrity": "sha1-bXcPDrUjrHgWTXK15xqIdyZcw+o=", "dev": true, "requires": { "global-prefix": "1.0.2", @@ -2443,7 +2375,7 @@ "acorn": "5.5.3", "convert-source-map": "1.5.1", "css": "2.2.1", - "debug-fabulous": "1.0.0", + "debug-fabulous": "1.1.0", "detect-newline": "2.1.0", "graceful-fs": "4.1.11", "source-map": "0.6.1", @@ -2472,9 +2404,9 @@ } }, "gulp-typescript": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-4.0.1.tgz", - "integrity": "sha512-BGdaBC1R4SJosXEkkEieeZ21qCZHnfSV78k7zzDljqAxvzDeGRTUqF4geckVclKEeiS3EYOBwNlxoHjJtn20vg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-4.0.2.tgz", + "integrity": "sha512-Hhbn5Aa2l3T+tnn0KqsG6RRJmcYEsr3byTL2nBpNBeAK8pqug9Od4AwddU4JEI+hRw7mzZyjRbB8DDWR6paGVA==", "dev": true, "requires": { "ansi-colors": "1.1.0", @@ -2509,12 +2441,6 @@ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", "dev": true }, - "is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", - "dev": true - }, "json-stable-stringify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", @@ -2539,16 +2465,6 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", - "dev": true, - "requires": { - "is-absolute": "1.0.0", - "is-negated-glob": "1.0.0" - } - }, "unique-stream": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", @@ -2713,9 +2629,9 @@ "dev": true }, "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "has-gulplog": { @@ -2823,9 +2739,9 @@ "dev": true }, "ieee754": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", - "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.11.tgz", + "integrity": "sha512-VhDzCKN7K8ufStx/CLj5/PDTMgph+qwN5Pkd5i0sGnVwk56zJ0lkT8Qzi1xqWLS0Wp29DgDtNeS7v8/wMoZeHg==", "dev": true }, "indexof": { @@ -2853,7 +2769,7 @@ "ini": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "integrity": "sha1-7uJfVtscnsYIXgwid4CD9Zar+Sc=", "dev": true }, "inline-source-map": { @@ -2866,16 +2782,17 @@ } }, "insert-module-globals": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.1.tgz", - "integrity": "sha1-wDv04BywhtW15azorQr+eInWOMM=", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.6.tgz", + "integrity": "sha512-R3sidKJr3SsggqQQ5cEwQb3pWG8RNx0UnpyeiOSR6jorRIeAOzH2gkTWnNdMnyRiVbjrG047K7UCtlMkQ1Mo9w==", "dev": true, "requires": { "JSONStream": "1.3.2", - "combine-source-map": "0.7.2", - "concat-stream": "1.5.2", + "combine-source-map": "0.8.0", + "concat-stream": "1.6.2", "is-buffer": "1.1.6", "lexical-scope": "1.2.0", + "path-is-absolute": "1.0.1", "process": "0.11.10", "through2": "2.0.3", "xtend": "4.0.1" @@ -2890,7 +2807,7 @@ "is-absolute": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "integrity": "sha1-OV4a6EsR8mrReV5zwXN45IowFXY=", "dev": true, "requires": { "is-relative": "1.0.0", @@ -2900,7 +2817,7 @@ "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { "kind-of": "6.0.2" @@ -2909,13 +2826,13 @@ "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=", "dev": true }, "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { "kind-of": "6.0.2" @@ -2924,7 +2841,7 @@ "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { "is-accessor-descriptor": "1.0.0", @@ -3015,7 +2932,7 @@ "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=", "dev": true, "requires": { "isobject": "3.0.1" @@ -3030,7 +2947,7 @@ "is-relative": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "integrity": "sha1-obtpNc6MXboei5dUubLcwCDiJg0=", "dev": true, "requires": { "is-unc-path": "1.0.0" @@ -3039,7 +2956,7 @@ "is-unc-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "integrity": "sha1-1zHoiY7QkKEsNSrS6u1Qla0yLJ0=", "dev": true, "requires": { "unc-path-regex": "0.1.2" @@ -3051,6 +2968,12 @@ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, + "is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", + "dev": true + }, "is-windows": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.1.tgz", @@ -3180,7 +3103,7 @@ "js-yaml": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", - "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "integrity": "sha1-LnhEFka9RoLpY/IrbpKCPDCcYtw=", "dev": true, "requires": { "argparse": "1.0.9", @@ -3190,7 +3113,7 @@ "esprima": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "integrity": "sha1-RJnt3NERDgshi6zy+n9/WfVcqAQ=", "dev": true } } @@ -3225,24 +3148,24 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", "dev": true }, "labeled-stream-splicer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz", - "integrity": "sha1-pS4dE4AkwAuGscDJH2d5GLiuClk=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", + "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", "dev": true, "requires": { "inherits": "2.0.3", - "isarray": "0.0.1", + "isarray": "2.0.4", "stream-splicer": "2.0.0" }, "dependencies": { "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", + "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", "dev": true } } @@ -3458,13 +3381,13 @@ "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", "dev": true, "requires": { - "es5-ext": "0.10.37" + "es5-ext": "0.10.42" } }, "make-error": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.2.tgz", - "integrity": "sha512-l9ra35l5VWLF24y75Tg8XgfGLX0ueRhph118WKM6H5denx4bB5QF59+4UAm9oJ2qsPQZas/CQUDdtDdfvYHBdQ==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz", + "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==", "dev": true }, "make-iterator": { @@ -3525,19 +3448,19 @@ } }, "memoizee": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.11.tgz", - "integrity": "sha1-vemBdmPJ5A/bKk6hw2cpYIeujI8=", + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.12.tgz", + "integrity": "sha512-sprBu6nwxBWBvBOh5v2jcsGqiGLlL2xr2dLub3vR8dnE8YB17omwtm/0NSHl8jjNbcsJd5GMWJAnTSVe/O0Wfg==", "dev": true, "requires": { "d": "1.0.0", - "es5-ext": "0.10.37", + "es5-ext": "0.10.42", "es6-weak-map": "2.0.2", "event-emitter": "0.3.5", "is-promise": "2.1.0", "lru-queue": "0.1.0", "next-tick": "1.0.0", - "timers-ext": "0.1.2" + "timers-ext": "0.1.5" } }, "merge2": { @@ -3592,7 +3515,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { "brace-expansion": "1.1.8" @@ -3607,7 +3530,7 @@ "mixin-deep": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.0.tgz", - "integrity": "sha512-dgaCvoh6i1nosAUBKb0l0pfJ78K8+S9fluyIR2YvAeUD/QuMahnFnF3xYty5eYXMjhGSsB0DsW6A0uAZyetoAg==", + "integrity": "sha1-R6hzK6l3mUV8jB7KKPlRMtfoFQo=", "dev": true, "requires": { "for-in": "1.0.2", @@ -3617,7 +3540,7 @@ "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", "dev": true, "requires": { "is-plain-object": "2.0.4" @@ -3643,9 +3566,9 @@ } }, "mocha": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.4.tgz", - "integrity": "sha512-nMOpAPFosU1B4Ix1jdhx5e3q7XO55ic5a8cgYvW27CequcEY+BabS0kUVL1Cw1V5PuVHZWeNRWFLmEPexo79VA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.5.tgz", + "integrity": "sha512-3MM3UjZ5p8EJrYpG7s+29HAI9G7sTzKEe4+w37Dg0QP7qL4XGsV+Q2xet2cE37AqdgN1OtYQB6Vl98YiPV3PgA==", "dev": true, "requires": { "browser-stdout": "1.3.1", @@ -3660,12 +3583,6 @@ "supports-color": "4.4.0" }, "dependencies": { - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", @@ -3675,10 +3592,10 @@ "ms": "2.0.0" } }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, "supports-color": { @@ -3698,6 +3615,40 @@ "integrity": "sha1-zK/w4ckc9Vf+d+B535lUuRt0d1Y=", "dev": true }, + "module-deps": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.0.2.tgz", + "integrity": "sha512-KWBI3009iRnHjRlxRhe8nJ6kdeBTg4sMi5N6AZgg5f1/v5S7EBCRBOY854I4P5Anl4kx6AJH+4bBBC2Gi3nkvg==", + "dev": true, + "requires": { + "JSONStream": "1.3.2", + "browser-resolve": "1.11.2", + "cached-path-relative": "1.0.1", + "concat-stream": "1.6.2", + "defined": "1.0.0", + "detective": "5.1.0", + "duplexer2": "0.1.4", + "inherits": "2.0.3", + "parents": "1.0.1", + "readable-stream": "2.3.3", + "resolve": "1.6.0", + "stream-combiner2": "1.1.1", + "subarg": "1.0.0", + "through2": "2.0.3", + "xtend": "4.0.1" + }, + "dependencies": { + "resolve": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.6.0.tgz", + "integrity": "sha512-mw7JQNu5ExIkcw4LPih0owX/TZXjD/ZUF/ZQ/pDnkw3ZKhDcZZw5klmBlj6gVMwjQ3Pz5Jgu7F3d0jcDVuEWdw==", + "dev": true, + "requires": { + "path-parse": "1.0.5" + } + } + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -3778,7 +3729,7 @@ "natives": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.1.tgz", - "integrity": "sha512-8eRaxn8u/4wN8tGkhlc2cgwwvOLMLUMUn4IYTexMgWd+LyUDfeXVkk2ygQR0hvIHbJQXgHujia3ieUUDwNGkEA==", + "integrity": "sha1-ARrM4ffL2H97prMJPWzZOSvhxXQ=", "dev": true }, "next-tick": { @@ -3861,7 +3812,7 @@ "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", "dev": true, "requires": { "is-accessor-descriptor": "0.1.6", @@ -3872,7 +3823,7 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", "dev": true } } @@ -4025,7 +3976,7 @@ "p-map": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", - "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "integrity": "sha1-5OlPMR6rvIYzoeeZCBZfyiYkG2s=", "dev": true }, "pako": { @@ -4049,8 +4000,8 @@ "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", "dev": true, "requires": { - "asn1.js": "4.9.2", - "browserify-aes": "1.1.1", + "asn1.js": "4.10.1", + "browserify-aes": "1.2.0", "create-hash": "1.1.3", "evp_bytestokey": "1.0.3", "pbkdf2": "3.0.14" @@ -4146,7 +4097,7 @@ "create-hmac": "1.1.6", "ripemd160": "2.0.1", "safe-buffer": "5.1.1", - "sha.js": "2.4.9" + "sha.js": "2.4.11" } }, "pify": { @@ -4262,7 +4213,7 @@ "browserify-rsa": "4.0.1", "create-hash": "1.1.3", "parse-asn1": "5.1.0", - "randombytes": "2.0.5" + "randombytes": "2.0.6" } }, "pump": { @@ -4295,29 +4246,6 @@ "duplexify": "3.5.4", "inherits": "2.0.3", "pump": "2.0.1" - }, - "dependencies": { - "duplexify": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.4.tgz", - "integrity": "sha512-JzYSLYMhoVVBe8+mbHQ4KgpvHpm0DZpJuL8PY93Vyv1fW7jYJ90LoXa1di/CVbJM+TgMs91rbDapE/RNIfnJsA==", - "dev": true, - "requires": { - "end-of-stream": "1.4.1", - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "stream-shift": "1.0.0" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, - "requires": { - "once": "1.4.0" - } - } } }, "punycode": { @@ -4345,21 +4273,21 @@ "dev": true }, "randombytes": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz", - "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", "dev": true, "requires": { "safe-buffer": "5.1.1" } }, "randomfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.3.tgz", - "integrity": "sha512-YL6GrhrWoic0Eq8rXVbMptH7dAxCs0J+mh5Y0euNekPPYaxEmdVGim6GdoxoRzKW2yJoU8tueifS7mYxvcFDEQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "dev": true, "requires": { - "randombytes": "2.0.5", + "randombytes": "2.0.6", "safe-buffer": "5.1.1" } }, @@ -4375,7 +4303,7 @@ "readable-stream": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "integrity": "sha1-No8lEtefnUb9/HE0mueHi7weuVw=", "dev": true, "requires": { "core-util-is": "1.0.2", @@ -4494,7 +4422,7 @@ "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=", "dev": true, "requires": { "glob": "7.1.2" @@ -4513,7 +4441,7 @@ "run-sequence": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/run-sequence/-/run-sequence-2.2.1.tgz", - "integrity": "sha512-qkzZnQWMZjcKbh3CNly2srtrkaO/2H/SI5f2eliMCapdRD3UhMrwjfOAZJAnZ2H8Ju4aBzFZkBGXUqFs9V0yxw==", + "integrity": "sha1-HOZD2jb9jH6n4akynaM/wriJhJU=", "dev": true, "requires": { "chalk": "1.1.3", @@ -4551,7 +4479,7 @@ "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=", "dev": true }, "sander": { @@ -4577,7 +4505,7 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=", "dev": true }, "semver": { @@ -4604,7 +4532,7 @@ "set-value": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "integrity": "sha1-ca5KiPD+77v1LR6mBPP7MV67YnQ=", "dev": true, "requires": { "extend-shallow": "2.0.1", @@ -4614,9 +4542,9 @@ } }, "sha.js": { - "version": "2.4.9", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz", - "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==", + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { "inherits": "2.0.3", @@ -4630,7 +4558,7 @@ "dev": true, "requires": { "json-stable-stringify": "0.0.1", - "sha.js": "2.4.9" + "sha.js": "2.4.11" } }, "shell-quote": { @@ -4719,7 +4647,7 @@ "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", "dev": true, "requires": { "is-accessor-descriptor": "0.1.6", @@ -4730,7 +4658,7 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", "dev": true } } @@ -4738,7 +4666,7 @@ "snapdragon-node": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "integrity": "sha1-bBdfhv8UvbByRWPo88GwIaKGhTs=", "dev": true, "requires": { "define-property": "1.0.0", @@ -4749,7 +4677,7 @@ "snapdragon-util": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "integrity": "sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI=", "dev": true, "requires": { "kind-of": "3.2.2" @@ -4787,7 +4715,7 @@ "source-map-resolve": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz", - "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==", + "integrity": "sha1-etD1k/IoFZjoVN+A8ZquS5LXoRo=", "dev": true, "requires": { "atob": "2.0.3", @@ -4838,7 +4766,7 @@ "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "integrity": "sha1-fLCd2jqGWFcFxks5pkZgOGguj+I=", "dev": true, "requires": { "extend-shallow": "3.0.2" @@ -4857,7 +4785,7 @@ "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", "dev": true, "requires": { "is-plain-object": "2.0.4" @@ -4933,7 +4861,7 @@ "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", "dev": true, "requires": { "is-accessor-descriptor": "0.1.6", @@ -4944,7 +4872,7 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", "dev": true } } @@ -4976,9 +4904,9 @@ "dev": true }, "stream-http": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz", - "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.1.tgz", + "integrity": "sha512-cQ0jo17BLca2r0GfRdZKYAGLU6JRoIWxqSOakUMuKOT6MOK7AAlE856L33QuDmAy/eeOrhLee3dZKX0Uadu93A==", "dev": true, "requires": { "builtin-status-codes": "3.0.0", @@ -5042,7 +4970,7 @@ "string_decoder": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", "dev": true, "requires": { "safe-buffer": "5.1.1" @@ -5082,13 +5010,22 @@ "minimist": "1.2.0" } }, + "supports-color": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", + "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + }, "syntax-error": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.3.0.tgz", - "integrity": "sha1-HtkmbE1AvnXcVb+bsct3Biu5bKE=", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", + "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", "dev": true, "requires": { - "acorn": "4.0.13" + "acorn-node": "1.3.0" } }, "through": { @@ -5142,15 +5079,25 @@ } }, "timers-ext": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.2.tgz", - "integrity": "sha1-YcxHp2wavTGV8UUn+XjViulMUgQ=", + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.5.tgz", + "integrity": "sha512-tsEStd7kmACHENhsUPaxb8Jf8/+GZZxyNFQbZD07HQOyooOa6At1rQqjffgvg7n+dxscQa9cjjMdWhJtsP2sxg==", "dev": true, "requires": { - "es5-ext": "0.10.37", + "es5-ext": "0.10.42", "next-tick": "1.0.0" } }, + "to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", + "dev": true, + "requires": { + "is-absolute": "1.0.0", + "is-negated-glob": "1.0.0" + } + }, "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", @@ -5240,7 +5187,7 @@ "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", "dev": true, "requires": { "is-accessor-descriptor": "0.1.6", @@ -5251,7 +5198,7 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", "dev": true } } @@ -5289,8 +5236,8 @@ "requires": { "arrify": "1.0.1", "chalk": "2.3.2", - "diff": "3.3.1", - "make-error": "1.3.2", + "diff": "3.5.0", + "make-error": "1.3.4", "minimist": "1.2.0", "mkdirp": "0.5.1", "source-map-support": "0.5.4", @@ -5298,9 +5245,9 @@ } }, "tslib": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.8.1.tgz", - "integrity": "sha1-aUavLR1lGnsYY7Ux1uWvpBqkTqw=", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz", + "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==", "dev": true }, "tslint": { @@ -5313,14 +5260,14 @@ "builtin-modules": "1.1.1", "chalk": "2.3.2", "commander": "2.15.1", - "diff": "3.3.1", + "diff": "3.5.0", "glob": "7.1.2", "js-yaml": "3.10.0", "minimatch": "3.0.4", "resolve": "1.6.0", "semver": "5.5.0", - "tslib": "1.8.1", - "tsutils": "2.16.0" + "tslib": "1.9.0", + "tsutils": "2.26.1" }, "dependencies": { "commander": { @@ -5347,14 +5294,20 @@ } }, "tsutils": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.16.0.tgz", - "integrity": "sha512-9Ier/60O7OZRNPiw+or5QAtAY4kQA+WDiO/r6xOYATEyefH9bdfvTRLCxrYnFhQlZfET2vYXKfpr3Vw2BiArZw==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.26.1.tgz", + "integrity": "sha512-bnm9bcjOqOr1UljleL94wVCDlpa6KjfGaTkefeLch4GRafgDkROxPizbB/FxTEdI++5JqhxczRy/Qub0syNqZA==", "dev": true, "requires": { - "tslib": "1.8.1" + "tslib": "1.9.0" } }, + "tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "dev": true + }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -5367,7 +5320,7 @@ "type-detect": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.5.tgz", - "integrity": "sha512-N9IvkQslUGYGC24RkJk1ba99foK6TkwC2FHAEBlQFBP0RxQZS8ZpJuAZcwiY/w9ZJHFQb1aOXBI60OdxhTrwEQ==", + "integrity": "sha1-1w5byB223io4G8rKDG4MvcdjXeI=", "dev": true }, "typedarray": { @@ -5377,9 +5330,9 @@ "dev": true }, "typescript": { - "version": "2.8.0-dev.20180322", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.8.0-dev.20180322.tgz", - "integrity": "sha512-dSYa9IAoj3CRAxtKx9+cSCQLetB7OLtHXhvQWeWY6PPIXvbpAC41ulQWX3TUAkMYU9NS/kGIU8TFM9VFpinJTg==", + "version": "2.9.0-dev.20180407", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.0-dev.20180407.tgz", + "integrity": "sha512-Tg0/hU2hSz+4pb5Lj5+bj1uLldN7C8NO5Ik19WfftMlpeXRyZQJzglV0oncmsXOfN9gG+JC0xnO58YspE6sZ1w==", "dev": true }, "uglify-js": { @@ -5402,9 +5355,9 @@ "optional": true }, "umd": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.1.tgz", - "integrity": "sha1-iuVW4RAR9jwllnCKiDclnwGz1g4=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", + "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", "dev": true }, "unc-path-regex": { @@ -5572,7 +5525,7 @@ "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", "dev": true, "requires": { "is-accessor-descriptor": "0.1.6", @@ -5583,7 +5536,7 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", "dev": true } } @@ -5766,7 +5719,7 @@ "vlq": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", - "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", + "integrity": "sha1-jz5DKM9jsVQMDWfhsneDhviXWyY=", "dev": true }, "vm-browserify": { @@ -5781,7 +5734,7 @@ "which": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "integrity": "sha1-/wS9/AEO5UfXgL7DjhrBwnd9JTo=", "dev": true, "requires": { "isexe": "2.0.0" @@ -5809,7 +5762,7 @@ "xml2js": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", - "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "integrity": "sha1-aGwg8hMgnpSr8NG88e+qKRx4J6c=", "dev": true, "requires": { "sax": "1.2.4", diff --git a/src/compiler/core.ts b/src/compiler/core.ts index ae7e8de2ae12c..b1e618d252acc 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -3118,8 +3118,8 @@ namespace ts { return (arg: T) => f(arg) && g(arg); } - export function or(f: (arg: T) => boolean, g: (arg: T) => boolean) { - return (arg: T) => f(arg) || g(arg); + export function or(f: (arg: T) => boolean, g: (arg: T) => boolean, ...others: ((arg: T) => boolean)[]) { + return (arg: T) => f(arg) || g(arg) || others.some(f => f(arg)); } export function assertTypeIsNever(_: never): void { } // tslint:disable-line no-empty diff --git a/src/services/refactors/generateGetAccessorAndSetAccessor.ts b/src/services/refactors/generateGetAccessorAndSetAccessor.ts index 882b239cd9411..ae59fedb1763c 100644 --- a/src/services/refactors/generateGetAccessorAndSetAccessor.ts +++ b/src/services/refactors/generateGetAccessorAndSetAccessor.ts @@ -4,17 +4,20 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { const actionDescription = Diagnostics.Generate_get_and_set_accessors.message; registerRefactor(actionName, { getEditsForAction, getAvailableActions }); - type AccepedDeclaration = ParameterDeclaration | PropertyDeclaration; + type AccepedDeclaration = ParameterDeclaration | PropertyDeclaration | PropertyAssignment; + type AccepedNameTypes = Identifier | StringLiteral; + type ContainerDeclation = ClassLikeDeclaration | ObjectLiteralExpression; interface DeclarationInfo { - classLikeContainer: ClassLikeDeclaration; + container: ContainerDeclation; isStatic: boolean; + type: TypeNode | undefined; } interface Info extends DeclarationInfo { declaration: AccepedDeclaration; - fieldName: string; - accessorName: string; + fieldName: AccepedNameTypes; + accessorName: AccepedNameTypes; } function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined { @@ -40,22 +43,23 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { if (!fieldInfo) return undefined; const changeTracker = textChanges.ChangeTracker.fromContext(context); - const { isStatic, fieldName, accessorName, classLikeContainer, declaration } = fieldInfo; + const { isStatic, fieldName, accessorName, type, container, declaration } = fieldInfo; const accessorModifiers = getAccessorModifiers(declaration, isStatic); const fieldModifiers = getFieldModifiers(isStatic); - const getAccessor = generateGetAccessor(fieldName, accessorName, accessorModifiers, declaration, isStatic, classLikeContainer); - const setAccessor = generateSetAccessor(fieldName, accessorName, accessorModifiers, declaration, isStatic, classLikeContainer); + const getAccessor = generateGetAccessor(fieldName, accessorName, type, accessorModifiers, isStatic, container); + const setAccessor = generateSetAccessor(fieldName, accessorName, type, accessorModifiers, isStatic, container); - updateFieldDeclaration(changeTracker, file, declaration, fieldName, fieldModifiers, classLikeContainer); + updateFieldDeclaration(changeTracker, file, declaration, fieldName, fieldModifiers, container); - insertAccessor(changeTracker, file, getAccessor, declaration, classLikeContainer); - insertAccessor(changeTracker, file, setAccessor, declaration, classLikeContainer); + insertAccessor(changeTracker, file, getAccessor, declaration, container); + insertAccessor(changeTracker, file, setAccessor, declaration, container); const edits = changeTracker.getChanges(); const renameFilename = file.fileName; - const renameLocation = getRenameLocation(edits, renameFilename, fieldName, /*isDeclaredBeforeUse*/ false); + const renameLocationOffset = isIdentifier(fieldName) ? 0 : -1; + const renameLocation = renameLocationOffset + getRenameLocation(edits, renameFilename, fieldName.text, /*isDeclaredBeforeUse*/ false); return { renameFilename, renameLocation, edits }; } @@ -74,12 +78,17 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { isStatic ? createToken(SyntaxKind.StaticKeyword) : undefined)); } + function isConvertableName (name: DeclarationName): name is AccepedNameTypes { + return isIdentifier(name) || isStringLiteral(name); + } + function getPropertyDeclarationInfo(propertyDeclaration: PropertyDeclaration): DeclarationInfo | undefined { if (!isClassLike(propertyDeclaration.parent) || !propertyDeclaration.parent.members) return undefined; return { isStatic: hasStaticModifier(propertyDeclaration), - classLikeContainer: propertyDeclaration.parent + type: propertyDeclaration.type, + container: propertyDeclaration.parent }; } @@ -88,45 +97,72 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { return { isStatic: false, - classLikeContainer: parameterDeclaration.parent.parent + type: parameterDeclaration.type, + container: parameterDeclaration.parent.parent }; } + function getPropertyAssignmentDeclarationInfo(propertyAssignment: PropertyAssignment): DeclarationInfo | undefined { + return { + isStatic: false, + type: undefined, + container: propertyAssignment.parent + }; + } + + function getDeclarationInfo(declaration: AccepedDeclaration) { + if (isPropertyDeclaration(declaration)) { + return getPropertyDeclarationInfo(declaration); + } + else if (isPropertyAssignment(declaration)) { + return getPropertyAssignmentDeclarationInfo(declaration); + } + else { + return getParameterPropertyDeclarationInfo(declaration); + } + } + function getConvertibleFieldAtPosition(file: SourceFile, startPosition: number): Info | undefined { const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); - const declaration = findAncestor(node.parent, or(isParameterPropertyDeclaration, isPropertyDeclaration)); + const declaration = findAncestor(node.parent, or(isParameterPropertyDeclaration, isPropertyDeclaration, isPropertyAssignment)); // make sure propertyDeclaration have AccessibilityModifier or Static Modifier const meaning = ModifierFlags.AccessibilityModifier | ModifierFlags.Static; - if (!declaration || !isIdentifier(declaration.name) || (getModifierFlags(declaration) | meaning) !== meaning) return undefined; + if (!declaration || !isConvertableName(declaration.name) || (getModifierFlags(declaration) | meaning) !== meaning) return undefined; - const info = isPropertyDeclaration(declaration) ? getPropertyDeclarationInfo(declaration) : getParameterPropertyDeclarationInfo(declaration); + const info = getDeclarationInfo(declaration); return { ...info, declaration, - fieldName: getUniqueName(`_${(declaration.name).text}`, file.text), - accessorName: (declaration.name).text + fieldName: createAccessorName(getUniqueName(`_${declaration.name.text}`, file.text), declaration.name), + accessorName: createAccessorName(declaration.name.text, declaration.name) }; } - function generateGetAccessor(fieldName: string, accessorName: string, modifiers: ModifiersArray, propertyDeclaration: AccepedDeclaration, isStatic: boolean, classLikeContainer: ClassLikeDeclaration) { + function createAccessorName (name: string, originalName: AccepedNameTypes) { + return isIdentifier(originalName) ? createIdentifier(name) : createLiteral(name); + } + + function createAccessorAccessExpression (fieldName: AccepedNameTypes, isStatic: boolean, container: ContainerDeclation) { + const leftHead = isStatic ? (container).name : createThis(); + return isIdentifier(fieldName) ? createPropertyAccess(leftHead, fieldName) : createElementAccess(leftHead, createLiteral(fieldName)); + } + + function generateGetAccessor(fieldName: AccepedNameTypes, accessorName: AccepedNameTypes, type: TypeNode, modifiers: ModifiersArray, isStatic: boolean, container: ContainerDeclation) { return createGetAccessor( /*decorators*/ undefined, modifiers, accessorName, /*parameters*/ undefined, - propertyDeclaration.type, + type, createBlock([ createReturn( - createPropertyAccess( - isStatic ? classLikeContainer.name : createThis(), - fieldName - ) + createAccessorAccessExpression(fieldName, isStatic, container) ) ], /*multiLine*/ true) ); } - function generateSetAccessor(fieldName: string, accessorName: string, modifiers: ModifiersArray, propertyDeclaration: AccepedDeclaration, isStatic: boolean, classLikeContainer: ClassLikeDeclaration) { + function generateSetAccessor(fieldName: AccepedNameTypes, accessorName: AccepedNameTypes, type: TypeNode, modifiers: ModifiersArray, isStatic: boolean, container: ContainerDeclation) { return createSetAccessor( /*decorators*/ undefined, modifiers, @@ -137,15 +173,12 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { /*dotDotDotToken*/ undefined, createIdentifier("value"), /*questionToken*/ undefined, - propertyDeclaration.type + type )], createBlock([ createStatement( createAssignment( - createPropertyAccess( - isStatic ? classLikeContainer.name : createThis(), - fieldName - ), + createAccessorAccessExpression(fieldName, isStatic, container), createIdentifier("value") ) ) @@ -153,7 +186,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { ); } - function updatePropertyDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: PropertyDeclaration, fieldName: string, modifiers: ModifiersArray) { + function updatePropertyDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: PropertyDeclaration, fieldName: AccepedNameTypes, modifiers: ModifiersArray) { const property = updateProperty( declaration, declaration.decorators, @@ -167,7 +200,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { changeTracker.replaceNode(file, declaration, property); } - function updateParameterPropertyDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: ParameterDeclaration, fieldName: string, modifiers: ModifiersArray, classLikeContainer: ClassLikeDeclaration) { + function updateParameterPropertyDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: ParameterDeclaration, fieldName: AccepedNameTypes, modifiers: ModifiersArray, classLikeContainer: ClassLikeDeclaration) { const property = createProperty( declaration.decorators, modifiers, @@ -181,14 +214,26 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { changeTracker.deleteNodeInList(file, declaration); } + function updatePropertyAssignmentDeclaration (changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: PropertyAssignment, fieldName: AccepedNameTypes) { + const assignment = updatePropertyAssignment(declaration, fieldName, declaration.initializer); + changeTracker.replacePropertyAssignment(file, declaration, assignment); + } - function updateFieldDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: AccepedDeclaration, fieldName: string, modifiers: ModifiersArray, classLikeContainer: ClassLikeDeclaration) { - isPropertyDeclaration(declaration) - ? updatePropertyDeclaration(changeTracker, file, declaration, fieldName, modifiers) - : updateParameterPropertyDeclaration(changeTracker, file, declaration, fieldName, modifiers, classLikeContainer); + function updateFieldDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: AccepedDeclaration, fieldName: AccepedNameTypes, modifiers: ModifiersArray, container: ContainerDeclation) { + if (isPropertyDeclaration(declaration)) { + updatePropertyDeclaration(changeTracker, file, declaration, fieldName, modifiers); + } + else if (isPropertyAssignment(declaration)) { + updatePropertyAssignmentDeclaration(changeTracker, file, declaration, fieldName); + } + else { + updateParameterPropertyDeclaration(changeTracker, file, declaration, fieldName, modifiers, container); + } } - function insertAccessor(changeTracker: textChanges.ChangeTracker, file: SourceFile, accessor: AccessorDeclaration, declaration: AccepedDeclaration, classLikeContainer: ClassLikeDeclaration) { - isPropertyDeclaration(declaration) ? changeTracker.insertNodeAfter(file, declaration, accessor) : changeTracker.insertNodeAtClassStart(file, classLikeContainer, accessor); + function insertAccessor(changeTracker: textChanges.ChangeTracker, file: SourceFile, accessor: AccessorDeclaration, declaration: AccepedDeclaration, container: ContainerDeclation) { + isParameterPropertyDeclaration(declaration) + ? changeTracker.insertNodeAtClassStart(file, container, accessor) + : changeTracker.insertNodeAfter(file, declaration, accessor); } } diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 0b29cdc438b4b..550ad095fe0b7 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -316,6 +316,12 @@ namespace ts.textChanges { return this.replaceRangeWithNodes(sourceFile, getAdjustedRange(sourceFile, startNode, endNode, options), newNodes, options); } + public replacePropertyAssignment(sourceFile: SourceFile, oldNode: PropertyAssignment, newNode: PropertyAssignment) { + return this.replaceNode(sourceFile, oldNode, newNode, { + suffix: "," + this.newLineCharacter + }) + } + private insertNodeAt(sourceFile: SourceFile, pos: number, newNode: Node, options: InsertNodeOptions = {}) { this.replaceRange(sourceFile, createTextRange(pos), newNode, options); } @@ -462,6 +468,9 @@ namespace ts.textChanges { else if (isVariableDeclaration(node)) { return { prefix: ", " }; } + else if (isPropertyAssignment(node)) { + return { suffix: "," + this.newLineCharacter } + } else if (isParameter(node)) { return {}; } diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess12.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess12.ts index 3cd29710fa4be..0e552e83ab3b9 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess12.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess12.ts @@ -1,9 +1,10 @@ /// //// class A { -//// /*a*/public "a": string = "foo";/*b*/ -//// /*c*/public get b/*d*/ () { return 1; } -//// /*e*/public set b/*f*/ (v) { } +//// /*a*/public get a/*b*/ () { return 1; } +//// /*c*/public set a/*d*/ (v) { } +//// /*e*/public ['b']/*f*/ () { } +//// /*g*/public ['c'] = 1;/*h*/ //// } goTo.select("a", "b"); @@ -13,4 +14,7 @@ goTo.select("c", "d"); verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); goTo.select("e", "f"); +verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); + +goTo.select("g", "h"); verify.not.refactorAvailable("Generate 'get' and 'set' accessors"); \ No newline at end of file diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess25.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess25.ts new file mode 100644 index 0000000000000..295b9e328271d --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess25.ts @@ -0,0 +1,21 @@ +/// + +//// class A { +//// public /*a*/"a"/*b*/: number = 1; +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private /*RENAME*/"_a": number = 1; + public get "a"(): number { + return this["_a"]; + } + public set "a"(value: number) { + this["_a"] = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess26.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess26.ts new file mode 100644 index 0000000000000..fd2936bd65802 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess26.ts @@ -0,0 +1,23 @@ +/// + +//// class A { +//// public _a: string = ""; +//// /*a*/public "a": number = 1;/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + public _a: string = ""; + private /*RENAME*/"_a_1": number = 1; + public get "a"(): number { + return this["_a_1"]; + } + public set "a"(value: number) { + this["_a_1"] = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess27.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess27.ts new file mode 100644 index 0000000000000..9538be381ca43 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess27.ts @@ -0,0 +1,21 @@ +/// + +//// class A { +//// /*a*/public "a-b": number = 1;/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private /*RENAME*/"_a-b": number = 1; + public get "a-b"(): number { + return this["_a-b"]; + } + public set "a-b"(value: number) { + this["_a-b"] = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess28.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess28.ts new file mode 100644 index 0000000000000..17a401b63ac31 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess28.ts @@ -0,0 +1,21 @@ +/// + +//// class A { +//// /*a*/public static "a": number = 1;/*b*/ +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private static /*RENAME*/"_a": number = 1; + public static get "a"(): number { + return A["_a"]; + } + public static set "a"(value: number) { + A["_a"] = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess29.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess29.ts new file mode 100644 index 0000000000000..f39da38d55f30 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess29.ts @@ -0,0 +1,21 @@ +/// + +//// const A = { +//// /*a*/a/*b*/: 1 +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `const A = { + _a: 1, + get a(): number { + return this._a; + }, + set a(value: number) { + this._a = value; + }, +};`, +}); From fafdcf52afef06da3f5da487a64565d7a8ad5d95 Mon Sep 17 00:00:00 2001 From: kingwl Date: Sat, 7 Apr 2018 22:36:03 +0800 Subject: [PATCH 8/9] add support for js file --- .../generateGetAccessorAndSetAccessor.ts | 69 +++++++++++-------- src/services/textChanges.ts | 4 +- ...efactorConvertToGetAccessAndSetAccess29.ts | 8 +-- ...efactorConvertToGetAccessAndSetAccess30.ts | 21 ++++++ ...efactorConvertToGetAccessAndSetAccess31.ts | 21 ++++++ ...efactorConvertToGetAccessAndSetAccess32.ts | 25 +++++++ ...ctorConvertToGetAccessAndSetAccess_js_1.ts | 22 ++++++ ...ctorConvertToGetAccessAndSetAccess_js_2.ts | 22 ++++++ ...ctorConvertToGetAccessAndSetAccess_js_3.ts | 22 ++++++ ...ctorConvertToGetAccessAndSetAccess_js_4.ts | 22 ++++++ ...ctorConvertToGetAccessAndSetAccess_js_5.ts | 24 +++++++ ...ctorConvertToGetAccessAndSetAccess_js_6.ts | 24 +++++++ ...ctorConvertToGetAccessAndSetAccess_js_7.ts | 24 +++++++ ...ctorConvertToGetAccessAndSetAccess_js_8.ts | 26 +++++++ 14 files changed, 298 insertions(+), 36 deletions(-) create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess30.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess31.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess32.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_1.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_2.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_3.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_4.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_5.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_6.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_7.ts create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_8.ts diff --git a/src/services/refactors/generateGetAccessorAndSetAccessor.ts b/src/services/refactors/generateGetAccessorAndSetAccessor.ts index ae59fedb1763c..a9b982f639cd7 100644 --- a/src/services/refactors/generateGetAccessorAndSetAccessor.ts +++ b/src/services/refactors/generateGetAccessorAndSetAccessor.ts @@ -5,7 +5,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { registerRefactor(actionName, { getEditsForAction, getAvailableActions }); type AccepedDeclaration = ParameterDeclaration | PropertyDeclaration | PropertyAssignment; - type AccepedNameTypes = Identifier | StringLiteral; + type AccepedNameType = Identifier | StringLiteral; type ContainerDeclation = ClassLikeDeclaration | ObjectLiteralExpression; interface DeclarationInfo { @@ -16,8 +16,8 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { interface Info extends DeclarationInfo { declaration: AccepedDeclaration; - fieldName: AccepedNameTypes; - accessorName: AccepedNameTypes; + fieldName: AccepedNameType; + accessorName: AccepedNameType; } function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined { @@ -42,17 +42,19 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { const fieldInfo = getConvertibleFieldAtPosition(file, startPosition); if (!fieldInfo) return undefined; + const isJS = isSourceFileJavaScript(file); const changeTracker = textChanges.ChangeTracker.fromContext(context); const { isStatic, fieldName, accessorName, type, container, declaration } = fieldInfo; - const accessorModifiers = getAccessorModifiers(declaration, isStatic); - const fieldModifiers = getFieldModifiers(isStatic); + const isInClassLike = isClassLike(container); + const accessorModifiers = getAccessorModifiers(isJS, declaration, isStatic, isInClassLike); + const fieldModifiers = getFieldModifiers(isJS, isStatic, isInClassLike); + + updateFieldDeclaration(changeTracker, file, declaration, fieldName, fieldModifiers, container); const getAccessor = generateGetAccessor(fieldName, accessorName, type, accessorModifiers, isStatic, container); const setAccessor = generateSetAccessor(fieldName, accessorName, type, accessorModifiers, isStatic, container); - updateFieldDeclaration(changeTracker, file, declaration, fieldName, fieldModifiers, container); - insertAccessor(changeTracker, file, getAccessor, declaration, container); insertAccessor(changeTracker, file, setAccessor, declaration, container); @@ -63,7 +65,22 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { return { renameFilename, renameLocation, edits }; } - function getAccessorModifiers(declaration: AccepedDeclaration, isStatic: boolean): NodeArray { + function isConvertableName (name: DeclarationName): name is AccepedNameType { + return isIdentifier(name) || isStringLiteral(name); + } + + function createPropertyName (name: string, originalName: AccepedNameType) { + return isIdentifier(originalName) ? createIdentifier(name) : createLiteral(name); + } + + function createAccessorAccessExpression (fieldName: AccepedNameType, isStatic: boolean, container: ContainerDeclation) { + const leftHead = isStatic ? (container).name : createThis(); + return isIdentifier(fieldName) ? createPropertyAccess(leftHead, fieldName) : createElementAccess(leftHead, createLiteral(fieldName)); + } + + function getAccessorModifiers(isJS: boolean, declaration: AccepedDeclaration, isStatic: boolean, isClassLike: boolean): NodeArray | undefined { + if (isJS || !isClassLike) return undefined; + if (!declaration.modifiers || getModifierFlags(declaration) & ModifierFlags.Private) { return createNodeArray( append([createToken(SyntaxKind.PublicKeyword)], @@ -72,16 +89,14 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { return declaration.modifiers; } - function getFieldModifiers(isStatic: boolean): NodeArray { + function getFieldModifiers(isJS: boolean, isStatic: boolean, isClassLike: boolean): NodeArray | undefined { + if (isJS || !isClassLike) return undefined; + return createNodeArray( append([createToken(SyntaxKind.PrivateKeyword)], isStatic ? createToken(SyntaxKind.StaticKeyword) : undefined)); } - function isConvertableName (name: DeclarationName): name is AccepedNameTypes { - return isIdentifier(name) || isStringLiteral(name); - } - function getPropertyDeclarationInfo(propertyDeclaration: PropertyDeclaration): DeclarationInfo | undefined { if (!isClassLike(propertyDeclaration.parent) || !propertyDeclaration.parent.members) return undefined; @@ -130,24 +145,18 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { if (!declaration || !isConvertableName(declaration.name) || (getModifierFlags(declaration) | meaning) !== meaning) return undefined; const info = getDeclarationInfo(declaration); + const fieldName = createPropertyName(getUniqueName(`_${declaration.name.text}`, file.text), declaration.name); + suppressLeadingAndTrailingTrivia(fieldName); + suppressLeadingAndTrailingTrivia(declaration); return { ...info, declaration, - fieldName: createAccessorName(getUniqueName(`_${declaration.name.text}`, file.text), declaration.name), - accessorName: createAccessorName(declaration.name.text, declaration.name) + fieldName, + accessorName: createPropertyName(declaration.name.text, declaration.name) }; } - function createAccessorName (name: string, originalName: AccepedNameTypes) { - return isIdentifier(originalName) ? createIdentifier(name) : createLiteral(name); - } - - function createAccessorAccessExpression (fieldName: AccepedNameTypes, isStatic: boolean, container: ContainerDeclation) { - const leftHead = isStatic ? (container).name : createThis(); - return isIdentifier(fieldName) ? createPropertyAccess(leftHead, fieldName) : createElementAccess(leftHead, createLiteral(fieldName)); - } - - function generateGetAccessor(fieldName: AccepedNameTypes, accessorName: AccepedNameTypes, type: TypeNode, modifiers: ModifiersArray, isStatic: boolean, container: ContainerDeclation) { + function generateGetAccessor(fieldName: AccepedNameType, accessorName: AccepedNameType, type: TypeNode, modifiers: ModifiersArray | undefined, isStatic: boolean, container: ContainerDeclation) { return createGetAccessor( /*decorators*/ undefined, modifiers, @@ -162,7 +171,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { ); } - function generateSetAccessor(fieldName: AccepedNameTypes, accessorName: AccepedNameTypes, type: TypeNode, modifiers: ModifiersArray, isStatic: boolean, container: ContainerDeclation) { + function generateSetAccessor(fieldName: AccepedNameType, accessorName: AccepedNameType, type: TypeNode, modifiers: ModifiersArray | undefined, isStatic: boolean, container: ContainerDeclation) { return createSetAccessor( /*decorators*/ undefined, modifiers, @@ -186,7 +195,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { ); } - function updatePropertyDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: PropertyDeclaration, fieldName: AccepedNameTypes, modifiers: ModifiersArray) { + function updatePropertyDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: PropertyDeclaration, fieldName: AccepedNameType, modifiers: ModifiersArray | undefined) { const property = updateProperty( declaration, declaration.decorators, @@ -200,7 +209,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { changeTracker.replaceNode(file, declaration, property); } - function updateParameterPropertyDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: ParameterDeclaration, fieldName: AccepedNameTypes, modifiers: ModifiersArray, classLikeContainer: ClassLikeDeclaration) { + function updateParameterPropertyDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: ParameterDeclaration, fieldName: AccepedNameType, modifiers: ModifiersArray | undefined, classLikeContainer: ClassLikeDeclaration) { const property = createProperty( declaration.decorators, modifiers, @@ -214,12 +223,12 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { changeTracker.deleteNodeInList(file, declaration); } - function updatePropertyAssignmentDeclaration (changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: PropertyAssignment, fieldName: AccepedNameTypes) { + function updatePropertyAssignmentDeclaration (changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: PropertyAssignment, fieldName: AccepedNameType) { const assignment = updatePropertyAssignment(declaration, fieldName, declaration.initializer); changeTracker.replacePropertyAssignment(file, declaration, assignment); } - function updateFieldDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: AccepedDeclaration, fieldName: AccepedNameTypes, modifiers: ModifiersArray, container: ContainerDeclation) { + function updateFieldDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: AccepedDeclaration, fieldName: AccepedNameType, modifiers: ModifiersArray | undefined, container: ContainerDeclation) { if (isPropertyDeclaration(declaration)) { updatePropertyDeclaration(changeTracker, file, declaration, fieldName, modifiers); } diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 550ad095fe0b7..45460fce1f9a1 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -319,7 +319,7 @@ namespace ts.textChanges { public replacePropertyAssignment(sourceFile: SourceFile, oldNode: PropertyAssignment, newNode: PropertyAssignment) { return this.replaceNode(sourceFile, oldNode, newNode, { suffix: "," + this.newLineCharacter - }) + }); } private insertNodeAt(sourceFile: SourceFile, pos: number, newNode: Node, options: InsertNodeOptions = {}) { @@ -469,7 +469,7 @@ namespace ts.textChanges { return { prefix: ", " }; } else if (isPropertyAssignment(node)) { - return { suffix: "," + this.newLineCharacter } + return { suffix: "," + this.newLineCharacter }; } else if (isParameter(node)) { return {}; diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess29.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess29.ts index f39da38d55f30..63e4c44d4ba34 100644 --- a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess29.ts +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess29.ts @@ -2,7 +2,7 @@ //// const A = { //// /*a*/a/*b*/: 1 -//// } +//// }; goTo.select("a", "b"); edit.applyRefactor({ @@ -10,11 +10,11 @@ edit.applyRefactor({ actionName: "Generate 'get' and 'set' accessors", actionDescription: "Generate 'get' and 'set' accessors", newContent: `const A = { - _a: 1, - get a(): number { + /*RENAME*/_a: 1, + get a() { return this._a; }, - set a(value: number) { + set a(value) { this._a = value; }, };`, diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess30.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess30.ts new file mode 100644 index 0000000000000..dd45b7c0cd1b9 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess30.ts @@ -0,0 +1,21 @@ +/// + +//// const A = { +//// /*a*/'a'/*b*/: 1 +//// }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `const A = { + /*RENAME*/"_a": 1, + get "a"() { + return this["_a"]; + }, + set "a"(value) { + this["_a"] = value; + }, +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess31.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess31.ts new file mode 100644 index 0000000000000..67e8b461affc5 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess31.ts @@ -0,0 +1,21 @@ +/// + +//// class A { +//// public /*a*/a/*b*/ = 1; +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + private /*RENAME*/_a = 1; + public get a() { + return this._a; + } + public set a(value) { + this._a = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess32.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess32.ts new file mode 100644 index 0000000000000..2cb131e685e53 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess32.ts @@ -0,0 +1,25 @@ +/// + +//// /** Class comment */ +//// class A { +//// // Field comment +//// public /*a*/a/*b*/: number = 1; +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `/** Class comment */ +class A { + // Field comment + private /*RENAME*/_a: number = 1; + public get a(): number { + return this._a; + } + public set a(value: number) { + this._a = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_1.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_1.ts new file mode 100644 index 0000000000000..7293afd921972 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_1.ts @@ -0,0 +1,22 @@ +/// +// @allowJs: true +// @Filename: a.js +//// const A = { +//// /*a*/"a"/*b*/: 1 +//// }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `const A = { + /*RENAME*/"_a": 1, + get "a"() { + return this["_a"]; + }, + set "a"(value) { + this["_a"] = value; + }, +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_2.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_2.ts new file mode 100644 index 0000000000000..19b2ef109a757 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_2.ts @@ -0,0 +1,22 @@ +/// +// @allowJs: true +// @Filename: a.js +//// const A = { +//// /*a*/a/*b*/: 1 +//// }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `const A = { + /*RENAME*/_a: 1, + get a() { + return this._a; + }, + set a(value) { + this._a = value; + }, +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_3.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_3.ts new file mode 100644 index 0000000000000..683f92d39ab26 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_3.ts @@ -0,0 +1,22 @@ +/// +// @allowJs: true +// @Filename: a.js +//// class A { +//// /*a*/a/*b*/ = 1; +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + /*RENAME*/_a = 1; + get a() { + return this._a; + } + set a(value) { + this._a = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_4.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_4.ts new file mode 100644 index 0000000000000..43abee5f7a3df --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_4.ts @@ -0,0 +1,22 @@ +/// +// @allowJs: true +// @Filename: a.js +//// class A { +//// /*a*/"a"/*b*/ = 1; +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + /*RENAME*/"_a" = 1; + get "a"() { + return this["_a"]; + } + set "a"(value) { + this["_a"] = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_5.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_5.ts new file mode 100644 index 0000000000000..8c7ccde7e55a5 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_5.ts @@ -0,0 +1,24 @@ +/// +// @allowJs: true +// @Filename: a.js +//// class A { +//// _a = 2; +//// /*a*/"a"/*b*/ = 1; +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + _a = 2; + /*RENAME*/"_a_1" = 1; + get "a"() { + return this["_a_1"]; + } + set "a"(value) { + this["_a_1"] = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_6.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_6.ts new file mode 100644 index 0000000000000..0c521ee43b116 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_6.ts @@ -0,0 +1,24 @@ +/// +// @allowJs: true +// @Filename: a.js +//// class A { +//// "_a" = 2; +//// /*a*/"a"/*b*/ = 1; +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + "_a" = 2; + /*RENAME*/"_a_1" = 1; + get "a"() { + return this["_a_1"]; + } + set "a"(value) { + this["_a_1"] = value; + } +}`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_7.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_7.ts new file mode 100644 index 0000000000000..ca135132a81e0 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_7.ts @@ -0,0 +1,24 @@ +/// +// @allowJs: true +// @Filename: a.js +//// const A = { +//// _a: 2, +//// /*a*/a/*b*/: 1 +//// }; + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `const A = { + _a: 2, + /*RENAME*/_a_1: 1, + get a() { + return this._a_1; + }, + set a(value) { + this._a_1 = value; + }, +};`, +}); diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_8.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_8.ts new file mode 100644 index 0000000000000..e2ba5941fcbec --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_8.ts @@ -0,0 +1,26 @@ +/// +// @allowJs: true +// @Filename: a.js +//// /** Class comment */ +//// class A { +//// // Field comment +//// /*a*/a/*b*/ = 1; +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `/** Class comment */ +class A { + // Field comment + /*RENAME*/_a = 1; + get a() { + return this._a; + } + set a(value) { + this._a = value; + } +}`, +}); From 0da98bd57eb6a413e528984ec1a52b22feee1564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Tue, 10 Apr 2018 18:59:31 +0800 Subject: [PATCH 9/9] allow static modifier in js file --- .../generateGetAccessorAndSetAccessor.ts | 20 ++++++++++------- ...ctorConvertToGetAccessAndSetAccess_js_9.ts | 22 +++++++++++++++++++ 2 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_9.ts diff --git a/src/services/refactors/generateGetAccessorAndSetAccessor.ts b/src/services/refactors/generateGetAccessorAndSetAccessor.ts index a9b982f639cd7..f1b1499a83876 100644 --- a/src/services/refactors/generateGetAccessorAndSetAccessor.ts +++ b/src/services/refactors/generateGetAccessorAndSetAccessor.ts @@ -79,22 +79,26 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { } function getAccessorModifiers(isJS: boolean, declaration: AccepedDeclaration, isStatic: boolean, isClassLike: boolean): NodeArray | undefined { - if (isJS || !isClassLike) return undefined; + if (!isClassLike) return undefined; if (!declaration.modifiers || getModifierFlags(declaration) & ModifierFlags.Private) { - return createNodeArray( - append([createToken(SyntaxKind.PublicKeyword)], - isStatic ? createToken(SyntaxKind.StaticKeyword) : undefined)); + const modifiers = append( + !isJS ? [createToken(SyntaxKind.PublicKeyword)] : undefined, + isStatic ? createToken(SyntaxKind.StaticKeyword) : undefined + ); + return modifiers && createNodeArray(modifiers); } return declaration.modifiers; } function getFieldModifiers(isJS: boolean, isStatic: boolean, isClassLike: boolean): NodeArray | undefined { - if (isJS || !isClassLike) return undefined; + if (!isClassLike) return undefined; - return createNodeArray( - append([createToken(SyntaxKind.PrivateKeyword)], - isStatic ? createToken(SyntaxKind.StaticKeyword) : undefined)); + const modifiers = append( + !isJS ? [createToken(SyntaxKind.PrivateKeyword)] : undefined, + isStatic ? createToken(SyntaxKind.StaticKeyword) : undefined + ); + return modifiers && createNodeArray(modifiers); } function getPropertyDeclarationInfo(propertyDeclaration: PropertyDeclaration): DeclarationInfo | undefined { diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_9.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_9.ts new file mode 100644 index 0000000000000..4a80fe1af9f79 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_js_9.ts @@ -0,0 +1,22 @@ +/// +// @allowJs: true +// @Filename: a.js +//// class A { +//// static /*a*/a/*b*/ = 1; +//// } + +goTo.select("a", "b"); +edit.applyRefactor({ + refactorName: "Generate 'get' and 'set' accessors", + actionName: "Generate 'get' and 'set' accessors", + actionDescription: "Generate 'get' and 'set' accessors", + newContent: `class A { + static /*RENAME*/_a = 1; + static get a() { + return A._a; + } + static set a(value) { + A._a = value; + } +}`, +});