File : ClassDocBuilder.js

1
/*
2
Copyright - 2021 - wwwouaiebe - Contact: https://www.ouaie.be/
3
4
This  program is free software;
5
you can redistribute it and/or modify it under the terms of the
6
GNU General Public License as published by the Free Software Foundation;
7
either version 3 of the License, or any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
GNU General Public License for more details.
13
14
You should have received a copy of the GNU General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
*/
18
/*
19
Changes:
20
    - v1.0.0:
21
        - created
22
Doc reviewed 20211111
23
*/
24
/* ------------------------------------------------------------------------------------------------------------------------- */
25
26
import CommentsDocBuilder from './CommentsDocBuilder.js';
27
import MethodOrPropertyDoc from './MethodOrPropertyDoc.js';
28
import ClassDoc from './ClassDoc.js';
29
30
/* ------------------------------------------------------------------------------------------------------------------------- */
31
/**
32
Build a ClassDoc object for a class
33
*/
34
/* ------------------------------------------------------------------------------------------------------------------------- */
35
36
class ClassDocBuilder {
37
38
    /**
39
    The path between the html file and theConfig.destDir ( something like '../../../', depending of the folders tree )
40
    @type {String}
41
    */
42
43
    #rootPath;
44
45
    /**
46
    The file name ( with the path since theConfig.srcDir ) in witch the current class is declared
47
    @type {String}
48
    */
49
50
    #fileName;
51
52
    /**
53
    A CommentsDocBuilder object
54
    @type {CommentsDocBuilder}
55
    */
56
57
    #commentsDocBuilder;
58
59
    /**
60
    The constructor
61
    */
62
63
    constructor ( ) {
64
        Object.freeze ( this );
65
        this.#commentsDocBuilder = new CommentsDocBuilder ( );
66
    }
67
68
    /**
69
    Build a MethodOrPropertyDoc object from an
70
    [ast node](https://github.com/babel/babel/blob/main/packages/babel-parser/ast/spec.md)
71
    @param {Object} methodOrPropertyNode An ast node of type **ClassPrivateProperty**, **ClassProperty**,
72
    **ClassPrivateMethod** or **ClassMethod**
73
    @return {MethodOrPropertyDoc} The created object
74
    */
75
76
    // eslint-disable-next-line complexity
77
    #buildMethodOrPropertyDoc ( methodOrPropertyNode ) {
78
79
        const methodOrPropertyDoc = new MethodOrPropertyDoc ( );
80
81
        methodOrPropertyDoc.name = methodOrPropertyNode?.key?.name || methodOrPropertyNode?.key?.id?.name;
82
        methodOrPropertyDoc.static = methodOrPropertyNode?.static;
83
        methodOrPropertyDoc.async = methodOrPropertyNode?.async;
84
        methodOrPropertyDoc.kind = methodOrPropertyNode?.kind;
85
        methodOrPropertyDoc.file = this.#fileName;
86
        methodOrPropertyDoc.rootPath = this.#rootPath;
87
        methodOrPropertyDoc.line = methodOrPropertyNode?.loc?.start?.line;
88
        methodOrPropertyDoc.commentsDoc = this.#commentsDocBuilder.build ( methodOrPropertyNode?.leadingComments );
89
90
        if ( methodOrPropertyNode?.params?.length ) {
91
            methodOrPropertyDoc.params = [];
92
            methodOrPropertyNode.params.forEach (
93
                param => { methodOrPropertyDoc.params.push ( param?.name ); }
94
            );
95
        }
96
97
        switch ( methodOrPropertyNode.type ) {
98
        case 'ClassPrivateProperty' :
99
            methodOrPropertyDoc.private = true;
100
            methodOrPropertyDoc.isA = 'property';
101
            break;
102
        case 'ClassProperty' :
103
            methodOrPropertyDoc.private = false;
104
            methodOrPropertyDoc.isA = 'property';
105
            break;
106
        case 'ClassPrivateMethod' :
107
            methodOrPropertyDoc.private = true;
108
            methodOrPropertyDoc.isA = 'method';
109
            break;
110
        case 'ClassMethod' :
111
            methodOrPropertyDoc.private = false;
112
            methodOrPropertyDoc.isA = 'method';
113
            break;
114
        default :
115
            break;
116
        }
117
118
        return Object.freeze ( methodOrPropertyDoc );
119
    }
120
121
    /**
122
    Build a ClassDoc object from an [ast node](https://github.com/babel/babel/blob/main/packages/babel-parser/ast/spec.md)
123
    @param {Object} classDeclarationNode An ast node of type classDeclarationNode
124
    @param {String} fileName The file name with the path since theConfig.srcDir
125
    @return {ClassDoc} The created object
126
    */
127
128
    build ( classDeclarationNode, fileName ) {
129
130
        // Saving the fileName for others methods
131
        this.#fileName = fileName;
132
133
        // Computing rootPath
134
        this.#rootPath = '';
135
        let rootPathCounter = this.#fileName.split ( '/' ).length - 1;
136
        while ( 0 < rootPathCounter ) {
137
            this.#rootPath += '../';
138
            rootPathCounter --;
139
        }
140
141
        // Creating the ClassDoc object
142
        const classDoc = new ClassDoc;
143
        classDoc.name = classDeclarationNode.id.name;
144
        classDoc.file = this.#fileName;
145
        classDoc.rootPath = this.#rootPath;
146
        classDoc.line = classDeclarationNode.loc.start.line;
147
148
        if ( classDeclarationNode?.superClass?.name ) {
149
            classDoc.superClass = classDeclarationNode.superClass.name;
150
        }
151
152
        classDoc.commentsDoc = this.#commentsDocBuilder.build ( classDeclarationNode.leadingComments );
153
154
        // Adding methods and properties
155
        classDeclarationNode.body.body.forEach (
156
            methodOrPropertyNode => {
157
                const methodOrPropertyDoc = this.#buildMethodOrPropertyDoc ( methodOrPropertyNode, this.#fileName );
158
                if ( methodOrPropertyDoc.isA && ! methodOrPropertyDoc?.commentsDoc?.ignore ) {
159
                    classDoc.methodsAndProperties = ( classDoc.methodsAndProperties ?? [] );
160
                    classDoc.methodsAndProperties.push ( methodOrPropertyDoc );
161
                }
162
            }
163
        );
164
165
        Object.freeze ( classDoc.methodsAndProperties );
166
        Object.freeze ( classDoc );
167
168
        return classDoc;
169
    }
170
}
171
172
export default ClassDocBuilder;
173
174
/* --- End of file --------------------------------------------------------------------------------------------------------- */
175