mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-14 19:16:17 -06:00
Split CodeFixes in Separate Files
This commit is contained in:
parent
ecc029fd1c
commit
a66b0ae54c
11
Jakefile.js
11
Jakefile.js
@ -149,6 +149,7 @@ var servicesSources = [
|
||||
"signatureHelp.ts",
|
||||
"symbolDisplay.ts",
|
||||
"transpile.ts",
|
||||
// Formatting
|
||||
"formatting/formatting.ts",
|
||||
"formatting/formattingContext.ts",
|
||||
"formatting/formattingRequestKind.ts",
|
||||
@ -164,7 +165,15 @@ var servicesSources = [
|
||||
"formatting/rulesMap.ts",
|
||||
"formatting/rulesProvider.ts",
|
||||
"formatting/smartIndenter.ts",
|
||||
"formatting/tokenRange.ts"
|
||||
"formatting/tokenRange.ts",
|
||||
// CodeFixes
|
||||
"codeFixes/codeFixProvider.ts",
|
||||
"codeFixes/fixes.ts",
|
||||
"codeFixes/fixExtendsInterfaceBecomesImplements.ts",
|
||||
"codeFixes/fixClassIncorrectlyImplementsInterface.ts",
|
||||
"codeFixes/fixClassDoesntImplementInheritedAbstractMember.ts",
|
||||
"codeFixes/fixClassSuperMustPrecedeThisAccess.ts",
|
||||
"codeFixes/fixConstructorForDerivedNeedSuperCall.ts"
|
||||
].map(function (f) {
|
||||
return path.join(servicesDirectory, f);
|
||||
}));
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
registerCodeFix({
|
||||
errorCodes: [Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2.code],
|
||||
getCodeActions: (context: CodeFixContext) => {
|
||||
const sourceFile = context.sourceFile;
|
||||
const start = context.span.start;
|
||||
const token = getTokenAtPosition(sourceFile, start);
|
||||
const checker = context.program.getTypeChecker();
|
||||
|
||||
if (token.kind === SyntaxKind.Identifier && isClassLike(token.parent)) {
|
||||
const classDeclaration = <ClassDeclaration>token.parent;
|
||||
const startPos = classDeclaration.members.pos;
|
||||
// TODO: (arozga) actually get abstract members
|
||||
const abstractClassMembers = ts.map(getNamedAbstractClassMembers(classDeclaration), member => member.name.getText());
|
||||
const trackingAddedMembers: string[] = [];
|
||||
const extendsClause = ts.getClassExtendsHeritageClauseElement(classDeclaration);
|
||||
let textChanges = getCodeFixChanges(extendsClause, abstractClassMembers, startPos, checker, /*reference*/ false, trackingAddedMembers, context.newLineCharacter);
|
||||
|
||||
if (textChanges.length > 0) {
|
||||
return [{
|
||||
description: getLocaleSpecificMessage(Diagnostics.Implement_inherited_abstract_class),
|
||||
changes: [{
|
||||
fileName: sourceFile.fileName,
|
||||
textChanges: textChanges
|
||||
}]
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
registerCodeFix({
|
||||
errorCodes: [Diagnostics.Class_0_incorrectly_implements_interface_1.code],
|
||||
getCodeActions: (context: CodeFixContext) => {
|
||||
const sourceFile = context.sourceFile;
|
||||
const start = context.span.start;
|
||||
const token = getTokenAtPosition(sourceFile, start);
|
||||
const checker = context.program.getTypeChecker();
|
||||
|
||||
if (token.kind === SyntaxKind.Identifier && isClassLike(token.parent)) {
|
||||
const classDeclaration = <ClassDeclaration>token.parent;
|
||||
const startPos: number = classDeclaration.members.pos;
|
||||
const classMembers = ts.map(getNamedClassMembers(classDeclaration), member => member.name.getText());
|
||||
const trackingAddedMembers: string[] = [];
|
||||
const interfaceClauses = ts.getClassImplementsHeritageClauseElements(classDeclaration);
|
||||
|
||||
let textChanges: TextChange[] = undefined;
|
||||
|
||||
for (let i = 0; interfaceClauses && i < interfaceClauses.length; i++) {
|
||||
let newChanges = getCodeFixChanges(interfaceClauses[i], classMembers, startPos, checker, /*reference*/ false, trackingAddedMembers, context.newLineCharacter);
|
||||
textChanges = textChanges ? textChanges.concat(newChanges) : newChanges;
|
||||
}
|
||||
|
||||
if (textChanges && textChanges.length > 0) {
|
||||
return [{
|
||||
description: getLocaleSpecificMessage(Diagnostics.Implement_interface_on_class),
|
||||
changes: [{
|
||||
fileName: sourceFile.fileName,
|
||||
textChanges: textChanges
|
||||
}]
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1,28 +1,5 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
function getOpenBraceEnd(constructor: ConstructorDeclaration, sourceFile: SourceFile) {
|
||||
// First token is the open curly, this is where we want to put the 'super' call.
|
||||
return constructor.body.getFirstToken(sourceFile).getEnd();
|
||||
}
|
||||
|
||||
registerCodeFix({
|
||||
errorCodes: [Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call.code],
|
||||
getCodeActions: (context: CodeFixContext) => {
|
||||
const sourceFile = context.sourceFile;
|
||||
const token = getTokenAtPosition(sourceFile, context.span.start);
|
||||
|
||||
if (token.kind !== SyntaxKind.ConstructorKeyword) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const newPosition = getOpenBraceEnd(<ConstructorDeclaration>token.parent, sourceFile);
|
||||
return [{
|
||||
description: getLocaleSpecificMessage(Diagnostics.Add_missing_super_call),
|
||||
changes: [{ fileName: sourceFile.fileName, textChanges: [{ newText: "super();", span: { start: newPosition, length: 0 } }] }]
|
||||
}];
|
||||
}
|
||||
});
|
||||
|
||||
registerCodeFix({
|
||||
errorCodes: [Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class.code],
|
||||
getCodeActions: (context: CodeFixContext) => {
|
||||
@ -0,0 +1,20 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
registerCodeFix({
|
||||
errorCodes: [Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call.code],
|
||||
getCodeActions: (context: CodeFixContext) => {
|
||||
const sourceFile = context.sourceFile;
|
||||
const token = getTokenAtPosition(sourceFile, context.span.start);
|
||||
|
||||
if (token.kind !== SyntaxKind.ConstructorKeyword) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const newPosition = getOpenBraceEnd(<ConstructorDeclaration>token.parent, sourceFile);
|
||||
return [{
|
||||
description: getLocaleSpecificMessage(Diagnostics.Add_missing_super_call),
|
||||
changes: [{ fileName: sourceFile.fileName, textChanges: [{ newText: "super();", span: { start: newPosition, length: 0 } }] }]
|
||||
}];
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1,3 +1,5 @@
|
||||
///<reference path='superFixes.ts' />
|
||||
///<reference path='interfaceFixes.ts' />
|
||||
///<reference path='changeExtendsToImplementsFix.ts' />
|
||||
/// <reference path="fixClassIncorrectlyImplementsInterface.ts" />
|
||||
/// <reference path="fixClassDoesntImplementInheritedAbstractMember.ts" />
|
||||
/// <reference path="fixClassSuperMustPrecedeThisAccess.ts" />
|
||||
/// <reference path="fixConstructorForDerivedNeedSuperCall.ts" />
|
||||
/// <reference path="fixExtendsInterfaceBecomesImplements.ts" />
|
||||
@ -1,228 +0,0 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
registerCodeFix({
|
||||
errorCodes: [Diagnostics.Class_0_incorrectly_implements_interface_1.code],
|
||||
getCodeActions: (context: CodeFixContext) => {
|
||||
const sourceFile = context.sourceFile;
|
||||
const start = context.span.start;
|
||||
const token = getTokenAtPosition(sourceFile, start);
|
||||
const checker = context.program.getTypeChecker();
|
||||
|
||||
if (token.kind === SyntaxKind.Identifier && isClassLike(token.parent)) {
|
||||
const classDeclaration = <ClassDeclaration>token.parent;
|
||||
const startPos: number = classDeclaration.members.pos;
|
||||
const classMembers = ts.map(getNamedClassMemberDeclarations(classDeclaration), member => member.name.getText());
|
||||
const trackingAddedMembers: string[] = [];
|
||||
const interfaceClauses = ts.getClassImplementsHeritageClauseElements(classDeclaration);
|
||||
|
||||
let textChanges: TextChange[] = undefined;
|
||||
|
||||
for (let i = 0; interfaceClauses && i < interfaceClauses.length; i++) {
|
||||
let newChanges = getChanges(interfaceClauses[i], classMembers, startPos, checker, /*reference*/ false, trackingAddedMembers, context.newLineCharacter);
|
||||
textChanges = textChanges ? textChanges.concat(newChanges) : newChanges;
|
||||
}
|
||||
|
||||
if (textChanges && textChanges.length > 0) {
|
||||
return [{
|
||||
description: getLocaleSpecificMessage(Diagnostics.Implement_interface_on_class),
|
||||
changes: [{
|
||||
fileName: sourceFile.fileName,
|
||||
textChanges: textChanges
|
||||
}]
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
|
||||
registerCodeFix({
|
||||
errorCodes: [Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2.code],
|
||||
getCodeActions: (context: CodeFixContext) => {
|
||||
const sourceFile = context.sourceFile;
|
||||
const start = context.span.start;
|
||||
const token = getTokenAtPosition(sourceFile, start);
|
||||
const checker = context.program.getTypeChecker();
|
||||
|
||||
let textChanges: TextChange[] = [];
|
||||
|
||||
if (token.kind === SyntaxKind.Identifier && isClassLike(token.parent)) {
|
||||
const classDeclaration = <ClassDeclaration>token.parent;
|
||||
const startPos = classDeclaration.members.pos;
|
||||
const abstractClassMembers = ts.map(getNamedClassAbstractMemberDeclarations(classDeclaration), member => member.name.getText());
|
||||
const trackingAddedMembers: string[] = [];
|
||||
const extendsClause = ts.getClassExtendsHeritageClauseElement(classDeclaration);
|
||||
textChanges = textChanges.concat(getChanges(extendsClause, abstractClassMembers, startPos, checker, /*reference*/ false, trackingAddedMembers, context.newLineCharacter));
|
||||
}
|
||||
|
||||
if (textChanges.length > 0) {
|
||||
return [{
|
||||
description: getLocaleSpecificMessage(Diagnostics.Implement_inherited_abstract_class),
|
||||
changes: [{
|
||||
fileName: sourceFile.fileName,
|
||||
textChanges: textChanges
|
||||
}]
|
||||
}];
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
|
||||
function getChanges(interfaceClause: Node, existingMembers: string[], startPos: number, checker: TypeChecker, reference: boolean, trackingAddedMembers: string[], newLineCharacter: string): TextChange[] {
|
||||
const type = checker.getTypeAtLocation(interfaceClause);
|
||||
const changesArray: TextChange[] = [];
|
||||
|
||||
if (type && type.symbol && type.symbol.declarations) {
|
||||
const interfaceMembers = getMembers(<InterfaceDeclaration>type.symbol.declarations[0], checker);
|
||||
for(let interfaceMember of interfaceMembers){
|
||||
if (interfaceMember.name && existingMembers.indexOf(interfaceMember.name.getText()) === -1) {
|
||||
if (interfaceMember.kind === SyntaxKind.PropertySignature) {
|
||||
const interfaceProperty = <PropertySignature>interfaceMember;
|
||||
if (trackingAddedMembers.indexOf(interfaceProperty.name.getText()) === -1) {
|
||||
let propertyText = "";
|
||||
if (reference) {
|
||||
propertyText = `${interfaceProperty.name.getText()} : ${getDefaultValue(interfaceProperty.type.kind)},${newLineCharacter}`;
|
||||
}
|
||||
else {
|
||||
propertyText = interfaceProperty.getText();
|
||||
const stringToAdd = !(propertyText.match(/;$/)) ? `;${newLineCharacter}` : newLineCharacter;
|
||||
propertyText += stringToAdd;
|
||||
}
|
||||
changesArray.push({ newText: propertyText, span: { start: startPos, length: 0 } });
|
||||
trackingAddedMembers.push(interfaceProperty.name.getText());
|
||||
}
|
||||
}
|
||||
else if (interfaceMember.kind === SyntaxKind.MethodSignature || interfaceMember.kind === SyntaxKind.MethodDeclaration) {
|
||||
const interfaceMethod = <MethodSignature>interfaceMember;
|
||||
handleMethods(interfaceMethod, startPos, reference, trackingAddedMembers, changesArray, newLineCharacter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reference && existingMembers.length === 0 && changesArray.length > 0) {
|
||||
let lastValue = changesArray[changesArray.length - 1].newText;
|
||||
lastValue = `${lastValue.substr(0, lastValue.length - (newLineCharacter.length + 1))} ${newLineCharacter}`;
|
||||
changesArray[changesArray.length - 1].newText = lastValue;
|
||||
}
|
||||
|
||||
return changesArray;
|
||||
}
|
||||
|
||||
function getMembers(declaration: InterfaceDeclaration, checker: TypeChecker): TypeElement[] {
|
||||
const clauses = getInterfaceBaseTypeNodes(declaration);
|
||||
let result: TypeElement[] = [];
|
||||
for (let i = 0; clauses && i < clauses.length; i++) {
|
||||
const type = checker.getTypeAtLocation(clauses[i]);
|
||||
if (type && type.symbol && type.symbol.declarations) {
|
||||
result = result.concat(getMembers(<InterfaceDeclaration>type.symbol.declarations[0], checker));
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration.members) {
|
||||
result = result.concat(declaration.members);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function getNamedClassMemberDeclarations(classDeclaration: ClassDeclaration): ClassElement[] {
|
||||
return classDeclaration.members.filter(member => member.name);
|
||||
}
|
||||
|
||||
function getNamedClassAbstractMemberDeclarations(classDeclaration: ClassDeclaration): ClassElement[] {
|
||||
return getNamedClassMemberDeclarations(classDeclaration).filter(member => getModifierFlags(member) & ModifierFlags.Abstract);
|
||||
}
|
||||
|
||||
/*
|
||||
function getMembersAndStartPosFromReference(variableDeclaration: VariableDeclaration): { startPos: number, members: string[] } {
|
||||
const children = variableDeclaration.getChildren();
|
||||
const variableMembers: string[] = [];
|
||||
let startPos = 0;
|
||||
|
||||
ts.forEach(children, child => {
|
||||
if (child.kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
const properties = (<ObjectLiteralExpression>child).properties;
|
||||
if (properties) {
|
||||
startPos = properties.pos;
|
||||
}
|
||||
for (let j = 0; properties && j < properties.length; j++) {
|
||||
if (properties[j].name) {
|
||||
variableMembers.push(properties[j].name.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return { startPos: startPos, members: variableMembers };
|
||||
}
|
||||
*/
|
||||
|
||||
function getDefaultValue(kind: SyntaxKind): string {
|
||||
switch (kind) {
|
||||
case SyntaxKind.StringKeyword:
|
||||
return '""';
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
return "false";
|
||||
case SyntaxKind.NumberKeyword:
|
||||
return "0";
|
||||
default:
|
||||
return "null";
|
||||
}
|
||||
}
|
||||
|
||||
function handleMethods(interfaceMethod: MethodSignature, startPos: number, isReference: boolean, trackingAddedMembers: string[], textChanges: TextChange[], newLineCharacter: string) {
|
||||
const methodBody = "throw new Error('Method not Implemented');";
|
||||
|
||||
if (trackingAddedMembers.indexOf(interfaceMethod.name.getText())) {
|
||||
const methodName = interfaceMethod.name.getText();
|
||||
const typeParameterArray: string[] = [];
|
||||
|
||||
for (let i = 0; interfaceMethod.typeParameters && i < interfaceMethod.typeParameters.length; i++) {
|
||||
typeParameterArray.push(interfaceMethod.typeParameters[i].getText());
|
||||
}
|
||||
|
||||
const parameterArray: string[] = [];
|
||||
for (let j = 0; interfaceMethod.parameters && j < interfaceMethod.parameters.length; j++) {
|
||||
parameterArray.push(interfaceMethod.parameters[j].getText());
|
||||
}
|
||||
|
||||
let methodText = methodName;
|
||||
if (typeParameterArray.length > 0) {
|
||||
methodText += "<";
|
||||
}
|
||||
|
||||
for (let k = 0; k < typeParameterArray.length; k++) {
|
||||
methodText += typeParameterArray[k];
|
||||
if (k !== typeParameterArray.length - 1) {
|
||||
methodText += ",";
|
||||
}
|
||||
}
|
||||
|
||||
if (typeParameterArray.length > 0) {
|
||||
methodText += ">";
|
||||
}
|
||||
|
||||
methodText += "(";
|
||||
for (let k = 0; k < parameterArray.length; k++) {
|
||||
methodText += parameterArray[k];
|
||||
if (k !== parameterArray.length - 1) {
|
||||
methodText += ",";
|
||||
}
|
||||
}
|
||||
|
||||
methodText += `)`;
|
||||
if (interfaceMethod.type) {
|
||||
methodText += ":" + interfaceMethod.type.getText();
|
||||
}
|
||||
|
||||
methodText += `{${newLineCharacter}${methodBody}${newLineCharacter}`;
|
||||
methodText = isReference ? methodText.concat(`},${newLineCharacter}`) : methodText.concat(`}${newLineCharacter}`);
|
||||
|
||||
textChanges.push({ newText: methodText, span: { start: startPos, length: 0 } });
|
||||
trackingAddedMembers.push(interfaceMethod.name.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -85,6 +85,11 @@
|
||||
"formatting/smartIndenter.ts",
|
||||
"formatting/tokenRange.ts",
|
||||
"codeFixes/codeFixProvider.ts",
|
||||
"codeFixes/fixes.ts"
|
||||
"codeFixes/fixes.ts",
|
||||
"codeFixes/fixExtendsInterfaceBecomesImplements.ts",
|
||||
"codeFixes/fixClassIncorrectlyImplementsInterface.ts",
|
||||
"codeFixes/fixClassDoesntImplementInheritedAbstractMember.ts",
|
||||
"codeFixes/fixClassSuperMustPrecedeThisAccess.ts",
|
||||
"codeFixes/fixConstructorForDerivedNeedSuperCall.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@ -1358,4 +1358,165 @@ namespace ts {
|
||||
diagnostics: error ? concatenate(diagnostics, [error]) : diagnostics
|
||||
};
|
||||
}
|
||||
|
||||
export function getCodeFixChanges(interfaceClause: Node, existingMembers: string[], startPos: number, checker: TypeChecker, reference: boolean, trackingAddedMembers: string[], newLineCharacter: string): TextChange[] {
|
||||
const type = checker.getTypeAtLocation(interfaceClause);
|
||||
const changesArray: TextChange[] = [];
|
||||
|
||||
if (type && type.symbol && type.symbol.declarations) {
|
||||
const interfaceMembers = getInterfaceMembers(<InterfaceDeclaration>type.symbol.declarations[0], checker);
|
||||
for(let interfaceMember of interfaceMembers){
|
||||
if (interfaceMember.name && existingMembers.indexOf(interfaceMember.name.getText()) === -1) {
|
||||
if (interfaceMember.kind === SyntaxKind.PropertySignature) {
|
||||
const interfaceProperty = <PropertySignature>interfaceMember;
|
||||
if (trackingAddedMembers.indexOf(interfaceProperty.name.getText()) === -1) {
|
||||
let propertyText = "";
|
||||
if (reference) {
|
||||
propertyText = `${interfaceProperty.name.getText()} : ${getDefaultValue(interfaceProperty.type.kind)},${newLineCharacter}`;
|
||||
}
|
||||
else {
|
||||
propertyText = interfaceProperty.getText();
|
||||
const stringToAdd = !(propertyText.match(/;$/)) ? `;${newLineCharacter}` : newLineCharacter;
|
||||
propertyText += stringToAdd;
|
||||
}
|
||||
changesArray.push({ newText: propertyText, span: { start: startPos, length: 0 } });
|
||||
trackingAddedMembers.push(interfaceProperty.name.getText());
|
||||
}
|
||||
}
|
||||
else if (interfaceMember.kind === SyntaxKind.MethodSignature || interfaceMember.kind === SyntaxKind.MethodDeclaration) {
|
||||
const interfaceMethod = <MethodSignature>interfaceMember;
|
||||
handleMethods(interfaceMethod, startPos, reference, trackingAddedMembers, changesArray, newLineCharacter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reference && existingMembers.length === 0 && changesArray.length > 0) {
|
||||
let lastValue = changesArray[changesArray.length - 1].newText;
|
||||
lastValue = `${lastValue.substr(0, lastValue.length - (newLineCharacter.length + 1))} ${newLineCharacter}`;
|
||||
changesArray[changesArray.length - 1].newText = lastValue;
|
||||
}
|
||||
|
||||
return changesArray;
|
||||
}
|
||||
|
||||
function getInterfaceMembers(declaration: InterfaceDeclaration, checker: TypeChecker): TypeElement[] {
|
||||
const clauses = getInterfaceBaseTypeNodes(declaration);
|
||||
let result: TypeElement[] = [];
|
||||
for (let i = 0; clauses && i < clauses.length; i++) {
|
||||
const type = checker.getTypeAtLocation(clauses[i]);
|
||||
if (type && type.symbol && type.symbol.declarations) {
|
||||
result = result.concat(getInterfaceMembers(<InterfaceDeclaration>type.symbol.declarations[0], checker));
|
||||
}
|
||||
}
|
||||
|
||||
if (declaration.members) {
|
||||
result = result.concat(declaration.members);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getNamedClassMembers(classDeclaration: ClassDeclaration): ClassElement[] {
|
||||
return classDeclaration.members.filter(member => member.name);
|
||||
}
|
||||
|
||||
export function getNamedAbstractClassMembers(classDeclaration: ClassDeclaration): ClassElement[] {
|
||||
return getNamedClassMembers(classDeclaration).filter(member => getModifierFlags(member) & ModifierFlags.Abstract);
|
||||
}
|
||||
|
||||
/*
|
||||
function getMembersAndStartPosFromReference(variableDeclaration: VariableDeclaration): { startPos: number, members: string[] } {
|
||||
const children = variableDeclaration.getChildren();
|
||||
const variableMembers: string[] = [];
|
||||
let startPos = 0;
|
||||
|
||||
ts.forEach(children, child => {
|
||||
if (child.kind === SyntaxKind.ObjectLiteralExpression) {
|
||||
const properties = (<ObjectLiteralExpression>child).properties;
|
||||
if (properties) {
|
||||
startPos = properties.pos;
|
||||
}
|
||||
for (let j = 0; properties && j < properties.length; j++) {
|
||||
if (properties[j].name) {
|
||||
variableMembers.push(properties[j].name.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return { startPos: startPos, members: variableMembers };
|
||||
}
|
||||
*/
|
||||
|
||||
function getDefaultValue(kind: SyntaxKind): string {
|
||||
switch (kind) {
|
||||
case SyntaxKind.StringKeyword:
|
||||
return '""';
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
return "false";
|
||||
case SyntaxKind.NumberKeyword:
|
||||
return "0";
|
||||
default:
|
||||
return "null";
|
||||
}
|
||||
}
|
||||
|
||||
function handleMethods(interfaceMethod: MethodSignature, startPos: number, isReference: boolean, trackingAddedMembers: string[], textChanges: TextChange[], newLineCharacter: string) {
|
||||
const methodBody = "throw new Error('Method not Implemented');";
|
||||
|
||||
if (trackingAddedMembers.indexOf(interfaceMethod.name.getText())) {
|
||||
const methodName = interfaceMethod.name.getText();
|
||||
const typeParameterArray: string[] = [];
|
||||
|
||||
for (let i = 0; interfaceMethod.typeParameters && i < interfaceMethod.typeParameters.length; i++) {
|
||||
typeParameterArray.push(interfaceMethod.typeParameters[i].getText());
|
||||
}
|
||||
|
||||
const parameterArray: string[] = [];
|
||||
for (let j = 0; interfaceMethod.parameters && j < interfaceMethod.parameters.length; j++) {
|
||||
parameterArray.push(interfaceMethod.parameters[j].getText());
|
||||
}
|
||||
|
||||
let methodText = methodName;
|
||||
if (typeParameterArray.length > 0) {
|
||||
methodText += "<";
|
||||
}
|
||||
|
||||
for (let k = 0; k < typeParameterArray.length; k++) {
|
||||
methodText += typeParameterArray[k];
|
||||
if (k !== typeParameterArray.length - 1) {
|
||||
methodText += ",";
|
||||
}
|
||||
}
|
||||
|
||||
if (typeParameterArray.length > 0) {
|
||||
methodText += ">";
|
||||
}
|
||||
|
||||
methodText += "(";
|
||||
for (let k = 0; k < parameterArray.length; k++) {
|
||||
methodText += parameterArray[k];
|
||||
if (k !== parameterArray.length - 1) {
|
||||
methodText += ",";
|
||||
}
|
||||
}
|
||||
|
||||
methodText += `)`;
|
||||
if (interfaceMethod.type) {
|
||||
methodText += ":" + interfaceMethod.type.getText();
|
||||
}
|
||||
|
||||
methodText += `{${newLineCharacter}${methodBody}${newLineCharacter}`;
|
||||
methodText = isReference ? methodText.concat(`},${newLineCharacter}`) : methodText.concat(`}${newLineCharacter}`);
|
||||
|
||||
textChanges.push({ newText: methodText, span: { start: startPos, length: 0 } });
|
||||
trackingAddedMembers.push(interfaceMethod.name.getText());
|
||||
}
|
||||
}
|
||||
|
||||
export function getOpenBraceEnd(constructor: ConstructorDeclaration, sourceFile: SourceFile) {
|
||||
// First token is the open curly, this is where we want to put the 'super' call.
|
||||
return constructor.body.getFirstToken(sourceFile).getEnd();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user