Commit 0a56879d authored by Stefan Behnel's avatar Stefan Behnel

optimise simple cases of adding string literals

--HG--
extra : transplant_source : w%8C%DC%3BS%CE%B2%8AC%D2%14%D3%99%B9%E8Z%0F%983%AD
parent 4fb73c07
......@@ -3442,6 +3442,31 @@ class ConstantFolding(Visitor.VisitorTransform, SkipDeclarations):
constant_result = node.constant_result)
return new_node
def visit_AddNode(self, node):
self._calculate_const(node)
if node.constant_result is ExprNodes.not_a_constant:
return node
if node.operand1.is_string_literal and node.operand2.is_string_literal:
# some people combine string literals with a '+'
str1, str2 = node.operand1, node.operand2
if isinstance(str1, ExprNodes.UnicodeNode) and isinstance(str2, ExprNodes.UnicodeNode):
bytes_value = None
if str1.bytes_value is not None and str2.bytes_value is not None:
if str1.bytes_value.encoding == str2.bytes_value.encoding:
bytes_value = BytesLiteral(str1.bytes_value + str2.bytes_value)
bytes_value.encoding = str1.bytes_value.encoding
string_value = EncodedString(node.constant_result)
return ExprNodes.UnicodeNode(
str1.pos, value=string_value, constant_result=node.constant_result, bytes_value=bytes_value)
elif isinstance(str1, ExprNodes.BytesNode) and isinstance(str2, ExprNodes.BytesNode):
if str1.value.encoding == str2.value.encoding:
bytes_value = BytesLiteral(node.constant_result)
bytes_value.encoding = str1.value.encoding
return ExprNodes.BytesNode(str1.pos, value=bytes_value, constant_result=node.constant_result)
# all other combinations are rather complicated
# to get right in Py2/3: encodings, unicode escapes, ...
return self.visit_BinopNode(node)
def visit_MulNode(self, node):
self._calculate_const(node)
if node.operand1.is_sequence_constructor:
......
......@@ -109,6 +109,27 @@ def binop_bool():
return plus1, pmix1, minus1, and1, or1, ormix1, xor1, plus3, pmix3, minus3, and3, or3, ormix3, xor3
@cython.test_fail_if_path_exists(
"//ReturnStatNode//AddNode",
)
@cython.test_assert_path_exists(
"//ListNode//AddNode",
)
def add_strings():
"""
>>> u, b, rest = add_strings()
>>> u == 'abcdef' or u
True
>>> b == b'abcdef' or b
True
>>> rest
1
"""
a = ["abc" + "def"] # not currently optimised
# FIXME: test encodings and unicode escapes
return u"abc" + u"def", b"abc" + b"def", a[0] and 1
@cython.test_fail_if_path_exists(
"//SliceIndexNode",
)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment