From 7a03eadfa9c1a24b38792d7e874364dafab90ae5 Mon Sep 17 00:00:00 2001 From: Waldemar Kornewald Date: Tue, 5 Nov 2013 14:15:28 +0100 Subject: [PATCH 1/2] fixed dot and bracket accessors on immediate numbers --- src/slimit/tests/test_minifier.py | 8 ++++++++ src/slimit/visitors/ecmavisitor.py | 5 ++++- src/slimit/visitors/minvisitor.py | 10 ++++++++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/slimit/tests/test_minifier.py b/src/slimit/tests/test_minifier.py index e999335..6fd9faf 100644 --- a/src/slimit/tests/test_minifier.py +++ b/src/slimit/tests/test_minifier.py @@ -398,6 +398,14 @@ def assertMinified(self, source, expected): """, "(function($){$.hello='world';}(jQuery));"), + # function call on immediate number + ('((25)).toString()', '(25).toString();'), + ('((25))["toString"]()', '(25).toString();'), + + # attribute access on immediate number + ('((25)).attr', '(25).attr;'), + ('((25))["attr"]', '(25).attr;'), + # function call in FOR init ('for(o(); i < 3; i++) {}', 'for(o();i<3;i++){}'), diff --git a/src/slimit/visitors/ecmavisitor.py b/src/slimit/visitors/ecmavisitor.py index 1c98598..c2e798c 100644 --- a/src/slimit/visitors/ecmavisitor.py +++ b/src/slimit/visitors/ecmavisitor.py @@ -354,7 +354,10 @@ def visit_DotAccessor(self, node): template = '(%s.%s)' else: template = '%s.%s' - s = template % (self.visit(node.node), self.visit(node.identifier)) + left = self.visit(node.node) + if isinstance(node.node, ast.Number): + left = '(%s)' % left + s = template % (left, self.visit(node.identifier)) return s def visit_BracketAccessor(self, node): diff --git a/src/slimit/visitors/minvisitor.py b/src/slimit/visitors/minvisitor.py index 1c6fd15..9846493 100644 --- a/src/slimit/visitors/minvisitor.py +++ b/src/slimit/visitors/minvisitor.py @@ -388,7 +388,10 @@ def visit_DotAccessor(self, node): template = '(%s.%s)' else: template = '%s.%s' - s = template % (self.visit(node.node), self.visit(node.identifier)) + left = self.visit(node.node) + if isinstance(node.node, ast.Number): + left = '(%s)' % left + s = template % (left, self.visit(node.identifier)) return s def visit_BracketAccessor(self, node): @@ -400,7 +403,10 @@ def visit_BracketAccessor(self, node): elif value.startswith('"'): value = value.strip('"') if _is_identifier(value): - s = '%s.%s' % (self.visit(node.node), value) + left = self.visit(node.node) + if isinstance(node.node, ast.Number): + left = '(%s)' % left + s = '%s.%s' % (left, value) return s s = '%s[%s]' % (self.visit(node.node), self.visit(node.expr)) From 7d8c8a1a40ff6dd6693a88c22402504f97ac1e3a Mon Sep 17 00:00:00 2001 From: Sebastian Willenborg Date: Fri, 14 Oct 2016 00:27:06 +0200 Subject: [PATCH 2/2] improve minivistor for immediate numbers accessed via dot accessor --- src/slimit/tests/test_ecmavisitor.py | 9 +++++++++ src/slimit/tests/test_minifier.py | 3 +++ src/slimit/visitors/ecmavisitor.py | 7 +++---- src/slimit/visitors/minvisitor.py | 13 +++++++------ 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/slimit/tests/test_ecmavisitor.py b/src/slimit/tests/test_ecmavisitor.py index 65dfce2..be85178 100644 --- a/src/slimit/tests/test_ecmavisitor.py +++ b/src/slimit/tests/test_ecmavisitor.py @@ -500,6 +500,15 @@ def setUp(self): } }; """, + # function call on immediate number + '(0x25).toString();', + '(1e3).toString();', + '(25).toString();', + + # attribute access on immediate number + '(25).attr;', + '25["attr"];', + '0["attr"];', ] diff --git a/src/slimit/tests/test_minifier.py b/src/slimit/tests/test_minifier.py index 6fd9faf..95536d4 100644 --- a/src/slimit/tests/test_minifier.py +++ b/src/slimit/tests/test_minifier.py @@ -399,12 +399,15 @@ def assertMinified(self, source, expected): "(function($){$.hello='world';}(jQuery));"), # function call on immediate number + ('(0x25).toString()', '0x25.toString();'), + ('(1e3).toString()', '1e3.toString();'), ('((25)).toString()', '(25).toString();'), ('((25))["toString"]()', '(25).toString();'), # attribute access on immediate number ('((25)).attr', '(25).attr;'), ('((25))["attr"]', '(25).attr;'), + ('((0))["attr"]', '(0).attr;'), # function call in FOR init ('for(o(); i < 3; i++) {}', 'for(o();i<3;i++){}'), diff --git a/src/slimit/visitors/ecmavisitor.py b/src/slimit/visitors/ecmavisitor.py index c2e798c..cc52ce2 100644 --- a/src/slimit/visitors/ecmavisitor.py +++ b/src/slimit/visitors/ecmavisitor.py @@ -352,12 +352,11 @@ def visit_NewExpr(self, node): def visit_DotAccessor(self, node): if getattr(node, '_parens', False): template = '(%s.%s)' + elif isinstance(node.node, ast.Number): + template = '(%s).%s' else: template = '%s.%s' - left = self.visit(node.node) - if isinstance(node.node, ast.Number): - left = '(%s)' % left - s = template % (left, self.visit(node.identifier)) + s = template % (self.visit(node.node), self.visit(node.identifier)) return s def visit_BracketAccessor(self, node): diff --git a/src/slimit/visitors/minvisitor.py b/src/slimit/visitors/minvisitor.py index 9846493..b7250d0 100644 --- a/src/slimit/visitors/minvisitor.py +++ b/src/slimit/visitors/minvisitor.py @@ -30,6 +30,9 @@ from slimit.lexer import Lexer _HAS_ID_MATCH = re.compile('^%s$' % Lexer.identifier).match +# Matches all immediate numbers, which are dot accessable (expects a number as input) +_DOT_ACCESSABLE_NUMBER = re.compile('^(0.+|.+[eE].+|.+\..+)$') + def _is_identifier(value): return _HAS_ID_MATCH(value) and value not in Lexer.keywords_dict @@ -386,12 +389,11 @@ def visit_NewExpr(self, node): def visit_DotAccessor(self, node): if getattr(node, '_parens', False): template = '(%s.%s)' + elif isinstance(node.node, ast.Number) and not _DOT_ACCESSABLE_NUMBER.match(node.node.value): + template = '(%s).%s' else: template = '%s.%s' - left = self.visit(node.node) - if isinstance(node.node, ast.Number): - left = '(%s)' % left - s = template % (left, self.visit(node.identifier)) + s = template % (self.visit(node.node), self.visit(node.identifier)) return s def visit_BracketAccessor(self, node): @@ -404,7 +406,7 @@ def visit_BracketAccessor(self, node): value = value.strip('"') if _is_identifier(value): left = self.visit(node.node) - if isinstance(node.node, ast.Number): + if isinstance(node.node, ast.Number) and not _DOT_ACCESSABLE_NUMBER.match(node.node.value): left = '(%s)' % left s = '%s.%s' % (left, value) return s @@ -440,4 +442,3 @@ def visit_Array(self, node): def visit_This(self, node): return 'this' -