Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

safer boolean transformations (see issue #84 in UglifyJS)

  • Loading branch information...
commit 5954d87e17ad0675205e0678585a43d6db58b410 1 parent d5194ca
Mihai Bazon authored
Showing with 34 additions and 9 deletions.
  1. +20 −8 src/squeeze.lisp
  2. +14 −1 src/walker.lisp
28 src/squeeze.lisp
View
@@ -76,13 +76,32 @@
`(:conditional ,cond ,then ,else)
`(:binary :&& ,cond ,then))))
+(defun boolean-expr (expr)
+ (ast-case expr
+ (:unary-prefix (op _) (member op '(:! :delete)))
+ (:binary (op left right)
+ (case op
+ ((:in :instanceof :== :!= :=== :!== :< :<= :> :>=) t)
+ ((:&& :|\|\||) (and (boolean-expr left)
+ (boolean-expr right)))))
+ (:conditional (_ left right)
+ (and (boolean-expr left)
+ (boolean-expr right)))
+ (:assign (op _ right)
+ (and (eq op t)
+ (boolean-expr right)))
+ (:seq (_ two)
+ (boolean-expr two))))
+
(defun negate (c)
(flet ((not-c ()
`(:unary-prefix :! ,c)))
(or (ast-case c
(:unary-prefix (op expr)
- (when (eq op :!)
+ (when (and (eq op :!) (boolean-expr expr))
expr))
+ (:seq (one two)
+ `(:seq ,one ,(negate two)))
(:binary (op left right)
(case op
(:< `(:binary :>= ,left ,right))
@@ -310,13 +329,6 @@
(:unary-prefix (op ex)
(when (eq op :!)
(let ((ex (walk ex)))
- (when (and (eq (car ex) :unary-prefix)
- (eq (cadr ex) :!))
- (let ((p (cadr stack)))
- (when (and (eq (car p) :unary-prefix)
- (eq (cadr p) :!))
- (return (caddr ex)))
- (return `(:unary-prefix :! ,ex))))
(best-of `(:unary-prefix :! ,ex) (negate ex)))))
(:atom (val)
15 src/walker.lisp
View
@@ -1,5 +1,14 @@
(in-package #:uglify-js)
+(defun varlist (names)
+ (iter (for i in names)
+ (case i
+ (_ (let ((sym (gensym "ignored")))
+ (collect sym into ignored)
+ (collect sym into vars)))
+ (t (collect i into vars)))
+ (finally (return (values vars ignored)))))
+
(defmacro ast-case (expr &body body)
(let ((ex (gensym "AST")))
`(let ((,ex ,expr))
@@ -8,7 +17,11 @@
:for c = (car i)
:for a = (cadr i)
:for b = (cddr i)
- :if a :collect `(,c (destructuring-bind (&optional ,@a) (cdr ,ex) (block nil ,@b)))
+ :if a :collect (multiple-value-bind (vars ignored) (varlist a)
+ `(,c (destructuring-bind (&optional ,@vars) (cdr ,ex)
+ ,(when ignored
+ `(declare (ignore ,@ignored)))
+ (block nil ,@b))))
:else :collect `(,c (block nil ,@b)))))))
(defmacro ast-walk ((ast &optional (expr 'expr) (walk 'walk) stack) &body body)
Please sign in to comment.
Something went wrong with that request. Please try again.