summaryrefslogtreecommitdiffstats
path: root/src/DocGen/CGen.ts
blob: 5a80ee0fe3438d128b308f2fe068700e58d473e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import { Position, Range, Selection, TextEditor, TextLine, WorkspaceEdit } from "vscode";
import { DoxygenCommands, IDocGen } from "./DocGen";

export default class CGen implements IDocGen {
    protected lineStart: string;
    protected endComment: string;
    protected commandIndicator: string;
    protected spaceAfterCommand: string;
    protected activeEditor: TextEditor;
    protected position: Position;
    protected comment: string;
    protected retVals: string[];
    protected params: string[];

    /**
     * @param  {TextEditor} actEdit Active editor window
     * @param  {Position} cursorPosition Where the cursor of the user currently is
     * @param  {string[]} param The parameter names of the method extracted by the parser
     * @param  {string[]} returnVals The return values extracted by the parser
     */
    public constructor(actEdit: TextEditor, cursorPosition: Position, param: string[], returnVals: string[]) {
        this.activeEditor = actEdit;
        this.position = cursorPosition;
        this.comment = "\n"; // Add the new line after the comment indicator
        this.params = param;
        this.retVals = returnVals;
    }

    /**
     * @inheritdoc
     */
    public GenerateDoc() {
        this.readConfig();
        this.generateComment();

        const oldPos: Position = this.position;

        const active: Position = this.activeEditor.selection.active;
        const anchor: Position = new Position(active.line + 1, active.character); // Start at the next line
        const replaceSelection = new Selection(anchor, active);
        this.activeEditor.edit((editBuilder) => {
            editBuilder.replace(replaceSelection, this.comment); // Insert the comment
        });

        // Set cursor after brief command
        this.setCursor(oldPos.line + 3, oldPos.character);
        const newSelectActive = new Position(oldPos.line + 3, oldPos.character + DoxygenCommands.detailed.length);
        const newSelectPos = new Position(oldPos.line + 3, oldPos.character);
        this.activeEditor.selection = new Selection(newSelectPos, newSelectActive);
    }

    /***************************************************************************
                                    Implementation
     ***************************************************************************/

    protected readConfig() {
        this.lineStart = " * "; // TODO: make this customizable
        this.endComment = "*/"; // TODO: make this customizable
        this.commandIndicator = "@"; // TODO: make this customizable
        this.spaceAfterCommand = " "; // TODO: make this customizable
    }

    protected indentLine(commentLine: string): string {
        const line: TextLine = this.activeEditor.document.lineAt(this.activeEditor.selection.start.line);
        const lineTxt: string = line.text;
        let stringToIndent: string = "";
        // Find indentation from previous line
        for (let i = 0; i < line.firstNonWhitespaceCharacterIndex; i++) {
            if (lineTxt.charAt(i) === "\t") {
                stringToIndent = stringToIndent + "\t";
            } else if (lineTxt.charAt(i) === " ") {
                stringToIndent = stringToIndent + " ";
            }
        }
        const textToInsert = stringToIndent + commentLine;
        return textToInsert;
    }

    protected generateBrief() {
        let line: string = "";
        line += this.lineStart;
        line += this.commandIndicator;
        line += DoxygenCommands.brief;
        line += this.spaceAfterCommand;
        this.comment += this.indentLine(line);
    }

    protected generateDetailed() {
        let line: string = "";
        line += this.lineStart;
        line += "\n";
        this.comment += this.indentLine(line);
        line = this.lineStart;
        line += DoxygenCommands.detailed + "\n";
        this.comment += this.indentLine(line);
        line = this.lineStart;
        this.comment += this.indentLine(line);
    }

    protected generateParams() {
        let line: string = "";

        this.params.forEach((element: string) => {
            line = this.lineStart;
            line += this.commandIndicator;
            line += DoxygenCommands.param + " "; // TODO: Make this customizable
            line += element + "\n";
            this.comment += this.indentLine(line);
        });
    }

    protected generateReturn() {
        let line: string = "";

        this.retVals.forEach((element: string) => {
            line = this.lineStart;
            line += this.commandIndicator;
            line += DoxygenCommands.return + " "; // TODO: Make this customizable
            line += element + "\n";
            this.comment += this.indentLine(line);
        });
    }

    protected generateEnd() {
        let line: string = " "; // TODO: Make this customizable
        line += this.endComment;
        this.comment += this.indentLine(line);
    }

    protected generateComment() {
        this.generateBrief();
        this.comment += "\n";
        this.generateDetailed();
        this.comment += "\n";
        if (this.params.length !== 0) { // Only if we have parameters
            this.generateParams();
        }
        if (this.retVals.length !== 0) { // Only if we have return values
            if (this.params.length !== 0) {
                const line: string = this.lineStart + "\n";
                this.comment += this.indentLine(line);
            }
            this.generateReturn();
        }
        this.generateEnd();
    }

    protected setCursor(line: number, character: number) {
        const indentLen: number = this.indentLine("").length;
        const move: Selection = new Selection(line, character, line, character);
        this.activeEditor.selection = move;
    }
}