File: jsgenerator.py

package info (click to toggle)
kdevelop 4%3A5.0.3-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 26,356 kB
  • ctags: 23,249
  • sloc: cpp: 160,775; python: 2,137; lex: 621; ansic: 617; sh: 577; xml: 142; ruby: 120; makefile: 52; php: 12; sed: 12
file content (224 lines) | stat: -rw-r--r-- 6,492 bytes parent folder | download
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# This file is part of qmljs, the QML/JS language support plugin for KDevelop
# Copyright (c) 2014 Denis Steckelmacher <steckdenis@yahoo.fr>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License or (at your option) version 3 or any later version
# accepted by the membership of KDE e.V. (or its successor approved
# by the membership of KDE e.V.), which shall act as a proxy
# defined in Section 14 of version 3 of the license.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

class Member(object):
    def __init__(self, name):
        """
            Member of classes are identified by a name. A parent name can be
            given and will be used to build the string "Parent.prototype.name"
        """
        self._name = name
        self._full_name = name

    def setParentName(self, name, usePrototype = True):
        if usePrototype:
            self._full_name = '%s.prototype.%s' % (name, self.name())
        else:
            self._full_name = '%s.%s' % (name, self.name())

    def setName(self, name):
        self._name = name

    def name(self):
        return self._name

    def fullName(self):
        return self._full_name

    def print(self):
        print('%s = %s;' % (self.fullName(), self.valueToAssign()))

        if self.valueAfterAssignation() != '':
            print(self.valueAfterAssignation())

    def valueToAssign(self):
        """
            Value to assign to the member, for instance "function (){}"
        """
        return '""';

    def valueAfterAssignation(self):
        """
            Line that will be printed after the assignation. Can be used to call
            a function (therefore giving the type of its parameters.
        """
        return '';

class F(Member):
    def __init__(self, returnValue, name, *args):
        """
            A function has a name, a return value, and arguments. Each argument,
            is a tuple whose first entry is the argument name, and the second
            one its type.

            Note that types are not given using names ("int", "bool", etc), but
            values of the type ("1" for an int, "true" or "false" for a boolean,
            "new X()" for class X, etc).
        """
        Member.__init__(self, name)

        self._return_value = returnValue
        self._args = args

    def print(self):
        if self.name() != '':
            # This function is not a member, no need to assign it to an object
            print(self.valueToAssign())
        else:
            Member.print(self)

    def valueToAssign(self):
        # Define the function
        return 'function %s(%s) { return %s; }' % (
            self.name(),
            ', '.join([arg[0] for arg in self._args]),
            self._return_value
        )

    def valueAfterAssignation(self):
        # Call it, so that its parameters have the correct type
        return '%s(%s);' % (
            self.fullName(),
            ', '.join([arg[1] for arg in self._args])
        )

class Var(Member):
    def __init__(self, type, name):
        """
            A variable has a name and a type
        """
        Member.__init__(self, name)

        self._type = type

    def print(self):
        if self.name() != '':
            # This variable is not a member, declare it using 'var'
            print('var %s = %s;' % (self.name(), self.valueToAssign()))
        else:
            Member.print(self)

    def valueToAssign(self):
        return self._type


class Class(F):
    def __init__(self, name, *args):
        F.__init__(self, '', name, *args)
        self._members = []
        self._prototype = None

    def prototype(self, proto):
        self._prototype = proto
        return self

    def member(self, member):
        self._members.append(member)
        return self

    def members(self, *args):
        for arg in args:
            self.member(arg)

        return self

    def print(self):
        # Declare the constructor (a function)
        print('/*\n * %s\n */' % self.fullName())

        # Always declare a function using the function keyword
        old_full_name = self._full_name
        old_name = self._name

        self._full_name = self._full_name.split('.')[-1]
        self._name = self._full_name

        F.print(self)

        if old_full_name != self._name:
            print('%s = %s;' % (old_full_name, self._name))

        self._full_name = old_full_name
        self._name = old_name

        # Print the prototype
        if self._prototype is not None:
            print('%s.prototype = %s;' % (self.fullName(), self._prototype))

        print('')

        # Declare the members
        for member in self._members:
            member.setParentName(self.fullName())
            member.setName('')
            member.print()
            print('')

class Struct(Var):
    def __init__(self, name):
        Var.__init__(self, '{}', name)
        self._members = []

    def member(self, member):
        self._members.append(member)
        return self

    def members(self, *args):
        for arg in args:
            self.member(arg)

        return self

    def print(self):
        # Declare the object
        print('/*\n * %s\n */' % self.fullName())
        Var.print(self)
        print('')

        # Declare the members
        for member in self._members:
            member.setParentName(self.fullName(), False)
            member.setName('')
            member.print()
            print('')

class Module(object):
    def __init__(self):
        self._members = []

    def member(self, member):
        self._members.append(member)
        return self

    def members(self, *args):
        for arg in args:
            self.member(arg)

        return self

    def print(self):
        # Declare the members in "exports"
        for member in self._members:
            member.setParentName('exports', False)
            member.setName('')
            member.print()
            print('')