Skip to content

Commit

Permalink
feat: 函数注释支持 python
Browse files Browse the repository at this point in the history
Co-authored-by: ygqygq2 <ygqygq2@qq.com>
  • Loading branch information
ygqygq2 committed Apr 26, 2024
1 parent 7d0ce85 commit b3ee208
Show file tree
Hide file tree
Showing 28 changed files with 462 additions and 29 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.5]

## 新增功能 🌱

- feat: 函数注释支持 python

# [0.2.4]

## 新增功能 🌱
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![Visual Studio Marketplace Version](https://img.shields.io/visual-studio-marketplace/v/ygqygq2.turbo-file-header.svg?color=07c160&label=turbo-file-header&logo=visual-studio-code)](https://marketplace.visualstudio.com/items?itemName=ygqygq2.turbo-file-header)
![Visual Studio Marketplace Installs](https://img.shields.io/visual-studio-marketplace/i/ygqygq2.turbo-file-header)

[中文](README.zh-CN.md)
[中文](README.zh-CN.md) | [Wiki](https://github.com/ygqygq2/turbo-file-header/wiki)

Turbo file header, sets file header information globally or for a project.

Expand Down
2 changes: 1 addition & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Properties:
| 配置 `tags` 在明亮主题 | 明亮主题中的 `tags` 配置 | tagsLight | `[]` |
| 配置 `tags` 在暗黑主题 | 暗黑主题中的 `tags` 配置 | tagsDark | `[]` |

**注意e**:
**注意**:

- `include``exclude` 是为了控制文件头影响范围,`addFileheader` 命令不受它们影响。
- `author` 包含用户名/邮箱,如果文件被 VCS 追踪,将从 VCS 中获取用户信息,否则将使用备用用户名/邮箱.
Expand Down
2 changes: 1 addition & 1 deletion 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.4",
"version": "0.2.5",
"icon": "resources/icons/icon.png",
"repository": {
"type": "git",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def funcName () -> str:
return "test"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"""
* @description
* @return default {str}
"""
def funcName () -> str:
return "test"
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def funcName ():
return "test"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"""
* @description
* @return default {auto}
"""
def funcName ():
return "test"
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def add(a='a', **kwargs) -> Union[int, float]:
return a + b
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""
* @description
* @return default {Union[int, float]}
* @param [a='a'] {any}
* @param [kwargs] {any}
"""
def add(a='a', **kwargs) -> Union[int, float]:
return a + b
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* @description
* @return default {int}
* @param String {a}
* @param int {b}
*/
public int func(String a, int b) {
System.out.println("test");
return 1;
}
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
@@ -0,0 +1,8 @@
"""
* @description
* @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
1 change: 1 addition & 0 deletions sampleWorkspace/test.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
{ "path": "function-comment-for-ts" },
{ "path": "function-comment-for-go" },
{ "path": "function-comment-for-java" },
{ "path": "function-comment-for-python" },
{ "path": "workspace" },
],
"settings": {},
Expand Down
4 changes: 2 additions & 2 deletions src/fileheader/FileheaderManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ export class FileheaderManager {
);

if (functionCommentInfo) {
const originFunctionComment = generateFunctionComment(originFunctionInfo, true);
const functionComment = generateFunctionComment(functionCommentInfo);
const originFunctionComment = generateFunctionComment(comments, originFunctionInfo, true);
const functionComment = generateFunctionComment(comments, functionCommentInfo);
// 函数注释没有变化
if (originFunctionComment === functionComment) {
logger.info('Not need update function comment:', document.uri.fsPath);
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 { PythonParser } from './PythonProvider';
import { TypescriptParser } from './TypescriptProvider';

export class FunctionParserLoader {
Expand All @@ -29,6 +30,7 @@ export class FunctionParserLoader {
javascriptreact: JavascriptParser,
go: GoParser,
java: JavaParser,
python: PythonParser,
};

public async loadParser(languageId: string): Promise<FunctionParamsParser | null> {
Expand Down
4 changes: 0 additions & 4 deletions src/function-params-parser/GoProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,6 @@ export class GoParser extends FunctionParamsParser {
const line = document.lineAt(i);
functionDefinition += line.text + '\n';

if (line.text.includes('=>') && !line.text.match(/=>\s*{/)) {
break;
}

for (const char of line.text) {
if (char === '(') {
parenthesisCount++;
Expand Down
6 changes: 1 addition & 5 deletions src/function-params-parser/JavaProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { escapeRegexString } from '@/utils/str';

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

function matchNormalFunction(
Expand Down Expand Up @@ -113,10 +113,6 @@ export class JavaParser extends FunctionParamsParser {
const line = document.lineAt(i);
functionDefinition += line.text + '\n';

if (line.text.includes('=>') && !line.text.match(/=>\s*{/)) {
break;
}

for (const char of line.text) {
if (char === '(') {
parenthesisCount++;
Expand Down
157 changes: 157 additions & 0 deletions src/function-params-parser/PythonProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
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 './python-splitParams';
import { FunctionParamsInfo, ParamsInfo, ReturnInfo } from './types';

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

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

const match = functionPattern.exec(functionDefinition);

if (match) {
matched = true;
const returnTypeStr = match[3] ? match[3].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 = 'Any' } = languageSettings;
let returnType: ReturnInfo = {
[defaultReturnName]: { type: defaultReturnType, description: '' },
};
let matched = false;
let params: ParamsInfo = {};

const matchers = [matchNormalFunction];

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 PythonParser 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; // 小括号计数
let colonDetected = false; // 函数冒号检测

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--;
} else if (char === ':' && parenthesisCount === 0) {
colonDetected = true;
}
}

if (bracketCount === 0 && parenthesisCount === 0 && colonDetected) {
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 === '*/') {
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),
};
}
}
4 changes: 3 additions & 1 deletion src/function-params-parser/go-splitParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ export function splitParams(
bracketCount++;
} else if (char === ')' || char === ']' || char === '}' || char === '>') {
bracketCount--;
} else if (
}

if (
(char === ',' && bracketCount === 0) ||
(i === paramsStr.length - 1 && bracketCount === 0)
) {
Expand Down
4 changes: 3 additions & 1 deletion src/function-params-parser/java-splitParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ export function splitParams(
bracketCount++;
} else if (char === ')' || char === ']' || char === '}' || char === '>') {
bracketCount--;
} else if (
}

if (
(char === ',' && bracketCount === 0) ||
(i === paramsStr.length - 1 && bracketCount === 0)
) {
Expand Down
47 changes: 47 additions & 0 deletions src/function-params-parser/python-splitParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { LanguageFunctionCommentSettings } from '@/typings/types';

import { ParamsInfo } from './types';

export function splitParams(
paramsStr: string,
languageSettings: LanguageFunctionCommentSettings,
): ParamsInfo {
const { defaultParamType = 'Any', defaultReturnName = 'default' } = languageSettings;
let bracketCount = 0;
let paramStartIndex = 0;
let defaultCount = 0;
const params: ParamsInfo = {};
for (let i = 0; i < paramsStr?.length; i++) {
const char = paramsStr[i];
if (char === '(' || char === '[' || char === '{' || char === '<') {
bracketCount++;
} else if (char === ')' || char === ']' || char === '}' || char === '>') {
bracketCount--;
}

if (
(char === ',' && bracketCount === 0) ||
(i === paramsStr.length - 1 && bracketCount === 0)
) {
const paramStr = paramsStr
.slice(paramStartIndex, i === paramsStr.length - 1 ? i + 1 : i)
.trim();

const paramPattern = /^(\*\*|\*)?(\w+)?\s*(:\s*(.*?))?(=\s*(.*))?$/;
const match = paramPattern.exec(paramStr);
if (match) {
const name =
match[2] ||
(defaultCount > 0 ? `${defaultReturnName}${defaultCount++}` : defaultReturnName);
const type = match[4] || defaultParamType;
const optional = match[1] || match[6] ? { optional: true } : {};
const defaultValue = match[6] ? { defaultValue: match[6] } : {};

params[name] = { type, description: '', ...optional, ...defaultValue };
}
paramStartIndex = i + 1;
}
}

return params;
}
4 changes: 3 additions & 1 deletion src/function-params-parser/ts-splitParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ export function splitParams(
bracketCount++;
} else if (char === ')' || char === ']' || char === '}' || char === '>') {
bracketCount--;
} else if (
}

if (
(char === ',' && bracketCount === 0) ||
(i === paramsStr.length - 1 && bracketCount === 0)
) {
Expand Down
Loading

0 comments on commit b3ee208

Please sign in to comment.