Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supported variable docblock #229

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,26 @@
All notable changes to the "php-docblocker" extension will be documented in this file.

## [Unreleased]
- Supported variable docblock
```php
# Example

/** @var int $var */
$var = 1;

/** @var stdClass $object */
$object = new stdClass;

/** @var \Closure $callback */
$callback = function () {};
$callback = fn () => 1;

/** @var [type] $item */
foreach ($data as $item) {}

/** @var [type] $item */
while ($item = array_pop($data)) {}
```

## [2.7.0] - 2022-02-11
- Allow configuration of default type
Expand Down
24 changes: 24 additions & 0 deletions src/block/ForeachBlock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Doc, Param } from "../doc";
import VariableBlock from "./VariableBlock";

/**
* Represents an var block for `foreach`
*/
export default class ForeachBlock extends VariableBlock
{

/**
* @inheritdoc
*/
protected pattern:RegExp = /^\s*foreach\s*\(.*?as\s+(\$[a-z_][a-z0-9_]*\s*=>\s*)?(\$[a-z_][a-z0-9_]*)\s*\)/im;

/**
* @inheritdoc
*/
public parse():Doc
{
let params = this.match();
return this.parseVar(params[2]);
}
}

46 changes: 46 additions & 0 deletions src/block/VariableBlock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Block } from "../block";
import { Doc, Param } from "../doc";
import Config from "../util/config";
import TypeUtil from "../util/TypeUtil";

/**
* Represents an var block
*/
export default class VariableBlock extends Block
{

/**
* @inheritdoc
*/
protected pattern:RegExp = /^\s*(\$[a-z0-9_]+)\s*\=?\s*([^;]*)/im;

/**
* @inheritdoc
*/
public parse():Doc
{
let params = this.match();
return this.parseVar(params[1], params[2]);
}

/**
* parse
*
* @param key e.g.`$key`
* @param value
* @returns
*/
protected parseVar(key: string, value: any=undefined): Doc
{
let doc = new Doc(key.substring(1));
if (value) {
doc.var = TypeUtil.instance.getTypeFromValue(value);
} else {
doc.var = TypeUtil.instance.getDefaultType();
}
doc.inline = true;

return doc;
}
}

24 changes: 24 additions & 0 deletions src/block/WhileBlock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Doc, Param } from "../doc";
import VariableBlock from "./VariableBlock";

/**
* Represents an var block for `while`
*/
export default class WhileBlock extends VariableBlock
{

/**
* @inheritdoc
*/
protected pattern:RegExp = /^\s*while\s*\((\$[a-z0-9_]+)\s*=(?!=)/im;

/**
* @inheritdoc
*/
public parse():Doc
{
let params = this.match();
return this.parseVar(params[1]);
}
}

34 changes: 24 additions & 10 deletions src/doc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ export class Doc
*/
public params:Array<Param> = [];

/**
* Doc inline
*
* Currently only used for variable block.
*/
public inline:boolean = false;

/**
* Return tag
*
Expand Down Expand Up @@ -87,6 +94,9 @@ export class Doc
if (input.message !== undefined) {
this.message = input.message;
}
if (input.inline !== undefined) {
this.inline = input.inline;
}
if (input.params !== undefined && Array.isArray(input.params)) {
input.params.forEach(param => {
this.params.push(new Param(param.type, param.name));
Expand Down Expand Up @@ -222,22 +232,26 @@ export class Doc
templateArray.pop();
}

let templateString:string = templateArray.join("\n");
let templateString: string;
if (this.inline && templateArray.length === 3) {
templateString = "/** " + templateArray[2] + " \$" + templateArray[0] + " \${###} */";
} else {
templateString = templateArray.join("\n");
templateString = templateString.replace(/^$/gm, " *");
templateString = templateString.replace(/^(?!(\s\*|\/\*))/gm, " * $1");
if (Config.instance.get('autoClosingBrackets') == "never") {
templateString = "\n" + templateString + "\n */";
} else {
templateString = "/**\n" + templateString + "\n */";
}
}

let stop = 0;
templateString = templateString.replace(/###/gm, function():string {
stop++;
return stop + "";
});

templateString = templateString.replace(/^$/gm, " *");
templateString = templateString.replace(/^(?!(\s\*|\/\*))/gm, " * $1");

if (Config.instance.get('autoClosingBrackets') == "never") {
templateString = "\n" + templateString + "\n */";
} else {
templateString = "/**\n" + templateString + "\n */";
}

let snippet = new SnippetString(templateString);

return snippet;
Expand Down
18 changes: 18 additions & 0 deletions src/documenter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import FunctionBlock from "./block/function";
import Property from "./block/property";
import Class from "./block/class";
import {Doc, Param} from "./doc";
import VariableBlock from "./block/VariableBlock";
import ForeachBlock from "./block/ForeachBlock";
import WhileBlock from "./block/WhileBlock";

/**
* Check which type of docblock we need and instruct the components to build the
Expand Down Expand Up @@ -59,6 +62,21 @@ export default class Documenter
return cla.parse().build();
}

let variable = new VariableBlock(this.targetPosition, this.editor);
if (variable.test()) {
return variable.parse().build();
}

let foreach = new ForeachBlock(this.targetPosition, this.editor);
if (foreach.test()) {
return foreach.parse().build();
}

let while_ = new WhileBlock(this.targetPosition, this.editor);
if (while_.test()) {
return while_.parse().build();
}

return new Doc().build(true);
}
}
39 changes: 34 additions & 5 deletions src/util/TypeUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ export default class TypeUtil {
return 'integer';
}
return 'int';
case 'real':
case 'double':
return 'float';
case 'unset':
return 'null';
default:
return name;
}
Expand All @@ -159,15 +164,13 @@ export default class TypeUtil {
*/
public getTypeFromValue(value:string):string
{
let result:Array<string>;

// Check for bool
// Check for bool `false` `true` `!exp`
if (value.match(/^\s*(false|true)\s*$/i) !== null || value.match(/^\s*\!/i) !== null) {
return this.getFormattedTypeByName('bool');
}

// Check for int
if (value.match(/^\s*([\d-]+)\s*$/) !== null) {
// Check for int `-1` `1` `1_000_000`
if (value.match(/^\s*(\-?\d[\d_]*)\s*$/) !== null) {
return this.getFormattedTypeByName('int');
}

Expand All @@ -176,6 +179,11 @@ export default class TypeUtil {
return 'float';
}

// Check for float `.1` `1.1` `-1.1` `0.1_000_1`
if (value.match(/^\s*(\-?[\d_\.]*)\s*$/) !== null) {
return 'float';
}

// Check for string
if (value.match(/^\s*(["'])/) !== null || value.match(/^\s*<<</) !== null) {
return 'string';
Expand All @@ -185,6 +193,27 @@ export default class TypeUtil {
if (value.match(/^\s*(array\(|\[)/) !== null) {
return 'array';
}

// Check for class
var match = value.match(/^\s*new\s+([a-z0-9_\\\|]+)/i);
if (match) {
if (match[1] === 'class') {
return 'object';
}
return match[1];
}

// Check for closure
var match = value.match(/^\s*function\s*\(/i) || value.match(/^\s*fn\s*\(/i);
if (match) {
return '\\Closure';
}

// Check for type casting
var match = value.match(/^\s*\(\s*(int|integer|bool|boolean|float|double|real|string|array|object|unset)\s*\)/i);
if (match) {
return this.getFormattedTypeByName(match[1]);
}

return this.getDefaultType();
}
Expand Down
9 changes: 7 additions & 2 deletions test/completions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ suite("Completion tests", () => {
});

map.forEach(testData => {
if (testData.name === undefined) {
testData.name = testData.key;
}
test("Completion: " + testData.name, () => {
let pos:Position = testPositions[testData.key];
let result:any = completions.provideCompletionItems(
Expand All @@ -31,10 +34,12 @@ suite("Completion tests", () => {

let matched:Array<string> = [];
result.forEach(data => {
matched.push(data.label);
matched.push(data.insertText.value);
});
let actual = matched.join("\n");
let expected = testData.result.join("\n");

assert.deepEqual(testData.result, matched);
assert.deepEqual(actual, expected);
});
});
});
20 changes: 20 additions & 0 deletions test/fixtures/completions.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,25 @@ class Blah
{
}

////=> variable
/**
$var = null;

////=> foreach
/**
foreach ([] as $key => $value) {

////=> foreach-with-key
/**
foreach ([] as $value) {

////=> while
/**
while ($value = array_shift($arrs)) {

////=> while-no-var
/**
while ($value == true) {

////=> empty
/**
Loading