Skip to content

Commit

Permalink
feat: 函数注释支持 php
Browse files Browse the repository at this point in the history
Co-authored-by: ygqygq2 <ygqygq2@qq.com>
  • Loading branch information
ygqygq2 committed Apr 28, 2024
1 parent f13f37e commit 360416c
Show file tree
Hide file tree
Showing 23 changed files with 344 additions and 17 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to the "turbo-file-header" extension will be documented in this file.

# [0.2.6]

## 新增功能 🌱

- feat: 函数注释支持 php

# [0.2.5]

## 新增功能 🌱
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "turbo-file-header",
"displayName": "Turbo File Header",
"description": "%description%",
"version": "0.2.5",
"version": "0.2.6",
"icon": "resources/icons/icon.png",
"repository": {
"type": "git",
Expand Down Expand Up @@ -337,7 +337,7 @@
},
"defaultParamType": {
"type": "string",
"default": "any",
"default": "",
"description": "%turboFileHeader.functionComment.languagesSettings.items.properties.defaultParamType.description%"
},
"typesUsingDefaultReturnType": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function funcName (): String {
return "test"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* @description
* @return default {String}
*/
function funcName (): String {
return "test"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function funcName () {
return "test"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* @description
* @return default {auto}
*/
function funcName () {
return "test"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function funcName(int $a, $b = 5, ...$rest): int {
return a + b;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* @description
* @return default {int}
* @param $a {int}
* @param [$b=5] {any}
* @param [$rest] {any}
*/
function funcName(int $a, $b = 5, ...$rest): int {
return a + b;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function funcName(int $a, int $b): int {
return a + b;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* @description
* @return default {int}
* @param $a {int}
* @param $b {int}
*/
function funcName(int $a, int $b): int {
return a + b;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
function funcName(int $a, int $b) {
return a + b;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* @description
* @return default {auto}
* @param $a {int}
* @param $b {int}
*/
function funcName(int $a, int $b) {
return a + b;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def add(a: Union[int, float], b: Union[int, float]) -> Union[int, float]:
return a + b
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
/**
"""
* @description
* @return default {int}
* @param String {a}
* @param int {b}
*/
public int func(String a, int b) {
System.out.println("test");
return 1;
}
* @return default {Union[int, float]}
* @param a {Union[int, float]}
* @param b {Union[int, float]}
"""
def add(a: Union[int, float], b: Union[int, float]) -> Union[int, float]:
return a + b
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
def add(a: Union[int, float], b: Union[int, float]) -> Union[int, float]:
def add(a: Union[int, float], b: Union[int, float]):
return a + b
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""
* @description
* @return default {Union[int, float]}
* @return default {auto}
* @param a {Union[int, float]}
* @param b {Union[int, float]}
"""
def add(a: Union[int, float], b: Union[int, float]) -> Union[int, float]:
def add(a: Union[int, float], b: Union[int, float]):
return a + b
1 change: 1 addition & 0 deletions sampleWorkspace/test.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
{ "path": "function-comment-for-go" },
{ "path": "function-comment-for-java" },
{ "path": "function-comment-for-python" },
{ "path": "function-comment-for-php" },
{ "path": "workspace" },
],
"settings": {},
Expand Down
7 changes: 4 additions & 3 deletions src/function-params-parser/FunctionParamsParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ export abstract class FunctionParamsParser {
mergedParams[key] = {
// 因为默认值无法确认类型,所以以用户修改的类型为准
type:
(params[key]?.defaultValue ? paramsInfo[key]?.type : params[key].type) ??
params[key].type,
(params[key]?.defaultValue && paramsInfo[key]?.defaultValue
? paramsInfo[key]?.type
: params[key].type) ?? params[key].type,
description: paramsInfo[key]?.description || '',
...(params[key]?.optional && { optional: true }),
...(params[key]?.defaultValue && { defaultValue: params[key].defaultValue }),
Expand Down Expand Up @@ -144,7 +145,7 @@ export abstract class FunctionParamsParser {
): FunctionCommentInfo {
const descriptionPattern = /@description\s+(.*)/;
const paramPattern =
/@param\s+(?:\[(\w+)(?:=(.*?))?\]|(\w+))\s*\{((?:[^}]|\}(?!\s*$))*)\}\s*(.*)/;
/@param\s+(?:\[\s*([^=\]]+)(?:=(.*?))?\s*\]|([^=\]]+))\s*\{((?:[^}]|\}(?!\s*$))*)\}\s*(.*)/;
const returnPattern = /@return\s+(?:(\w+)\s*)?\{((?:[^}]|\}(?!\s*$))*)\}\s*(.*)/;

const functionCommentLines = document.getText(range).split('\n');
Expand Down
2 changes: 2 additions & 0 deletions src/function-params-parser/FunctionParserLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { FunctionParamsParser } from './FunctionParamsParser';
import { GoParser } from './GoProvider';
import { JavaParser } from './JavaProvider';
import { JavascriptParser } from './JavascriptProvider';
import { PhpParser } from './PhpProvider';
import { PythonParser } from './PythonProvider';
import { TypescriptParser } from './TypescriptProvider';

Expand All @@ -31,6 +32,7 @@ export class FunctionParserLoader {
go: GoParser,
java: JavaParser,
python: PythonParser,
php: PhpParser,
};

public async loadParser(languageId: string): Promise<FunctionParamsParser | null> {
Expand Down
194 changes: 194 additions & 0 deletions src/function-params-parser/PhpProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
import * as vscode from 'vscode';

import { ConfigManager } from '@/configuration/ConfigManager';
import { logger } from '@/extension';
import { LanguageFunctionCommentSettings } from '@/typings/types';
import { escapeRegexString } from '@/utils/str';

import { extractFunctionParamsString } from './extractFunctionParamsString';
import { FunctionParamsParser } from './FunctionParamsParser';
import { splitParams } from './php-splitParams';
import { FunctionParamsInfo, ParamsInfo, ReturnInfo } from './types';

function matchNormalFunction(
functionDefinition: string,
languageSettings: LanguageFunctionCommentSettings,
): {
matched: boolean;
returnType: ReturnInfo;
params: ParamsInfo;
} {
const { defaultReturnName = 'default', defaultReturnType = 'Null' } = languageSettings;
const returnType: ReturnInfo = {};
let matched = false;
let params: ParamsInfo = {};

// 提取参数括号里的字符串
const functionParamsStr = extractFunctionParamsString(functionDefinition);
const functionParamsRegStr = escapeRegexString(functionParamsStr);
const functionPattern = new RegExp(
`function\\s*([&?]?[a-zA-Z0-9_]+)\\s*\\(${functionParamsRegStr}\\)\\s*(?::\\s*(.*))?\\s*{`,
'm',
);

const match = functionPattern.exec(functionDefinition);

if (match) {
matched = true;
const returnTypeStr = match[2] ? match[2].trim() : defaultReturnType;

returnType[defaultReturnName] = {
type: returnTypeStr,
description: '',
};

params = splitParams(functionParamsStr, languageSettings);
}

return { matched, returnType, params };
}

function matchArrowFunction(
functionDefinition: string,
languageSettings: LanguageFunctionCommentSettings,
): {
matched: boolean;
returnType: ReturnInfo;
params: ParamsInfo;
} {
const { defaultReturnName = 'default', defaultReturnType = 'Null' } = languageSettings;
const returnType: ReturnInfo = {};
let matched = false;
let params: ParamsInfo = {};

// 提取参数括号里的字符串
const functionParamsStr = extractFunctionParamsString(functionDefinition);
const functionParamsRegStr = escapeRegexString(functionParamsStr);
const functionPattern = new RegExp(`fn\\s*\\(${functionParamsRegStr}\\)\\s*=>`, 'm');

const match = functionPattern.exec(functionDefinition);

if (match) {
matched = true;
const returnTypeStr = match[2] ? match[2].trim() : defaultReturnType;

returnType[defaultReturnName] = {
type: returnTypeStr,
description: '',
};

params = splitParams(functionParamsStr, languageSettings);
}

return { matched, returnType, params };
}

/**
* @description
* @return default {auto}
*/
function matchFunction(
functionDefinition: string,
languageSettings: LanguageFunctionCommentSettings,
): { matched: boolean; returnType: ReturnInfo; params: ParamsInfo } {
const { defaultReturnName = 'default', defaultReturnType = 'Null' } = languageSettings;
let returnType: ReturnInfo = {
[defaultReturnName]: { type: defaultReturnType, description: '' },
};
let matched = false;
let params: ParamsInfo = {};

const matchers = [matchNormalFunction, matchArrowFunction];

for (const matcher of matchers) {
const result = matcher(functionDefinition, languageSettings);
if (result.matched) {
matched = result.matched;
params = result.params;
returnType = result.returnType;
break;
}
}

return { matched, returnType, params };
}

export class PhpParser extends FunctionParamsParser {
constructor(configManager: ConfigManager, languageId: string) {
super(configManager, languageId);
}

private getFunctionString(document: vscode.TextDocument, startLine: number) {
let functionDefinition = '';
let bracketCount = 0; // 大括号计数
let parenthesisCount = 0; // 小括号计数

for (let i = startLine; i < document.lineCount; i++) {
const line = document.lineAt(i);
functionDefinition += line.text + '\n';

for (const char of line.text) {
if (char === '(') {
parenthesisCount++;
} else if (char === ')') {
parenthesisCount--;
} else if (char === '{') {
bracketCount++;
} else if (char === '}') {
bracketCount--;
}
}

if (bracketCount === 0 && parenthesisCount === 0) {
break;
}
}

return functionDefinition;
}

public getFunctionParamsAtCursor(
activeEditor: vscode.TextEditor,
languageSettings: LanguageFunctionCommentSettings = this.languageSettings,
): FunctionParamsInfo {
let functionParams: ParamsInfo = {};
let matchedFunction = false;
let returnType: ReturnInfo = {};
const document = activeEditor.document;
const cursorLine = activeEditor.selection.start.line;
let startLine = cursorLine;
// 如果光标所在行为空行或者注释,则从下一行开始
const cursorLineText = document.lineAt(cursorLine).text.trim();
if (
cursorLineText === '' ||
cursorLineText === '//' ||
cursorLineText === '#' ||
cursorLineText === '*/'
) {
startLine = cursorLine + 1;
}

const functionDefinition = this.getFunctionString(document, startLine);
const {
matched,
returnType: returnTypeTmp,
params,
} = matchFunction(functionDefinition, languageSettings);
if (matched) {
matchedFunction = true;
returnType = returnTypeTmp;
functionParams = params;
}

if (!matchFunction) {
logger.info(vscode.l10n.t('No function found at the cursor'));
}

return {
matchedFunction,
returnType,
params: functionParams,
insertPosition: new vscode.Position(startLine, 0),
};
}
}
Loading

0 comments on commit 360416c

Please sign in to comment.