Skip to content

Commit

Permalink
feat: copy over PR #313 due to unrelated histories and adjust logic
Browse files Browse the repository at this point in the history
  • Loading branch information
kkoomen committed Jul 23, 2022
1 parent 8f9ca3e commit a8eceb6
Show file tree
Hide file tree
Showing 16 changed files with 808 additions and 4 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Is your favorite doc standard not supported?
| :white_check_mark: | C | [Doxygen][doxygen], [KernelDoc][kerneldoc] |
| :white_check_mark: | Bash | [Google][sh-google] |
| :white_check_mark: | Rust | [RustDoc][rustdoc] |
| :white_check_mark: | C-Sharp | [XMLDoc][xmldoc] |

# Getting started

Expand Down Expand Up @@ -155,7 +156,8 @@ Here is the full list of available doc standards per filetype:
| `g:doge_doc_standard_cpp` | `'doxygen_javadoc'` | `'doxygen_javadoc'`, `'doxygen_javadoc_no_asterisk'`, `'doxygen_javadoc_banner'`, `'doxygen_qt'`, `'doxygen_qt_no_asterisk'` |
| `g:doge_doc_standard_c` | `'doxygen_javadoc'` | `'kernel_doc'`, `'doxygen_javadoc'`, `'doxygen_javadoc_no_asterisk'`, `'doxygen_javadoc_banner'`, `'doxygen_qt'`, `'doxygen_qt_no_asterisk'` |
| `g:doge_doc_standard_sh` | `'google'` | `'google'` |
| `g:doge_doc_standard_rs` | `'rustdoc'` | `'rustdoc'` |
| `g:doge_doc_standard_rs` | `'rustdoc'` | `'rustdoc'` |
| `g:doge_doc_standard_cs` | `'xmldoc'` | `'xmldoc'` |

## Options

Expand Down
59 changes: 59 additions & 0 deletions ftplugin/cs.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
" ==============================================================================
" The PHP documentation should follow the 'phpdoc' conventions.
" see https://www.phpdoc.org
" ==============================================================================

let s:save_cpo = &cpoptions
set cpoptions&vim

let b:doge_parser = 'cs'
let b:doge_insert = 'above'

let b:doge_supported_doc_standards = doge#buffer#get_supported_doc_standards(['csxml'])
let b:doge_doc_standard = doge#buffer#get_doc_standard('cs')
let b:doge_patterns = doge#buffer#get_patterns()

" ==============================================================================
"
" Define the doc standards.
"
" ==============================================================================

call doge#buffer#register_doc_standard('csxml', [
\ {
\ 'nodeTypes': ['method_declaration', 'operator_declaration', 'delegate_declaration'],
\ 'parameters': {
\ 'format': '<param name="{name}">!description</param>'
\ },
\ 'template': [
\ '/// <summary>',
\ '/// !description',
\ '/// </summary>',
\ '%(parameters|/// {parameters})%',
\ '%(hasReturn|/// <returns>!description</returns>)%',
\ ],
\ },
\ {
\ 'nodeTypes': ['constructor_declaration'],
\ 'parameters': {
\ 'format': '<param name="{name}">!description</param>'
\ },
\ 'template': [
\ '/// <summary>',
\ '/// !description',
\ '/// </summary>',
\ '%(parameters|/// {parameters})%',
\ ],
\ },
\ {
\ 'nodeTypes': ['class_declaration', 'variable_declaration', 'property_declaration', 'field_declaration', 'enum_declaration'],
\ 'template': [
\ '/// <summary>',
\ '/// !description',
\ '/// </summary>',
\ ],
\ },
\])

let &cpoptions = s:save_cpo
unlet s:save_cpo
25 changes: 23 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"tree-sitter": "^0.20.0",
"tree-sitter-bash": "^0.19.0",
"tree-sitter-c": "^0.20.1",
"tree-sitter-c-sharp": "^0.19.1",
"tree-sitter-cpp": "^0.20.0",
"tree-sitter-java": "^0.19.1",
"tree-sitter-php": "^0.19.0",
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export enum Language {
TYPESCRIPT = 'typescript',
PYTHON = 'python',
C = 'c',
CSHARP = 'cs',
CPP = 'cpp',
BASH = 'bash',
RUBY = 'ruby',
Expand Down
2 changes: 2 additions & 0 deletions src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Bash from 'tree-sitter-bash';
import C from 'tree-sitter-c';
import CPP from 'tree-sitter-cpp';
import CSharp from 'tree-sitter-c-sharp';
import Java from 'tree-sitter-java';
import Lua from '@muniftanjim/tree-sitter-lua';
import PHP from 'tree-sitter-php';
Expand All @@ -18,6 +19,7 @@ export function loadParserPackage(language: ValueOf<Language>): any {
[Language.PYTHON]: Python,
[Language.C]: C,
[Language.CPP]: CPP,
[Language.CSHARP]: CSharp,
[Language.BASH]: Bash,
[Language.RUBY]: Ruby,
[Language.LUA]: Lua,
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const lineNumber: number = Math.max(0, Number(args.shift()) - 1);
const nodeTypes: string[] = args;

const languageParser = loadParserPackage(language);

if (languageParser) {
const parser = new Parser();
parser.setLanguage(languageParser);
Expand Down
16 changes: 15 additions & 1 deletion src/parsers/base-parser.service.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
import { SyntaxNode } from 'tree-sitter';

export class BaseParserService {
/**
* The result that will be printed for vim to handle later.
*/
protected result: Record<string, any> = {};

/**
* Whether the parsing process is done or not.
*/
protected done = false;

/**
* Force an empty object to be printed. Can be useful if you want to render a
* template without any tokens.
*/
protected forceOutput = false;

public output(): void {
if (Object.keys(this.result).length > 0) {
if (this.forceOutput) {
console.log('{}');
} else if (Object.keys(this.result).length > 0) {
console.log(JSON.stringify(this.result));
}
}
Expand Down
97 changes: 97 additions & 0 deletions src/parsers/cs.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { SyntaxNode } from 'tree-sitter';
import { BaseParserService } from './base-parser.service';
import { CustomParserService } from './custom-parser-service.interface';

enum NodeType {
METHOD_DECLARATION = 'method_declaration',
CLASS_DECLARATION = 'class_declaration',
VARIABLE_DECLARATION = 'variable_declaration',
PROPERTY_DECLARATION = 'property_declaration',
CONSTRUCTOR_DECLARATION = 'constructor_declaration',
CONSTANT_DECLARATION = 'field_declaration',
OPERATOR_DECLARATION = 'operator_declaration',
DELEGATE_DECLARATION = 'delegate_declaration',
ENUM_DECLARATION = 'enum_declaration'
}

export class CSharpParserService extends BaseParserService implements CustomParserService {
constructor(
readonly rootNode: SyntaxNode,
private readonly lineNumber: number,
private readonly nodeTypes: string[],
) {
super();
}

public traverse(node: SyntaxNode): void {
if (
node.startPosition.row !== this.lineNumber
|| !this.nodeTypes.includes(node.type)
|| this.done !== false
) {
if (node.childCount > 0) {
node.children.forEach((childNode: SyntaxNode) => {
this.traverse(childNode);
});
}

return;
}

switch (node.type) {
case NodeType.METHOD_DECLARATION:
case NodeType.DELEGATE_DECLARATION:
case NodeType.OPERATOR_DECLARATION:
this.result = { parameters: [], hasReturn: true };
this.runNodeParser(this.parseFunction, node);
break;

case NodeType.CONSTRUCTOR_DECLARATION:
this.result = { parameters: [] };
this.runNodeParser(this.parseConstructor, node);
break;

case NodeType.VARIABLE_DECLARATION:
case NodeType.ENUM_DECLARATION:
case NodeType.CONSTANT_DECLARATION:
case NodeType.PROPERTY_DECLARATION:
case NodeType.CLASS_DECLARATION:
this.result = {};
this.forceOutput = true;
break;


default:
console.error(`Unable to handle node type: ${node.type}`);
break;
}
}

private parseFunction(node: SyntaxNode): void {
node.children.forEach((childNode: SyntaxNode) => {
if (childNode.type === 'void_keyword') {
this.result.hasReturn = false;
} else if (childNode.type === 'parameter_list') {
this.extractParamsFromList(childNode);
}
});
}

private parseConstructor(node: SyntaxNode): void {
node.children.forEach((childNode: SyntaxNode) => {
if (childNode.type === 'parameter_list') {
this.extractParamsFromList(childNode);
}
});
}

private extractParamsFromList(parameterList: SyntaxNode) {
parameterList.children.forEach((parameterNode: SyntaxNode) => {
if (parameterNode.type === 'parameter') {
this.result.parameters.push({
name: parameterNode.children?.filter((n: SyntaxNode) => n.type === 'identifier').pop()?.text
});
}
});
}
}
5 changes: 5 additions & 0 deletions src/parsers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ValueOf } from '../types';
import { BashParserService } from './bash.service';
import { CParserService } from './c.service';
import { CppParserService } from './cpp.service';
import { CSharpParserService } from './cs.service';
import { JavaParserService } from './java.service';
import { LuaParserService } from './lua.service';
import { PhpParserService } from './php.service';
Expand All @@ -18,6 +19,7 @@ export type ParserService =
| PythonParserService
| CParserService
| CppParserService
| CSharpParserService
| BashParserService
| RubyParserService
| LuaParserService
Expand All @@ -44,6 +46,9 @@ export function getParserService(
case Language.CPP:
return new CppParserService(...args);

case Language.CSHARP:
return new CSharpParserService(...args);

case Language.BASH:
return new BashParserService(...args);

Expand Down
1 change: 1 addition & 0 deletions src/vim-doge.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ declare module 'tree-sitter-php';
declare module 'tree-sitter-typescript/tsx';
declare module 'tree-sitter-python';
declare module 'tree-sitter-c';
declare module 'tree-sitter-c-sharp';
declare module 'tree-sitter-cpp';
declare module 'tree-sitter-bash';
declare module 'tree-sitter-ruby';
Expand Down
53 changes: 53 additions & 0 deletions test/filetypes/cs/class-constructor.vader
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# ==============================================================================
# Construcor without params
# ==============================================================================
Given cs (constructor without params):
public class MyClass
{
public MyClass()
{
}
}

Do (run doge):
:3\<CR>
\<C-d>

Expect cs (constructor with summary only):
public class MyClass
{
/// <summary>
/// [TODO:description]
/// </summary>
public MyClass()
{
}
}

# ==============================================================================
# Constructor with params
# ==============================================================================
Given cs (constructor without params):
public class MyClass
{
public MyClass(string arg1, MyClass arg2)
{
}
}

Do (run doge):
:3\<CR>
\<C-d>

Expect cs (constructor with summary only):
public class MyClass
{
/// <summary>
/// [TODO:description]
/// </summary>
/// <param name="arg1">[TODO:description]</param>
/// <param name="arg2">[TODO:description]</param>
public MyClass(string arg1, MyClass arg2)
{
}
}
Loading

0 comments on commit a8eceb6

Please sign in to comment.