Same name in other branches
  1. 5.0.x advagg_js_minify/jsqueeze.inc \Patchwork\JSqueeze::makeVars()
  2. 6.0.x advagg_js_minify/jsqueeze.inc \Patchwork\JSqueeze::makeVars()
  3. 8.x-2.x advagg_js_minify/jsqueeze.inc \Patchwork\JSqueeze::makeVars()
  4. 8.x-3.x advagg_js_minify/jsqueeze.inc \Patchwork\JSqueeze::makeVars()
  5. 8.x-4.x advagg_js_minify/jsqueeze.inc \Patchwork\JSqueeze::makeVars()
1 call to JSqueeze::makeVars()
JSqueeze::squeeze in advagg_js_compress/jsqueeze.inc
Squeezes a JavaScript source code.

File

advagg_js_compress/jsqueeze.inc, line 699

Class

JSqueeze

Namespace

Patchwork

Code

protected function makeVars($closure, &$tree, $key) {
    $tree['code'] =& $closure;
    $tree['nfe'] = false;
    $tree['used'] = array();
    $tree['local'] = array();
    // Replace multiple "var" declarations by a single one
    $closure = preg_replace_callback("'(?<=[\n\\{\\}])var [^\n\\{\\};]+(?:\nvar [^\n\\{\\};]+)+'", array(
        $this,
        'mergeVarDeclarations',
    ), $closure);
    // Get all local vars (functions, arguments and "var" prefixed)
    $vars =& $tree['local'];
    if (preg_match("'^( [^(]*)?\\((.*?)\\)\\{'", $closure, $v)) {
        if ($v[1]) {
            $vars[$tree['nfe'] = substr($v[1], 1)] = -1;
            $tree['parent']['local'][';' . $key] =& $vars[$tree['nfe']];
        }
        if ($v[2]) {
            $i = 0;
            $v = explode(',', $v[2]);
            foreach ($v as $w) {
                $vars[$w] = $this->argFreq[$i++] - 1;
                // Give a bonus to argument variables
            }
        }
    }
    $v = preg_split("'(?<![\$.a-zA-Z0-9_])var '", $closure);
    if ($i = count($v) - 1) {
        $w = array();
        while ($i) {
            $j = $c = 0;
            $l = strlen($v[$i]);
            while ($j < $l) {
                switch ($v[$i][$j]) {
                    case '(':
                    case '[':
                    case '{':
                        ++$c;
                        break;
                    case ')':
                    case ']':
                    case '}':
                        if ($c-- <= 0) {
                            break 2;
                        }
                        break;
                    case ';':
                    case "\n":
                        if (!$c) {
                            break 2;
                        }
                    default:
                        $c || ($w[] = $v[$i][$j]);
                }
                ++$j;
            }
            $w[] = ',';
            --$i;
        }
        $v = explode(',', implode('', $w));
        foreach ($v as $w) {
            if (preg_match("'^{$this->varRx}'", $w, $v)) {
                isset($vars[$v[0]]) || ($vars[$v[0]] = 0);
            }
        }
    }
    if (preg_match_all("@function ({$this->varRx})//''\"\"#@", $closure, $v)) {
        foreach ($v[1] as $w) {
            isset($vars[$w]) || ($vars[$w] = 0);
        }
    }
    if ($this->argFreq[-1] && preg_match_all("@}catch\\(({$this->varRx})@", $closure, $v)) {
        $v[0] = array();
        foreach ($v[1] as $w) {
            isset($v[0][$w]) ? ++$v[0][$w] : ($v[0][$w] = 1);
        }
        foreach ($v[0] as $w => $v) {
            $vars[$w] = $this->argFreq[-1] - $v;
        }
    }
    // Get all used vars, local and non-local
    $vars =& $tree['used'];
    if (preg_match_all("#([.,{]?(?:[gs]et )?)(?<![a-zA-Z0-9_\$])({$this->varRx})(:?)#", $closure, $w, PREG_SET_ORDER)) {
        foreach ($w as $k) {
            if (isset($k[1][0]) && (',' === $k[1][0] || '{' === $k[1][0])) {
                if (':' === $k[3]) {
                    $k = '.' . $k[2];
                }
                elseif ('get ' === substr($k[1], 1, 4) || 'set ' === substr($k[1], 1, 4)) {
                    ++$this->charFreq[ord($k[1][1])];
                    // "g" or "s"
                    ++$this->charFreq[101];
                    // "e"
                    ++$this->charFreq[116];
                    // "t"
                    $k = '.' . $k[2];
                }
                else {
                    $k = $k[2];
                }
            }
            else {
                $k = $k[1] . $k[2];
            }
            isset($vars[$k]) ? ++$vars[$k] : ($vars[$k] = 1);
        }
    }
    if (preg_match_all("#//''\"\"[0-9]+(?:['!]|/')#", $closure, $w)) {
        foreach ($w[0] as $a) {
            $v = "'" === substr($a, -1) && "/'" !== substr($a, -2) && $this->specialVarRx ? preg_split("#([.,{]?(?:[gs]et )?(?<![a-zA-Z0-9_\$@]){$this->specialVarRx}:?)#", $this->strings[$a], -1, PREG_SPLIT_DELIM_CAPTURE) : array(
                $this->strings[$a],
            );
            $a = count($v);
            for ($i = 0; $i < $a; ++$i) {
                $k = $v[$i];
                if (1 === $i % 2) {
                    if (',' === $k[0] || '{' === $k[0]) {
                        if (':' === substr($k, -1)) {
                            $k = '.' . substr($k, 1, -1);
                        }
                        elseif ('get ' === substr($k, 1, 4) || 'set ' === substr($k, 1, 4)) {
                            ++$this->charFreq[ord($k[1])];
                            // "g" or "s"
                            ++$this->charFreq[101];
                            // "e"
                            ++$this->charFreq[116];
                            // "t"
                            $k = '.' . substr($k, 5);
                        }
                        else {
                            $k = substr($k, 1);
                        }
                    }
                    elseif (':' === substr($k, -1)) {
                        $k = substr($k, 0, -1);
                    }
                    $w =& $tree;
                    while (isset($w['parent']) && !(isset($w['used'][$k]) || isset($w['local'][$k]))) {
                        $w =& $w['parent'];
                    }
                    (isset($w['used'][$k]) || isset($w['local'][$k])) && (isset($vars[$k]) ? ++$vars[$k] : ($vars[$k] = 1));
                    unset($w);
                }
                if (0 === $i % 2 || !isset($vars[$k])) {
                    foreach (count_chars($v[$i], 1) as $k => $w) {
                        $this->charFreq[$k] += $w;
                    }
                }
            }
        }
    }
    // Propagate the usage number to parents
    foreach ($vars as $w => $a) {
        $k =& $tree;
        $chain = array();
        do {
            $vars =& $k['local'];
            $chain[] =& $k;
            if (isset($vars[$w])) {
                unset($k['used'][$w]);
                if (isset($vars[$w])) {
                    $vars[$w] += $a;
                }
                else {
                    $vars[$w] = $a;
                }
                $a = false;
                break;
            }
        } while ($k['parent'] && ($k =& $k['parent']));
        if ($a && !$k['parent']) {
            if (isset($vars[$w])) {
                $vars[$w] += $a;
            }
            else {
                $vars[$w] = $a;
            }
        }
        if (isset($tree['used'][$w]) && isset($vars[$w])) {
            foreach ($chain as &$b) {
                isset($b['local'][$w]) || ($b['used'][$w] =& $vars[$w]);
            }
        }
    }
    // Analyse children
    $tree['children'] = array();
    $vars =& $tree['children'];
    if (preg_match_all("@//''\"\"#[0-9]+'@", $closure, $w)) {
        foreach ($w[0] as $a) {
            $vars[$a] = array(
                'parent' => &$tree,
            );
            $this->makeVars($this->closures[$a], $vars[$a], $a);
        }
    }
}