Skip to content

Commit 524fa64

Browse files
authored
Merge pull request #11547 from Microsoft/interfaceFixes
Codefix for implementing interfaces
2 parents 9865a17 + 3fc94bb commit 524fa64

File tree

163 files changed

+1564
-222
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

163 files changed

+1564
-222
lines changed

Jakefile.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ var servicesSources = [
151151
"signatureHelp.ts",
152152
"symbolDisplay.ts",
153153
"transpile.ts",
154+
// Formatting
154155
"formatting/formatting.ts",
155156
"formatting/formattingContext.ts",
156157
"formatting/formattingRequestKind.ts",
@@ -166,7 +167,18 @@ var servicesSources = [
166167
"formatting/rulesMap.ts",
167168
"formatting/rulesProvider.ts",
168169
"formatting/smartIndenter.ts",
169-
"formatting/tokenRange.ts"
170+
"formatting/tokenRange.ts",
171+
// CodeFixes
172+
"codeFixProvider.ts",
173+
"codefixes/fixes.ts",
174+
"codefixes/fixExtendsInterfaceBecomesImplements.ts",
175+
"codefixes/fixClassIncorrectlyImplementsInterface.ts",
176+
"codefixes/fixClassDoesntImplementInheritedAbstractMember.ts",
177+
"codefixes/fixClassSuperMustPrecedeThisAccess.ts",
178+
"codefixes/fixConstructorForDerivedNeedSuperCall.ts",
179+
"codefixes/helpers.ts",
180+
"codefixes/importFixes.ts",
181+
"codefixes/unusedIdentifierFixes.ts"
170182
].map(function (f) {
171183
return path.join(servicesDirectory, f);
172184
}));

src/compiler/checker.ts

+60-35
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,11 @@ namespace ts {
7979
getDeclaredTypeOfSymbol,
8080
getPropertiesOfType,
8181
getPropertyOfType,
82+
getIndexInfoOfType,
8283
getSignaturesOfType,
8384
getIndexTypeOfType,
8485
getBaseTypes,
86+
getTypeFromTypeNode,
8587
getReturnTypeOfSignature,
8688
getNonNullableType,
8789
getSymbolsInScope,
@@ -90,6 +92,7 @@ namespace ts {
9092
getExportSpecifierLocalTargetSymbol,
9193
getTypeAtLocation: getTypeOfNode,
9294
getPropertySymbolOfDestructuringAssignment,
95+
signatureToString,
9396
typeToString,
9497
getSymbolDisplayBuilder,
9598
symbolToString,
@@ -1369,7 +1372,9 @@ namespace ts {
13691372
return symbol.parent ? getFullyQualifiedName(symbol.parent) + "." + symbolToString(symbol) : symbolToString(symbol);
13701373
}
13711374

1372-
// Resolves a qualified name and any involved aliases
1375+
/**
1376+
* Resolves a qualified name and any involved aliases.
1377+
*/
13731378
function resolveEntityName(name: EntityNameOrEntityNameExpression, meaning: SymbolFlags, ignoreErrors?: boolean, dontResolveAlias?: boolean, location?: Node): Symbol | undefined {
13741379
if (nodeIsMissing(name)) {
13751380
return undefined;
@@ -2110,7 +2115,7 @@ namespace ts {
21102115
return result || types;
21112116
}
21122117

2113-
function visibilityToString(flags: ModifierFlags) {
2118+
function visibilityToString(flags: ModifierFlags): string | undefined {
21142119
if (flags === ModifierFlags.Private) {
21152120
return "private";
21162121
}
@@ -2488,26 +2493,6 @@ namespace ts {
24882493
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Value, SymbolFormatFlags.None, typeFormatFlags);
24892494
}
24902495

2491-
function writeIndexSignature(info: IndexInfo, keyword: SyntaxKind) {
2492-
if (info) {
2493-
if (info.isReadonly) {
2494-
writeKeyword(writer, SyntaxKind.ReadonlyKeyword);
2495-
writeSpace(writer);
2496-
}
2497-
writePunctuation(writer, SyntaxKind.OpenBracketToken);
2498-
writer.writeParameter(info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : "x");
2499-
writePunctuation(writer, SyntaxKind.ColonToken);
2500-
writeSpace(writer);
2501-
writeKeyword(writer, keyword);
2502-
writePunctuation(writer, SyntaxKind.CloseBracketToken);
2503-
writePunctuation(writer, SyntaxKind.ColonToken);
2504-
writeSpace(writer);
2505-
writeType(info.type, TypeFormatFlags.None);
2506-
writePunctuation(writer, SyntaxKind.SemicolonToken);
2507-
writer.writeLine();
2508-
}
2509-
}
2510-
25112496
function writePropertyWithModifiers(prop: Symbol) {
25122497
if (isReadonlySymbol(prop)) {
25132498
writeKeyword(writer, SyntaxKind.ReadonlyKeyword);
@@ -2595,8 +2580,8 @@ namespace ts {
25952580
writePunctuation(writer, SyntaxKind.SemicolonToken);
25962581
writer.writeLine();
25972582
}
2598-
writeIndexSignature(resolved.stringIndexInfo, SyntaxKind.StringKeyword);
2599-
writeIndexSignature(resolved.numberIndexInfo, SyntaxKind.NumberKeyword);
2583+
buildIndexSignatureDisplay(resolved.stringIndexInfo, writer, IndexKind.String, enclosingDeclaration, globalFlags, symbolStack);
2584+
buildIndexSignatureDisplay(resolved.numberIndexInfo, writer, IndexKind.Number, enclosingDeclaration, globalFlags, symbolStack);
26002585
for (const p of resolved.properties) {
26012586
const t = getTypeOfSymbol(p);
26022587
if (p.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(t).length) {
@@ -2787,6 +2772,11 @@ namespace ts {
27872772
}
27882773

27892774
function buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) {
2775+
const returnType = getReturnTypeOfSignature(signature);
2776+
if (flags & TypeFormatFlags.SuppressAnyReturnType && isTypeAny(returnType)) {
2777+
return;
2778+
}
2779+
27902780
if (flags & TypeFormatFlags.WriteArrowStyleSignature) {
27912781
writeSpace(writer);
27922782
writePunctuation(writer, SyntaxKind.EqualsGreaterThanToken);
@@ -2800,7 +2790,6 @@ namespace ts {
28002790
buildTypePredicateDisplay(signature.typePredicate, writer, enclosingDeclaration, flags, symbolStack);
28012791
}
28022792
else {
2803-
const returnType = getReturnTypeOfSignature(signature);
28042793
buildTypeDisplay(returnType, writer, enclosingDeclaration, flags, symbolStack);
28052794
}
28062795
}
@@ -2825,6 +2814,34 @@ namespace ts {
28252814
buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, symbolStack);
28262815
}
28272816

2817+
function buildIndexSignatureDisplay(info: IndexInfo, writer: SymbolWriter, kind: IndexKind, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]) {
2818+
if (info) {
2819+
if (info.isReadonly) {
2820+
writeKeyword(writer, SyntaxKind.ReadonlyKeyword);
2821+
writeSpace(writer);
2822+
}
2823+
writePunctuation(writer, SyntaxKind.OpenBracketToken);
2824+
writer.writeParameter(info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : "x");
2825+
writePunctuation(writer, SyntaxKind.ColonToken);
2826+
writeSpace(writer);
2827+
switch (kind) {
2828+
case IndexKind.Number:
2829+
writeKeyword(writer, SyntaxKind.NumberKeyword);
2830+
break;
2831+
case IndexKind.String:
2832+
writeKeyword(writer, SyntaxKind.StringKeyword);
2833+
break;
2834+
}
2835+
2836+
writePunctuation(writer, SyntaxKind.CloseBracketToken);
2837+
writePunctuation(writer, SyntaxKind.ColonToken);
2838+
writeSpace(writer);
2839+
buildTypeDisplay(info.type, writer, enclosingDeclaration, globalFlags, symbolStack);
2840+
writePunctuation(writer, SyntaxKind.SemicolonToken);
2841+
writer.writeLine();
2842+
}
2843+
}
2844+
28282845
return _displayBuilder || (_displayBuilder = {
28292846
buildSymbolDisplay,
28302847
buildTypeDisplay,
@@ -2835,6 +2852,7 @@ namespace ts {
28352852
buildDisplayForTypeParametersAndDelimiters,
28362853
buildTypeParameterDisplayFromSymbol,
28372854
buildSignatureDisplay,
2855+
buildIndexSignatureDisplay,
28382856
buildReturnTypeDisplay
28392857
});
28402858
}
@@ -3786,11 +3804,13 @@ namespace ts {
37863804
return signatures;
37873805
}
37883806

3789-
// The base constructor of a class can resolve to
3790-
// undefinedType if the class has no extends clause,
3791-
// unknownType if an error occurred during resolution of the extends expression,
3792-
// nullType if the extends expression is the null value, or
3793-
// an object type with at least one construct signature.
3807+
/**
3808+
* The base constructor of a class can resolve to
3809+
* * undefinedType if the class has no extends clause,
3810+
* * unknownType if an error occurred during resolution of the extends expression,
3811+
* * nullType if the extends expression is the null value, or
3812+
* * an object type with at least one construct signature.
3813+
*/
37943814
function getBaseConstructorTypeOfClass(type: InterfaceType): Type {
37953815
if (!type.resolvedBaseConstructorType) {
37963816
const baseTypeNode = getBaseTypeNodeOfClass(type);
@@ -4271,7 +4291,7 @@ namespace ts {
42714291
return <InterfaceTypeWithDeclaredMembers>type;
42724292
}
42734293

4274-
function getTypeWithThisArgument(type: Type, thisArgument?: Type) {
4294+
function getTypeWithThisArgument(type: Type, thisArgument?: Type): Type {
42754295
if (getObjectFlags(type) & ObjectFlags.Reference) {
42764296
return createTypeReference((<TypeReference>type).target,
42774297
concatenate((<TypeReference>type).typeArguments, [thisArgument || (<TypeReference>type).target.thisType]));
@@ -4497,6 +4517,9 @@ namespace ts {
44974517
setStructuredTypeMembers(type, emptySymbols, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
44984518
}
44994519

4520+
/**
4521+
* Converts an AnonymousType to a ResolvedType.
4522+
*/
45004523
function resolveAnonymousTypeMembers(type: AnonymousType) {
45014524
const symbol = type.symbol;
45024525
if (type.target) {
@@ -7278,10 +7301,12 @@ namespace ts {
72787301
return false;
72797302
}
72807303

7281-
// Compare two types and return
7282-
// Ternary.True if they are related with no assumptions,
7283-
// Ternary.Maybe if they are related with assumptions of other relationships, or
7284-
// Ternary.False if they are not related.
7304+
/**
7305+
* Compare two types and return
7306+
* * Ternary.True if they are related with no assumptions,
7307+
* * Ternary.Maybe if they are related with assumptions of other relationships, or
7308+
* * Ternary.False if they are not related.
7309+
*/
72857310
function isRelatedTo(source: Type, target: Type, reportErrors?: boolean, headMessage?: DiagnosticMessage): Ternary {
72867311
let result: Ternary;
72877312
if (source.flags & TypeFlags.StringOrNumberLiteral && source.flags & TypeFlags.FreshLiteral) {

src/compiler/core.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1060,7 +1060,7 @@ namespace ts {
10601060
}
10611061
}
10621062

1063-
function formatStringFromArgs(text: string, args: { [index: number]: string; }, baseIndex?: number): string {
1063+
export function formatStringFromArgs(text: string, args: { [index: number]: string; }, baseIndex?: number): string {
10641064
baseIndex = baseIndex || 0;
10651065

10661066
return text.replace(/{(\d+)}/g, (_match, index?) => args[+index + baseIndex]);

src/compiler/diagnosticMessages.json

+4-8
Original file line numberDiff line numberDiff line change
@@ -3239,23 +3239,19 @@
32393239
"category": "Message",
32403240
"code": 90002
32413241
},
3242-
"Change 'extends' to 'implements'": {
3242+
"Change 'extends' to 'implements'.": {
32433243
"category": "Message",
32443244
"code": 90003
32453245
},
3246-
"Remove unused identifiers": {
3246+
"Remove unused identifiers.": {
32473247
"category": "Message",
32483248
"code": 90004
32493249
},
3250-
"Implement interface on reference": {
3251-
"category": "Message",
3252-
"code": 90005
3253-
},
3254-
"Implement interface on class": {
3250+
"Implement interface '{0}'.": {
32553251
"category": "Message",
32563252
"code": 90006
32573253
},
3258-
"Implement inherited abstract class": {
3254+
"Implement inherited abstract class.": {
32593255
"category": "Message",
32603256
"code": 90007
32613257
},

src/compiler/types.ts

+20-13
Original file line numberDiff line numberDiff line change
@@ -640,9 +640,9 @@ namespace ts {
640640

641641
export interface ParameterDeclaration extends Declaration {
642642
kind: SyntaxKind.Parameter;
643-
dotDotDotToken?: DotDotDotToken; // Present on rest parameter
643+
dotDotDotToken?: DotDotDotToken; // Present on rest parameter
644644
name: BindingName; // Declared parameter name
645-
questionToken?: QuestionToken; // Present on optional parameter
645+
questionToken?: QuestionToken; // Present on optional parameter
646646
type?: TypeNode; // Optional type annotation
647647
initializer?: Expression; // Optional initializer
648648
}
@@ -658,14 +658,14 @@ namespace ts {
658658
export interface PropertySignature extends TypeElement {
659659
kind: SyntaxKind.PropertySignature | SyntaxKind.JSDocRecordMember;
660660
name: PropertyName; // Declared property name
661-
questionToken?: QuestionToken; // Present on optional property
661+
questionToken?: QuestionToken; // Present on optional property
662662
type?: TypeNode; // Optional type annotation
663663
initializer?: Expression; // Optional initializer
664664
}
665665

666666
export interface PropertyDeclaration extends ClassElement {
667667
kind: SyntaxKind.PropertyDeclaration;
668-
questionToken?: QuestionToken; // Present for use with reporting a grammar error
668+
questionToken?: QuestionToken; // Present for use with reporting a grammar error
669669
name: PropertyName;
670670
type?: TypeNode;
671671
initializer?: Expression; // Optional initializer
@@ -2334,6 +2334,7 @@ namespace ts {
23342334
getDeclaredTypeOfSymbol(symbol: Symbol): Type;
23352335
getPropertiesOfType(type: Type): Symbol[];
23362336
getPropertyOfType(type: Type, propertyName: string): Symbol;
2337+
getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo;
23372338
getSignaturesOfType(type: Type, kind: SignatureKind): Signature[];
23382339
getIndexTypeOfType(type: Type, kind: IndexKind): Type;
23392340
getBaseTypes(type: InterfaceType): ObjectType[];
@@ -2347,6 +2348,8 @@ namespace ts {
23472348
getExportSpecifierLocalTargetSymbol(location: ExportSpecifier): Symbol;
23482349
getPropertySymbolOfDestructuringAssignment(location: Identifier): Symbol;
23492350
getTypeAtLocation(node: Node): Type;
2351+
getTypeFromTypeNode(node: TypeNode): Type;
2352+
signatureToString(signature: Signature, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): string;
23502353
typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string;
23512354
symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string;
23522355
getSymbolDisplayBuilder(): SymbolDisplayBuilder;
@@ -2391,6 +2394,7 @@ namespace ts {
23912394
buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
23922395
buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void;
23932396
buildSignatureDisplay(signatures: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, kind?: SignatureKind): void;
2397+
buildIndexSignatureDisplay(info: IndexInfo, writer: SymbolWriter, kind: IndexKind, enclosingDeclaration?: Node, globalFlags?: TypeFormatFlags, symbolStack?: Symbol[]): void;
23942398
buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
23952399
buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
23962400
buildTypePredicateDisplay(predicate: TypePredicate, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void;
@@ -2434,6 +2438,7 @@ namespace ts {
24342438
InFirstTypeArgument = 0x00000100, // Writing first type argument of the instantiated type
24352439
InTypeAlias = 0x00000200, // Writing type in type alias declaration
24362440
UseTypeAliasValue = 0x00000400, // Serialize the type instead of using type-alias. This is needed when we emit declaration file.
2441+
SuppressAnyReturnType = 0x00000800, // If the return type is any-like, don't offer a return type.
24372442
}
24382443

24392444
export const enum SymbolFormatFlags {
@@ -2866,7 +2871,7 @@ namespace ts {
28662871
objectFlags: ObjectFlags;
28672872
}
28682873

2869-
// Class and interface types (TypeFlags.Class and TypeFlags.Interface)
2874+
/** Class and interface types (TypeFlags.Class and TypeFlags.Interface). */
28702875
export interface InterfaceType extends ObjectType {
28712876
typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic)
28722877
outerTypeParameters: TypeParameter[]; // Outer type parameters (undefined if none)
@@ -2886,14 +2891,16 @@ namespace ts {
28862891
declaredNumberIndexInfo: IndexInfo; // Declared numeric indexing info
28872892
}
28882893

2889-
// Type references (TypeFlags.Reference). When a class or interface has type parameters or
2890-
// a "this" type, references to the class or interface are made using type references. The
2891-
// typeArguments property specifies the types to substitute for the type parameters of the
2892-
// class or interface and optionally includes an extra element that specifies the type to
2893-
// substitute for "this" in the resulting instantiation. When no extra argument is present,
2894-
// the type reference itself is substituted for "this". The typeArguments property is undefined
2895-
// if the class or interface has no type parameters and the reference isn't specifying an
2896-
// explicit "this" argument.
2894+
/**
2895+
* Type references (TypeFlags.Reference). When a class or interface has type parameters or
2896+
* a "this" type, references to the class or interface are made using type references. The
2897+
* typeArguments property specifies the types to substitute for the type parameters of the
2898+
* class or interface and optionally includes an extra element that specifies the type to
2899+
* substitute for "this" in the resulting instantiation. When no extra argument is present,
2900+
* the type reference itself is substituted for "this". The typeArguments property is undefined
2901+
* if the class or interface has no type parameters and the reference isn't specifying an
2902+
* explicit "this" argument.
2903+
*/
28972904
export interface TypeReference extends ObjectType {
28982905
target: GenericType; // Type reference target
28992906
typeArguments: Type[]; // Type reference type arguments (undefined if none)

src/compiler/utilities.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1830,7 +1830,7 @@ namespace ts {
18301830
}
18311831
}
18321832

1833-
export function getAncestor(node: Node, kind: SyntaxKind): Node {
1833+
export function getAncestor(node: Node | undefined, kind: SyntaxKind): Node {
18341834
while (node) {
18351835
if (node.kind === kind) {
18361836
return node;

0 commit comments

Comments
 (0)