fix(33836): allow readonly modifier for a field with only get accessor (#36543)

This commit is contained in:
Alexander T
2020-05-13 23:28:32 +03:00
committed by GitHub
parent 9725d623ce
commit 71711257ea
3 changed files with 36 additions and 19 deletions

View File

@@ -41,7 +41,6 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
const fieldInfo = getConvertibleFieldAtPosition(context);
if (!fieldInfo) return undefined;
const isJS = isSourceFileJS(file);
const changeTracker = textChanges.ChangeTracker.fromContext(context);
const { isStatic, isReadonly, fieldName, accessorName, originalName, type, container, declaration, renameAccessor } = fieldInfo;
@@ -50,15 +49,20 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
suppressLeadingAndTrailingTrivia(declaration);
suppressLeadingAndTrailingTrivia(container);
const isInClassLike = isClassLike(container);
// avoid Readonly modifier because it will convert to get accessor
const modifierFlags = getEffectiveModifierFlags(declaration) & ~ModifierFlags.Readonly;
const accessorModifiers = isInClassLike
? !modifierFlags || modifierFlags & ModifierFlags.Private
? getModifiers(isJS, isStatic, SyntaxKind.PublicKeyword)
: createNodeArray(createModifiersFromModifierFlags(modifierFlags))
: undefined;
const fieldModifiers = isInClassLike ? getModifiers(isJS, isStatic, SyntaxKind.PrivateKeyword) : undefined;
let accessorModifiers: ModifiersArray | undefined;
let fieldModifiers: ModifiersArray | undefined;
if (isClassLike(container)) {
const modifierFlags = getEffectiveModifierFlags(declaration);
if (isSourceFileJS(file)) {
const modifiers = createModifiers(modifierFlags);
accessorModifiers = modifiers;
fieldModifiers = modifiers;
}
else {
accessorModifiers = createModifiers(prepareModifierFlagsForAccessor(modifierFlags));
fieldModifiers = createModifiers(prepareModifierFlagsForField(modifierFlags));
}
}
updateFieldDeclaration(changeTracker, file, declaration, fieldName, fieldModifiers);
@@ -105,12 +109,26 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
return isIdentifier(fieldName) ? createPropertyAccess(leftHead, fieldName) : createElementAccess(leftHead, createLiteral(fieldName));
}
function getModifiers(isJS: boolean, isStatic: boolean, accessModifier: SyntaxKind.PublicKeyword | SyntaxKind.PrivateKeyword): NodeArray<Modifier> | undefined {
const modifiers = append<Modifier>(
!isJS ? [createToken(accessModifier) as Token<SyntaxKind.PublicKeyword> | Token<SyntaxKind.PrivateKeyword>] : undefined,
isStatic ? createToken(SyntaxKind.StaticKeyword) : undefined
);
return modifiers && createNodeArray(modifiers);
function createModifiers(modifierFlags: ModifierFlags): ModifiersArray | undefined {
return modifierFlags ? createNodeArray(createModifiersFromModifierFlags(modifierFlags)) : undefined;
}
function prepareModifierFlagsForAccessor(modifierFlags: ModifierFlags): ModifierFlags {
modifierFlags &= ~ModifierFlags.Readonly; // avoid Readonly modifier because it will convert to get accessor
modifierFlags &= ~ModifierFlags.Private;
if (!(modifierFlags & ModifierFlags.Protected)) {
modifierFlags |= ModifierFlags.Public;
}
return modifierFlags;
}
function prepareModifierFlagsForField(modifierFlags: ModifierFlags): ModifierFlags {
modifierFlags &= ~ModifierFlags.Public;
modifierFlags &= ~ModifierFlags.Protected;
modifierFlags |= ModifierFlags.Private;
return modifierFlags;
}
function getConvertibleFieldAtPosition(context: RefactorContext): Info | undefined {