~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to wxPython/wx/tools/Editra/plugins/codebrowser/codebrowser/gentag/phptags.py

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
###############################################################################
 
2
# Name: phptags.py                                                            #
 
3
# Purpose: Generate Tags for Php documents                                    #
 
4
# Author: Cody Precord <cprecord@editra.org>                                  #
 
5
# Copyright: (c) 2008 Cody Precord <staff@editra.org>                         #
 
6
# License: wxWindows License                                                  #
 
7
###############################################################################
 
8
 
 
9
"""
 
10
FILE: phptags.py
 
11
AUTHOR: Cody Precord
 
12
LANGUAGE: Python
 
13
SUMMARY:
 
14
  Generate a DocStruct object that captures the structure of a Php document.
 
15
Currently it supports parsing for Classes, Class Variables, Class Methods, and
 
16
Function Definitions.
 
17
 
 
18
"""
 
19
 
 
20
__author__ = "Cody Precord <cprecord@editra.org>"
 
21
__svnid__ = "$Id: phptags.py 60797 2009-05-29 22:41:06Z CJP $"
 
22
__revision__ = "$Revision: 60797 $"
 
23
 
 
24
#--------------------------------------------------------------------------#
 
25
# Dependancies
 
26
import taglib
 
27
import parselib
 
28
 
 
29
#--------------------------------------------------------------------------#
 
30
 
 
31
def GenerateTags(buff):
 
32
    """Create a DocStruct object that represents a Php Script
 
33
    @param buff: a file like buffer object (StringIO)
 
34
 
 
35
    """
 
36
    rtags = taglib.DocStruct()
 
37
 
 
38
    # Setup document structure
 
39
    rtags.SetElementDescription('function', "Function Definitions")
 
40
 
 
41
    inphp = False        # Are we in a php section or not
 
42
    inclass = False      # Inside a class defintion
 
43
    incomment = False    # Inside a comment
 
44
    infundef = False     # Inside a function definition
 
45
    lastclass = None
 
46
    lastfun = None
 
47
    instring = False
 
48
    openb = 0            # Keep track of open brackets
 
49
 
 
50
    for lnum, line in enumerate(buff):
 
51
        line = line.strip()
 
52
        llen = len(line)
 
53
        idx = 0
 
54
        while idx < len(line):
 
55
            # Skip Whitespace
 
56
            idx = parselib.SkipWhitespace(line, idx)
 
57
 
 
58
            # Walk through strings ignoring contents
 
59
            if instring or line[idx] in (u"'", u'"'):
 
60
                idx, instring = parselib.FindStringEnd(line[idx:], idx)
 
61
                # For multiline strings
 
62
                if instring:
 
63
                    continue
 
64
 
 
65
            # Check if in a <?php ?> block or not
 
66
            if line[idx:].startswith(u'<?'):
 
67
                idx += 2
 
68
                if line[idx:].startswith(u'php'):
 
69
                    idx += 5
 
70
                inphp = True
 
71
            elif line[idx:].startswith(u'?>'):
 
72
                idx += 2
 
73
                inphp = False
 
74
 
 
75
            # Skip anything not in side of a php section
 
76
            if not inphp:
 
77
                idx += 1
 
78
                continue
 
79
 
 
80
            # Check for coments
 
81
            if line[idx:].startswith(u'/*'):
 
82
                idx += 2
 
83
                incomment = True
 
84
            elif line[idx:].startswith(u'//') or line[idx:].startswith(u'#'):
 
85
                break # go to next line
 
86
            elif line[idx:].startswith(u'*/'):
 
87
                idx += 2
 
88
                incomment = False
 
89
 
 
90
            # At end of line
 
91
            if idx >= llen:
 
92
                break
 
93
 
 
94
            # Look for tags
 
95
            if incomment:
 
96
                idx += 1
 
97
            elif line[idx] == u'{':
 
98
                idx += 1
 
99
                openb += 1
 
100
                # Class name must be followed by a {
 
101
                if not inclass and lastclass is not None:
 
102
                    inclass = True
 
103
                    rtags.AddClass(lastclass)
 
104
                elif lastfun is not None:
 
105
                    infundef = True
 
106
                    lastfun = None
 
107
                else:
 
108
                    pass
 
109
            elif line[idx] == u'}':
 
110
                idx += 1
 
111
                openb -= 1
 
112
                if inclass and openb == 0:
 
113
                    inclass = False
 
114
                    lastclass = None
 
115
                elif infundef and inclass and openb == 1:
 
116
                    infundef = False
 
117
                elif infundef and openb == 0:
 
118
                    infundef = False
 
119
                    lastfun = None
 
120
                else:
 
121
                    pass
 
122
            elif not infundef and parselib.IsToken(line, idx, u'class'):
 
123
                # Skip whitespace
 
124
                idx = parselib.SkipWhitespace(line, idx + 5)
 
125
                name = parselib.GetFirstIdentifier(line[idx:])
 
126
                if name is not None:
 
127
                    idx += len(name) # Move past the class name
 
128
                    lastclass = taglib.Class(name, lnum)
 
129
            elif parselib.IsToken(line, idx, u'function'):
 
130
                # Skip whitespace
 
131
                idx = parselib.SkipWhitespace(line, idx + 8)
 
132
                name = parselib.GetFirstIdentifier(line[idx:])
 
133
                if name is not None:
 
134
                    lastfun = name
 
135
                    # Skip whitespace
 
136
                    idx = parselib.SkipWhitespace(line, idx + len(name))
 
137
 
 
138
                    if line[idx] != u'(':
 
139
                        continue
 
140
 
 
141
                    if inclass and lastclass is not None:
 
142
                        lastclass.AddMethod(taglib.Method(name, lnum, lastclass.GetName()))
 
143
                    else:
 
144
                        rtags.AddFunction(taglib.Function(name, lnum))
 
145
            elif inclass and parselib.IsToken(line, idx, u'var'):
 
146
                # Look for class variables
 
147
                idx += 3
 
148
                parts = line[idx:].split()
 
149
                if len(parts) and parts[0].startswith(u'$'):
 
150
                    name = parselib.GetFirstIdentifier(parts[0][1:])
 
151
                    if name is not None and lastclass is not None:
 
152
                        name = u'$' + name
 
153
                        lastclass.AddVariable(taglib.Variable(name, lnum, lastclass.GetName()))
 
154
                        idx += len(name)
 
155
            else:
 
156
                idx += 1
 
157
 
 
158
    return rtags
 
159
 
 
160
#-----------------------------------------------------------------------------#
 
161
# Test
 
162
# Test
 
163
if __name__ == '__main__':
 
164
   import sys
 
165
   import StringIO
 
166
 
 
167
   fhandle = open(sys.argv[1])
 
168
   txt = fhandle.read()
 
169
   fhandle.close()
 
170
   tags = GenerateTags(StringIO.StringIO(txt))
 
171
   print "\n\nElements:"
 
172
 
 
173
   def printElements(elements):
 
174
       for element in elements:
 
175
           print "\n%s:" % element.keys()[0]
 
176
           for val in element.values()[0]:
 
177
               print "%s [%d]" % (val.GetName(), val.GetLine())
 
178
               if isinstance(val, taglib.Scope):
 
179
                   print "----"
 
180
                   printElements(val.GetElements())
 
181
 
 
182
   elements = tags.GetElements()
 
183
   printElements(elements)
 
184
   print "END"