Skip to content

Commit 4231c50

Browse files
committed
Improve performance
Add more documentation to the readme
1 parent 4309f0a commit 4231c50

File tree

6 files changed

+51
-32
lines changed

6 files changed

+51
-32
lines changed

.gitignore

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@
66
DiffUtils.egg-info
77

88
# Python
9-
*.pyc
9+
*.pyc
10+
11+
# A big file I use to test performance:
12+
joined.srg

README.md

+13
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,15 @@
11
# SrgLib
22
A python library for handling srg files and related stuff
3+
4+
## Features
5+
- Correctly Parses and Outputs srg files
6+
- Is able to [fully reproduce](test.py#21) the original srg file from its internal representation
7+
- Well documented
8+
- All public methods have complete documentation
9+
- Object oriented
10+
- Types have objects, which have useful utility methods
11+
- Fast
12+
- Parses 27,000 lines in under a second (on pypy)
13+
- Takes slightly over a second on python 3.5
14+
- Compatible with python 2.7 and 3.5
15+
- Also compatible with pypy

profiling.py

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from srg.output import serialize_srg
2+
from srg.parser import parse_srg
3+
4+
with open('joined.srg') as file:
5+
lines = file.read().splitlines(keepends=False)
6+
7+
mappings = parse_srg(lines)
8+
9+
output_text = list(serialize_srg(mappings))

setup.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@
77
description='A python library for handling srg files and related stuff)',
88
author='Techcable',
99
author_emails='[email protected]',
10-
packages=["srg"]
10+
packages=["srg"],
11+
requires=["enum34"]
1112
)

srg/__init__.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from srg.types import Type
55

66

7-
class MethodData:
7+
class MethodData(object):
88
def __init__(self, type, name, args, return_type):
99
"""
1010
Create a method data object
@@ -51,7 +51,7 @@ def __eq__(self, other):
5151
and self.args == other.args\
5252
and self.return_type == other.return_type
5353

54-
class FieldData:
54+
class FieldData(object):
5555
def __init__(self, type, name):
5656
"""
5757
Create field data
@@ -231,7 +231,7 @@ def validate_method(method):
231231

232232
# String Validator
233233

234-
_identifier_regex = re.compile("[\w_]+")
234+
_identifier_regex = re.compile("[\w_\$]+")
235235
_type_regex = re.compile('([\w_]+[\$\.])*([\w_]+)')
236236
_package_regex = re.compile('([\w_]+\.)*([\w_]+)')
237237

srg/types.py

+20-27
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import srg
44

55

6-
class Type:
6+
class Type(object):
77
"""
88
A java class
99
@@ -139,7 +139,7 @@ def __init__(self, kind):
139139
140140
:param kind: the kind of this primitive
141141
"""
142-
super().__init__()
142+
super(PrimitiveType, self).__init__()
143143
self._kind = kind
144144

145145
def get_kind(self):
@@ -167,7 +167,7 @@ def __init__(self, element_type):
167167
168168
:param element_type: the element type of the array
169169
"""
170-
super().__init__()
170+
super(ArrayType, self).__init__()
171171
self._type = element_type
172172

173173
def get_element_type(self):
@@ -196,33 +196,27 @@ class PrimitiveKind(Enum):
196196
void is actually a valid java type (believe it or not)
197197
"""
198198

199-
BYTE = 0
200-
SHORT = 1
201-
INT = 2
202-
LONG = 3
203-
FLOAT = 4
204-
DOUBLE = 5
205-
CHAR = 6
206-
BOOLEAN = 7
207-
VOID = 8
199+
BYTE = 'B'
200+
SHORT = 'S'
201+
INT = 'I'
202+
LONG = 'J'
203+
FLOAT = 'F'
204+
DOUBLE = 'D'
205+
CHAR = 'C'
206+
BOOLEAN = 'Z'
207+
VOID = 'V'
208208

209209
def get_descriptor(self):
210210
"""
211211
Get the bytecode descriptor of this primitive type
212212
213213
:return: the bytecode descriptor of this primitive type
214214
"""
215-
return {
216-
PrimitiveKind.BYTE: "B",
217-
PrimitiveKind.SHORT: "S",
218-
PrimitiveKind.INT: "I",
219-
PrimitiveKind.LONG: "J",
220-
PrimitiveKind.FLOAT: "F",
221-
PrimitiveKind.DOUBLE: "D",
222-
PrimitiveKind.CHAR: "C",
223-
PrimitiveKind.BOOLEAN: "Z",
224-
PrimitiveKind.VOID: "V"
225-
}[self]
215+
return self.value
216+
217+
@staticmethod
218+
def from_descriptor(descriptor):
219+
return PrimitiveKind(descriptor)
226220

227221

228222
def parse_internal_name(name):
@@ -235,7 +229,6 @@ def parse_internal_name(name):
235229
"""
236230
return parse_name(name.replace("/", "."))
237231

238-
239232
def parse_name(name):
240233
"""
241234
Parse the given name into a Type
@@ -285,10 +278,10 @@ def parse_descriptor(descriptor):
285278
return ArrayType(parse_descriptor(descriptor[1:]))
286279
except ValueError:
287280
raise ValueError("Couldn't parse descriptor " + descriptor)
288-
for primitive in PrimitiveKind:
289-
if primitive.get_descriptor() == descriptor:
290-
return PrimitiveType(primitive)
291281
if descriptor.startswith("L") and srg.is_valid_type(descriptor[1:].replace("/", ".")):
292282
return Type(descriptor[1:-1].replace('/', "."))
283+
primitive = PrimitiveKind.from_descriptor(descriptor)
284+
if primitive is not None:
285+
return PrimitiveType(primitive)
293286
# Unable to parse
294287
raise ValueError("Couldn't parse descriptor " + descriptor)

0 commit comments

Comments
 (0)