Skip to content

Commit

Permalink
Merge a16dfd0 into b04178a
Browse files Browse the repository at this point in the history
  • Loading branch information
MGApcDev committed Sep 23, 2021
2 parents b04178a + a16dfd0 commit 1580bb7
Show file tree
Hide file tree
Showing 7 changed files with 439 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
],
"stopOnEntry": false,
"outFiles": ["${workspaceFolder}/out/test/**/*.js"],
"preLaunchTask": "npm: watch"
"preLaunchTask": "npm: pretest"
}
]
}
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ All notable changes to the "php-docblocker" extension will be documented in this

### Added
- Psalm and Phan annotations - Thanks @imliam
- Aligning of @param and @return - Thanks @MGApcDev
- Added option for param description
- Added option for return description

### Updated
- Fixes issue with multi-line functions that have a trailing comma
Expand Down
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ This extension contributes the following settings:
* `php-docblocker.returnVoid`: set to `false` to turn off the automatic void return type when it can't be determined
* `php-docblocker.extra`: an array of extra tags to add to each DocBlock (These can include tabstops and snippet variables)
* `php-docblocker.useShortNames`: Whether we should use short type names. e.g. bool or boolean
* `php-docblocker.qualifyClassNames`: When adding type hints for class names search namespace use statements and qualify the class
* `php-docblocker.qualifyClassNames`: When adding type hints for class names search namespace use statements and qualify the class
* `php-docblocker.alignParams`: set to `true` to align params vertically and add appropriate spaces after param names
* `php-docblocker.alignReturn`: set to `true` to align return vertically with above params statements, this setting requires align params to also be active
* `php-docblocker.paramDescription`: set to `true` to include a description placeholder for `@param` completions. If you specify a string this will be the default placeholder text
* `php-docblocker.returnDescription`: set to `true` to include a description placeholder for `@param` completions. If you specify a string this will be the default placeholder text
* `php-docblocker.author`: An object containing your default author tag settings
* `php-docblocker.functionTemplate`: See below for how to set up docblock templates
* `php-docblocker.propertyTemplate`: See below for how to set up docblock templates
Expand Down Expand Up @@ -74,7 +78,7 @@ config option per key to add additional control.

#### Configured function template example

In the example below we have added some gap configuration and removed the return tag for our template as well as
In the example below we have added some gap configuration and removed the return tag for our template as well as
changing the default order. This means we'll never have a @return tag and extra comes before the params. It's also
worth pointing out that the gapAfter in the message is the same as setting the gap config option in the main config
to true.
Expand All @@ -93,8 +97,8 @@ to true.

#### Configured function with extra content and placeholders

The example below won't have a return tag and will add in an author tag with correct placeholders depending on
how many options you have. You can put in placeholders by using `###` in place of the tab stop number and it
The example below won't have a return tag and will add in an author tag with correct placeholders depending on
how many options you have. You can put in placeholders by using `###` in place of the tab stop number and it
will be calculated at generation time.

```json
Expand Down
20 changes: 20 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,26 @@
"default": false,
"description": "Fully qualifies any data types used in param and returns by reading the namespaces."
},
"php-docblocker.alignParams": {
"type": "boolean",
"default": false,
"description": "Vertically aligns param types and names with additional spaces."
},
"php-docblocker.alignReturn": {
"type": "boolean",
"default": false,
"description": "Vertically aligns return with above param statements."
},
"php-docblocker.paramDescription": {
"type": ["string", "boolean"],
"default": false,
"description": "Include a description placeholder for @param tags"
},
"php-docblocker.returnDescription": {
"type": ["string", "boolean"],
"default": false,
"description": "Include a description placeholder for @return tags"
},
"php-docblocker.functionTemplate": {
"type": "object",
"default": null,
Expand Down
147 changes: 145 additions & 2 deletions src/doc.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import {workspace, SnippetString, WorkspaceConfiguration} from 'vscode';
import Config from './util/config';

interface MaxParamLength {
type: number,
name: number
}

interface AlignmentSpaces {
prepend: string,
append: string
}

/**
* Represents a comment block.
*
Expand Down Expand Up @@ -54,6 +64,13 @@ export class Doc
this.message = message;
}

/**
* Define indent character for param alignment.
*
* @type {string}
*/
public indentCharacter:string = ' ';

/**
* Set class properties from a standard object
*
Expand Down Expand Up @@ -89,6 +106,9 @@ export class Doc
let extra = Config.instance.get('extra');
let gap = Config.instance.get('gap');
let returnGap = Config.instance.get('returnGap');
let alignParams = Config.instance.get('alignParams');
// Align return is false if align params is not active.
let alignReturn = alignParams ? Config.instance.get('alignReturn') : false;

let returnString = "";
let varString = "";
Expand All @@ -103,13 +123,34 @@ export class Doc

messageString = "\${###" + (this.message != "" ? ':' : '') + this.message + "}";

// Loop through params and find max length of type and name.
let maxParamLength = this.getMaxParamLength(this.params, this.return);

if (this.params.length) {
paramString = "";
this.params.forEach(param => {
if (paramString != "") {
paramString += "\n";
}
paramString += "@param \${###:"+param.type+"} " + param.name.replace('$', '\\$');

let paramType = param.type;
let paramName = param.name.replace('$', '\\$');

let alignmentSpaces = this.getParamAlignmentSpaces(maxParamLength, paramName, paramType);

paramString +=
"@param " +
// Add extra space to align '@param' and '@return'.
(alignReturn ? this.indentCharacter : '') +
"\${###:"+paramType+"} " +
alignmentSpaces.prepend + paramName + alignmentSpaces.append;

let description = Config.instance.get('paramDescription');
if (description === true) {
paramString += "\${###}"
} else if (typeof description == 'string') {
paramString += "\${###:" + description + "}"
}
});
}

Expand All @@ -118,7 +159,15 @@ export class Doc
}

if (this.return && (this.return != 'void' || Config.instance.get('returnVoid'))) {
returnString = "@return \${###:" +this.return + "}";
let alignmentSpaces = this.getReturnAlignmentSpaces(maxParamLength);
returnString = "@return \${###:" +this.return + "}" + alignmentSpaces.append;

let description = Config.instance.get('returnDescription');
if (description === true) {
returnString += "\${###}"
} else if (typeof description == 'string') {
returnString += "\${###:" + description + "}"
}
}

if (Array.isArray(extra) && extra.length > 0) {
Expand Down Expand Up @@ -213,6 +262,100 @@ export class Doc

return this._template;
}

/**
* Get the max param type length and param name length.
*
* @param {Array<Param>} params
* @param {string} returnStatement
* @returns {MaxParamLength}
*/
private getMaxParamLength(params: Array<Param>, returnStatement: string): MaxParamLength
{
let alignParams = Config.instance.get('alignParams');
let alignReturn = alignParams ? Config.instance.get('alignReturn') : false;


let maxParamTypeLength = 0;
let maxParamNameLength = 0;
if (params.length && alignParams) {
params.forEach(param => {
let paramType = param.type;
if (paramType.length > maxParamTypeLength) {
maxParamTypeLength = paramType.length;
}
let paramName = param.name.replace('$', '\\$')
if (paramName.length > maxParamNameLength) {
maxParamNameLength = paramName.length;
}
});
}
// If align return is active, check if it has a longer type.
if (returnStatement && (returnStatement != 'void' || Config.instance.get('returnVoid')) && alignReturn) {
if (returnStatement.length > maxParamTypeLength) {
maxParamTypeLength = returnStatement.length;
}
}

return {
type: maxParamTypeLength,
name: maxParamNameLength
}
}

/**
* Get extra spaces for alignment of params.
*
* @param {MaxParamLength} maxParamLength
* @param {string} paramName
* @param {string} paramType
* @returns {AlignmentSpaces}
*/
private getParamAlignmentSpaces(maxParamLength: MaxParamLength, paramName: string, paramType: string): AlignmentSpaces
{
let alignParams = Config.instance.get('alignParams');
let paramDescription = Config.instance.get('paramDescription');

let prependSpace = '';
let appendSpace = '';
if (alignParams) {
// Append additional spaces on param type and param name.
prependSpace = Array(maxParamLength.type - paramType.length).fill(this.indentCharacter).join('');
// Add 1 to array size, so there is already a space appended for typing comments.
appendSpace = Array(1 + maxParamLength.name - paramName.length).fill(this.indentCharacter).join('');
}

return {
append: paramDescription ? (alignParams ? appendSpace : this.indentCharacter) : '',
prepend: prependSpace
};
}

/**
* Get extra spaces for alignment of return statement.
*
* @param {MaxParamLength} maxParamLength
* @returns {AlignmentSpaces}
*/
private getReturnAlignmentSpaces(maxParamLength: MaxParamLength): AlignmentSpaces
{
let alignParams = Config.instance.get('alignParams');
let alignReturn = alignParams ? Config.instance.get('alignReturn') : false;
let returnDescription = Config.instance.get('returnDescription');

let appendSpace = '';
if (alignReturn) {
appendSpace =
Array(1 + maxParamLength.type - this.return.length).fill(this.indentCharacter).join('') +
Array(maxParamLength.name).fill(this.indentCharacter).join('');
}

return {
append: returnDescription ? (alignReturn ? appendSpace : this.indentCharacter) : '',
prepend: ''
};
}

}

/**
Expand Down
2 changes: 1 addition & 1 deletion test/completions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ suite("Completion tests", () => {
});

map.forEach(testData => {
test("Completion: "+ testData.name, () => {
test("Completion: " + testData.name, () => {
let pos:Position = testPositions[testData.key];
let result:any = completions.provideCompletionItems(
document,
Expand Down

0 comments on commit 1580bb7

Please sign in to comment.