Skip to content

Commit

Permalink
Additional tests and language service fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
rbuckton committed Jun 29, 2022
1 parent 54024cf commit 9a9624b
Show file tree
Hide file tree
Showing 17 changed files with 1,522 additions and 37 deletions.
30 changes: 15 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions src/compiler/checker.ts
Expand Up @@ -8922,7 +8922,7 @@ namespace ts {
return getTypeForBindingElement(declaration as BindingElement);
}

const isProperty = isPropertyDeclaration(declaration) || isPropertySignature(declaration);
const isProperty = isPropertyDeclaration(declaration) && !hasAccessorModifier(declaration) || isPropertySignature(declaration);
const isOptional = includeOptionality && (
isProperty && !!declaration.questionToken ||
isParameter(declaration) && (!!declaration.questionToken || isJSDocOptionalParameter(declaration)) ||
Expand Down Expand Up @@ -12774,7 +12774,7 @@ namespace ts {
}

function isOptionalPropertyDeclaration(node: Declaration) {
return isPropertyDeclaration(node) && node.questionToken;
return isPropertyDeclaration(node) && !hasAccessorModifier(node) && node.questionToken;
}

function isOptionalJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag {
Expand Down Expand Up @@ -45152,9 +45152,12 @@ namespace ts {
if (languageVersion < ScriptTarget.ES2015 && isPrivateIdentifier(node.name)) {
return grammarErrorOnNode(node.name, Diagnostics.Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher);
}
if (languageVersion < ScriptTarget.ES2015 && hasAccessorModifier(node)) {
if (languageVersion < ScriptTarget.ES2015 && isAutoAccessorPropertyDeclaration(node)) {
return grammarErrorOnNode(node.name, Diagnostics.Properties_with_the_accessor_modifier_are_only_available_when_targeting_ECMAScript_2015_and_higher);
}
if (isAutoAccessorPropertyDeclaration(node) && checkGrammarForInvalidQuestionMark(node.questionToken, Diagnostics.An_accessor_property_cannot_be_declared_optional)) {
return true;
}
}
else if (node.parent.kind === SyntaxKind.InterfaceDeclaration) {
if (checkGrammarForInvalidDynamicName(node.name, Diagnostics.A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) {
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Expand Up @@ -903,6 +903,10 @@
"category": "Error",
"code": 1275
},
"An 'accessor' property cannot be declared optional.": {
"category": "Error",
"code": 1276
},

"'with' statements are not allowed in an async function block.": {
"category": "Error",
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/factory/nodeFactory.ts
Expand Up @@ -1100,10 +1100,10 @@ namespace ts {
if (flags & ModifierFlags.Private) result.push(createModifier(SyntaxKind.PrivateKeyword));
if (flags & ModifierFlags.Protected) result.push(createModifier(SyntaxKind.ProtectedKeyword));
if (flags & ModifierFlags.Abstract) result.push(createModifier(SyntaxKind.AbstractKeyword));
if (flags & ModifierFlags.Accessor) result.push(createModifier(SyntaxKind.AccessorKeyword));
if (flags & ModifierFlags.Static) result.push(createModifier(SyntaxKind.StaticKeyword));
if (flags & ModifierFlags.Override) result.push(createModifier(SyntaxKind.OverrideKeyword));
if (flags & ModifierFlags.Readonly) result.push(createModifier(SyntaxKind.ReadonlyKeyword));
if (flags & ModifierFlags.Accessor) result.push(createModifier(SyntaxKind.AccessorKeyword));
if (flags & ModifierFlags.Async) result.push(createModifier(SyntaxKind.AsyncKeyword));
if (flags & ModifierFlags.In) result.push(createModifier(SyntaxKind.InKeyword));
if (flags & ModifierFlags.Out) result.push(createModifier(SyntaxKind.OutKeyword));
Expand Down
21 changes: 9 additions & 12 deletions src/services/codefixes/helpers.ts
Expand Up @@ -67,8 +67,15 @@ namespace ts.codefix {
const scriptTarget = getEmitScriptTarget(context.program.getCompilerOptions());
const declaration = declarations[0];
const name = getSynthesizedDeepClone(getNameOfDeclaration(declaration), /*includeTrivia*/ false) as PropertyName;
const visibilityModifier = createVisibilityModifier(getEffectiveModifierFlags(declaration));
const modifiers = visibilityModifier ? factory.createNodeArray([visibilityModifier]) : undefined;
const effectiveModifierFlags = getEffectiveModifierFlags(declaration);
let modifierFlags =
effectiveModifierFlags & ModifierFlags.Public ? ModifierFlags.Public :
effectiveModifierFlags & ModifierFlags.Protected ? ModifierFlags.Protected :
ModifierFlags.None;
if (isAutoAccessorPropertyDeclaration(declaration)) {
modifierFlags |= ModifierFlags.Accessor;
}
const modifiers = modifierFlags ? factory.createNodeArray(factory.createModifiersFromModifierFlags(modifierFlags)) : undefined;
const type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration));
const optional = !!(symbol.flags & SymbolFlags.Optional);
const ambient = !!(enclosingDeclaration.flags & NodeFlags.Ambient) || isAmbient;
Expand Down Expand Up @@ -473,16 +480,6 @@ namespace ts.codefix {
/*multiline*/ true);
}

function createVisibilityModifier(flags: ModifierFlags): Modifier | undefined {
if (flags & ModifierFlags.Public) {
return factory.createToken(SyntaxKind.PublicKeyword);
}
else if (flags & ModifierFlags.Protected) {
return factory.createToken(SyntaxKind.ProtectedKeyword);
}
return undefined;
}

export function setJsonCompilerOptionValues(
changeTracker: textChanges.ChangeTracker,
configFile: TsConfigSourceFile,
Expand Down
6 changes: 5 additions & 1 deletion src/services/symbolDisplay.ts
Expand Up @@ -158,7 +158,7 @@ namespace ts.SymbolDisplay {
if (symbolKind !== ScriptElementKind.unknown || symbolFlags & SymbolFlags.Class || symbolFlags & SymbolFlags.Alias) {
// If symbol is accessor, they are allowed only if location is at declaration identifier of the accessor
if (symbolKind === ScriptElementKind.memberGetAccessorElement || symbolKind === ScriptElementKind.memberSetAccessorElement) {
const declaration = find(symbol.declarations as ((GetAccessorDeclaration | SetAccessorDeclaration)[]), declaration => declaration.name === location);
const declaration = find(symbol.declarations as ((GetAccessorDeclaration | SetAccessorDeclaration | PropertyDeclaration)[]), declaration => declaration.name === location);
if (declaration) {
switch(declaration.kind){
case SyntaxKind.GetAccessor:
Expand All @@ -167,6 +167,9 @@ namespace ts.SymbolDisplay {
case SyntaxKind.SetAccessor:
symbolKind = ScriptElementKind.memberSetAccessorElement;
break;
case SyntaxKind.PropertyDeclaration:
symbolKind = ScriptElementKind.memberAccessorVariableElement;
break;
default:
Debug.assertNever(declaration);
}
Expand Down Expand Up @@ -509,6 +512,7 @@ namespace ts.SymbolDisplay {

// For properties, variables and local vars: show the type
if (symbolKind === ScriptElementKind.memberVariableElement ||
symbolKind === ScriptElementKind.memberAccessorVariableElement ||
symbolKind === ScriptElementKind.memberGetAccessorElement ||
symbolKind === ScriptElementKind.memberSetAccessorElement ||
symbolKind === ScriptElementKind.jsxAttribute ||
Expand Down
3 changes: 3 additions & 0 deletions src/services/types.ts
Expand Up @@ -1461,6 +1461,9 @@ namespace ts {
*/
memberVariableElement = "property",

/** class X { [public|private]* accessor foo: number; } */
memberAccessorVariableElement = "accessor",

/**
* class X { constructor() { } }
* class X { static { } }
Expand Down
2 changes: 2 additions & 0 deletions tests/baselines/reference/accessorFieldAllowedModifiers.js
Expand Up @@ -13,6 +13,7 @@ abstract class C1 {
accessor "k": any;
accessor 108: any;
accessor ["m"]: any;
accessor n!: number;
}

class C2 extends C1 {
Expand Down Expand Up @@ -40,6 +41,7 @@ class C1 {
accessor "k";
accessor 108;
accessor ["m"];
accessor n;
}
class C2 extends C1 {
accessor e;
Expand Down
Expand Up @@ -10,9 +10,9 @@ tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallow
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(11,5): error TS1275: 'accessor' modifier can only appear on a property declaration.
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(12,5): error TS1275: 'accessor' modifier can only appear on a property declaration.
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(13,5): error TS1275: 'accessor' modifier can only appear on a property declaration.
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(17,14): error TS1029: 'override' modifier must precede 'accessor' modifier.
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(21,5): error TS1070: 'accessor' modifier cannot appear on a type member.
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(24,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(14,15): error TS1276: An 'accessor' property cannot be declared optional.
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(18,14): error TS1029: 'override' modifier must precede 'accessor' modifier.
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(22,5): error TS1070: 'accessor' modifier cannot appear on a type member.
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(25,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(26,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(27,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
Expand All @@ -21,13 +21,14 @@ tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallow
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(30,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(31,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(32,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(32,25): error TS2792: Cannot find module 'x'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(33,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(33,25): error TS2792: Cannot find module 'x'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(34,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(35,1): error TS1275: 'accessor' modifier can only appear on a property declaration.
tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts(36,1): error TS1275: 'accessor' modifier can only appear on a property declaration.


==== tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts (27 errors) ====
==== tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallowedModifiers.ts (28 errors) ====
abstract class C1 {
accessor accessor a: any;
~~~~~~~~
Expand Down Expand Up @@ -65,6 +66,9 @@ tests/cases/conformance/classes/propertyMemberDeclarations/accessorFieldDisallow
accessor constructor() {}
~~~~~~~~
!!! error TS1275: 'accessor' modifier can only appear on a property declaration.
accessor l?: any;
~
!!! error TS1276: An 'accessor' property cannot be declared optional.
}

class C2 extends C1 {
Expand Down
2 changes: 2 additions & 0 deletions tests/baselines/reference/accessorFieldDisallowedModifiers.js
Expand Up @@ -12,6 +12,7 @@ abstract class C1 {
accessor get j() { return false; }
accessor set k(v: any) {}
accessor constructor() {}
accessor l?: any;
}

class C2 extends C1 {
Expand Down Expand Up @@ -48,6 +49,7 @@ class C1 {
accessor get j() { return false; }
accessor set k(v) { }
constructor() { }
accessor l;
}
class C2 extends C1 {
accessor g;
Expand Down
2 changes: 2 additions & 0 deletions tests/baselines/reference/api/tsserverlibrary.d.ts
Expand Up @@ -6729,6 +6729,8 @@ declare namespace ts {
* interface Y { foo:number; }
*/
memberVariableElement = "property",
/** class X { [public|private]* accessor foo: number; } */
memberAccessorVariableElement = "accessor",
/**
* class X { constructor() { } }
* class X { static { } }
Expand Down
2 changes: 2 additions & 0 deletions tests/baselines/reference/api/typescript.d.ts
Expand Up @@ -6729,6 +6729,8 @@ declare namespace ts {
* interface Y { foo:number; }
*/
memberVariableElement = "property",
/** class X { [public|private]* accessor foo: number; } */
memberAccessorVariableElement = "accessor",
/**
* class X { constructor() { } }
* class X { static { } }
Expand Down

0 comments on commit 9a9624b

Please sign in to comment.