Skip to content

Commit 04bc19c

Browse files
committed
feat: add interface type skeleton
1 parent 44c3567 commit 04bc19c

File tree

1 file changed

+83
-28
lines changed

1 file changed

+83
-28
lines changed

src/wizardPhpSkeletons.ts

Lines changed: 83 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as vscode from 'vscode';
22
import * as path from 'path';
33
import { showFile, writeFile, generateNamespace } from './utils/files';
4+
import { capitalize, capitalizeAndTrim } from './utils/string';
45

56
export async function wizardGeneratePhpSkeleton() {
67
const folder = await wizardSelectFolder();
@@ -41,7 +42,7 @@ async function wizardSelectFolder(): Promise<vscode.Uri> {
4142
async function wizardFileType(): Promise<string> {
4243
const acceptedTypes = [
4344
"class",
44-
// "interface",
45+
"interface",
4546
// "trait",
4647
// "enum",
4748
// "value object (immutable class)"
@@ -60,31 +61,33 @@ async function wizardFileType(): Promise<string> {
6061
}
6162

6263
async function wizardFileName(type: string): Promise<string> {
63-
let className = await vscode.window.showInputBox({
64+
let fileName = await vscode.window.showInputBox({
6465
placeHolder: `Name of ${type}`
6566
});
66-
if (!className) {
67-
throw new Error("It is required to provide a name for the class");
67+
if (!fileName) {
68+
throw new Error("It is required to provide a name for the ${type}");
6869
}
69-
className = capitalizeAndTrim(className);
70-
return className;
70+
fileName = capitalizeAndTrim(fileName);
71+
return fileName;
7172
}
7273

73-
async function generatePhpSkeleton(type: string, className: string, namespace: string): Promise<string> {
74+
async function generatePhpSkeleton(type: string, fileName: string, namespace: string): Promise<string> {
7475
if (type === "class") {
75-
return await generatePhpClassSkeleton(className, namespace);
76+
return await generatePhpClassSkeleton(fileName, namespace);
77+
}
78+
if (type === "interface") {
79+
return await generatePhpInterfaceSkeleton(fileName, namespace);
7680
}
7781
return "## TODO";
7882
}
7983

8084
async function generatePhpClassSkeleton(className: string, namespace: string): Promise<string> {
81-
const properties = await wizardProperties();
85+
const properties = await wizardClassProperties();
8286

8387
let declareProperties = [];
8488
for (const property of properties) {
8589
declareProperties.push(`${property.visibility} ${property.type} $${property.name}`);
8690
}
87-
const declarePropertiesAsString = declareProperties.join(", ");
8891

8992
let gettersAndSetters = "";
9093
for (const property of properties) {
@@ -100,15 +103,15 @@ async function generatePhpClassSkeleton(className: string, namespace: string): P
100103
}`;
101104
}
102105

103-
let skeleton = `<?php
106+
const skeleton = `<?php
104107
105108
declare(strict_types=1);
106109
107110
namespace ${namespace};
108111
109112
class ${className}
110113
{
111-
public function __construct(${declarePropertiesAsString})
114+
public function __construct(${declareProperties.join(", ")})
112115
{
113116
}
114117
@@ -118,12 +121,7 @@ ${gettersAndSetters}
118121
return skeleton;
119122
}
120123

121-
function capitalize(str: string): string {
122-
return str.charAt(0).toUpperCase() + str.slice(1);
123-
}
124-
125-
126-
async function wizardProperties(): Promise<Array<{ name: string, visibility: string, type: string }>> {
124+
async function wizardClassProperties(): Promise<Array<{ name: string, visibility: string, type: string }>> {
127125
let properties = [];
128126

129127
let input = await vscode.window.showInputBox({
@@ -139,36 +137,93 @@ async function wizardProperties(): Promise<Array<{ name: string, visibility: str
139137
let visibility = await vscode.window.showQuickPick(
140138
acceptedVisibilities,
141139
{
142-
placeHolder: "Select the visibility of the property"
140+
placeHolder: `Select the visibility of the "${input}" property`
143141
}
144142
);
145143
if (!visibility) {
146144
visibility = "private";
147145
}
148146

149147
let type = await vscode.window.showInputBox({
150-
prompt: "Enter the type of the property (int, string, etc.)"
148+
prompt: `Enter the type of the "${input}" property (int, string, etc.)`
151149
});
152150
if (!type) {
153151
type = "string";
154152
}
155153

156-
properties.push({ name: input, visibility: visibility ?? '', type: type ?? '' });
154+
properties.push({ name: input, visibility: visibility || '', type: type || '' });
157155

158156
input = await vscode.window.showInputBox({
159-
prompt: "Enter a property name (press 'Cancel' or leave empty to finish)"
157+
prompt: "Enter another property name (press 'Cancel' or leave empty to finish)"
160158
});
161159
}
162160

163161
return properties;
164162
}
165163

164+
async function generatePhpInterfaceSkeleton(interfaceName: string, namespace: string): Promise<string> {
165+
166+
const methods = await wizardInterfaceMethods();
167+
168+
let declareMethods = [];
169+
for (const method of methods) {
170+
let paramsMethod: Array<string> = [];
171+
for (const param of method.params) {
172+
paramsMethod.push(`${param.type} $${param.name}`);
173+
}
174+
declareMethods.push(` public function ${method.name}(${paramsMethod.join(', ')}): ${method.returnType};`);
175+
}
176+
177+
const skeleton =
178+
`<?php
179+
180+
declare(strict_types=1);
181+
182+
namespace ${namespace};
183+
184+
interface ${interfaceName}
185+
{
186+
${declareMethods.join("\n\n")}
187+
}
188+
`;
189+
190+
return skeleton;
191+
}
192+
193+
async function wizardInterfaceMethods(): Promise<Array<{ name: string, returnType: string, params: Array<{ type: string, name: string }> }>> {
194+
let methods = [];
195+
196+
let methodName = await vscode.window.showInputBox({
197+
prompt: "Enter a method name (press 'Cancel' or leave empty to finish)"
198+
});
199+
200+
while (methodName) {
201+
let params: Array<{ type: string, name: string }> = [];
202+
203+
const returnType = await vscode.window.showInputBox({
204+
prompt: `Enter a return type of "${methodName}" method (default is void)`
205+
});
206+
207+
let paramName = await vscode.window.showInputBox({
208+
prompt: `Enter a parameter name of "${methodName}" method (press 'Cancel' or leave empty to finish)`
209+
});
210+
211+
while (paramName) {
212+
const paramType = await vscode.window.showInputBox({
213+
prompt: `Enter a type of "${paramName}" parameter (int, string, etc.)`
214+
});
215+
params.push({ type: paramType || '', name: paramName });
216+
paramName = await vscode.window.showInputBox({
217+
prompt: `Enter another parameter name of "${methodName}" method (press 'Cancel' or leave empty to finish)`
218+
});
219+
}
220+
221+
methods.push({ name: methodName, returnType: returnType || 'void', params: params });
166222

167-
function capitalizeAndTrim(str: string): string {
168-
const words = str.split(' ');
169-
let result = "";
170-
for (let word of words) {
171-
result += word.charAt(0).toUpperCase() + word.slice(1);
223+
methodName = await vscode.window.showInputBox({
224+
prompt: "Enter another method name (press 'Cancel' or leave empty to finish)"
225+
});
172226
}
173-
return result;
227+
228+
return methods;
174229
}

0 commit comments

Comments
 (0)