Source code for jasy.style.clean.Unused

#
# Jasy - Web Tooling Framework
# Copyright 2010-2012 Zynga Inc.
# Copyright 2013-2014 Sebastian Werner
#

import jasy.style.parse.Node as Node
import jasy.style.parse.ScopeScanner as ScopeScanner
import jasy.core.Console as Console


#
# Public API
#

[docs]class Error(Exception): def __init__(self, name, line): self.__name = name self.__line = line def __str__(self): return "Unallowed private field access to %s at line %s!" % (self.__name, self.__line)
[docs]def cleanup(node): """""" if not hasattr(node, "variables"): ScopeScanner.scan(node) # Re cleanup until nothing to remove is found iteration = 0 cleaned = False Console.debug("Removing unused variables...") Console.indent() while True: iteration += 1 modified = __cleanup(node) if modified > 0: Console.debug("Removed %s unused variables", modified) ScopeScanner.scan(node) cleaned = True else: break Console.outdent() return cleaned
# # Implementation # def __cleanup(node): """The scanner part which looks for scopes with unused variables/params.""" cleaned = 0 for child in list(node): if child is not None: cleaned += __cleanup(child) # Process any selector separately. # Variables defined in there do not affect the outside if node.type == "selector": rules = node.rules if rules.scope.unused: cleaned += __recurser(node.rules, rules.scope.unused) # Process global style sheet node elif node.type == "sheet" and not hasattr(node, "parent"): if node.scope.unused: cleaned += __recurser(node, node.scope.unused) return cleaned def __recurser(node, unused): """The cleanup part which always processes one scope and cleans up params and variable definitions which are unused.""" modified = 0 # Process children, but ignore all selector blocks as these should be processed separately if node.type != "selector": for child in reversed(node): # None children are allowed sometimes e.g. during array_init like [1,2,,,7,8] if child is not None: modified += __recurser(child, unused) if node.type == "mixin": # Mixin with actual users aka extending customers if getattr(node, "selector", None): pass # Remove full unused functions (when not in top-level scope) elif node.name in unused: Console.debug("Removing unused mixin %s at line %s" % (node.name, node.line)) node.parent.remove(node) modified += 1 else: # Remove unused parameters params = getattr(node.parent, "params", None) if params: # Start from back, as we can only remove params as long # as there is not a required one after the current one for variable in reversed(params): if variable.name in unused: Console.debug("Removing unused parameter '%s' in line %s", variable.name, variable.line) params.remove(variable) modified += 1 else: break elif node.type == "declaration": if node.name in unused: if hasattr(node, "initializer"): init = node.initializer if init.type in ("null", "this", "true", "false", "identifier", "number", "string"): Console.debug("Removing unused primitive variable %s at line %s" % (node.name, node.line)) node.parent.remove(node) modified += 1 else: Console.debug("Could not automatically remove unused variable %s at line %s without possible side-effects" % (node.name, node.line)) else: node.parent.remove(node) modified += 1 return modified