summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerman M. Bravo <german.mb@deipi.com>2013-10-04 15:23:51 -0500
committerGerman M. Bravo <german.mb@deipi.com>2013-10-04 15:23:51 -0500
commit4ab721722ccc1473cbf32c1407d26f84e613bb98 (patch)
tree48ae126229d709e5a8f80c6637dc32f75d0ddb36
parentf11f1ec17aa7babcf20ce87629fd4f9394fa8994 (diff)
downloadpyscss-4ab721722ccc1473cbf32c1407d26f84e613bb98.tar.gz
Added "Unused @import" warning message
-rw-r--r--scss/__init__.py31
-rw-r--r--scss/rule.py29
-rw-r--r--scss/tests/files/kronuz/imports-unused.css6
-rw-r--r--scss/tests/files/kronuz/imports-unused.scss14
4 files changed, 65 insertions, 15 deletions
diff --git a/scss/__init__.py b/scss/__init__.py
index 9193d29..284744e 100644
--- a/scss/__init__.py
+++ b/scss/__init__.py
@@ -146,7 +146,7 @@ class SourceFile(object):
self.line_numbers = line_numbers
self.line_strip = line_strip
self.contents = self.prepare_source(contents)
- self.parent_dir = parent_dir
+ self.parent_dir = os.path.realpath(parent_dir)
self.is_string = is_string
@classmethod
@@ -494,6 +494,8 @@ class Scss(object):
for rule in children:
self.manage_children(rule, scope)
+ root_namespace.warn_unused_imports()
+
@print_timing(4)
def manage_children(self, rule, scope):
try:
@@ -652,7 +654,7 @@ class Scss(object):
if default is not None:
defaults[var_name] = default
- mixin = [list(new_params), defaults, block.unparsed_contents, rule.namespace, argspec_node]
+ mixin = [list(new_params), defaults, block.unparsed_contents, rule.namespace, argspec_node, rule.import_key]
if block.directive == '@function':
def _call(mixin):
def __call(namespace, *args, **kwargs):
@@ -662,6 +664,8 @@ class Scss(object):
m_params = mixin[0]
m_defaults = mixin[1]
m_codestr = mixin[2]
+ pristine_callee_namespace = mixin[3]
+ import_key = mixin[5]
params = []
params_dict = {}
@@ -695,6 +699,7 @@ class Scss(object):
# consider itself as existing where it was defined, not
# called?
source_file=rule.source_file,
+ import_key=rule.import_key,
# TODO
unparsed_contents=m_codestr,
@@ -708,6 +713,7 @@ class Scss(object):
namespace=m_vars,
)
+ pristine_callee_namespace.use_import(import_key)
self.manage_children(_rule, scope)
ret = _rule.retval
if ret is None:
@@ -769,6 +775,7 @@ class Scss(object):
m_codestr = mixin[2]
pristine_callee_namespace = mixin[3]
callee_argspec = mixin[4]
+ import_key = mixin[5]
if caller_argspec.inject and callee_argspec.inject:
# DEVIATION: Pass the ENTIRE local namespace to the mixin (yikes)
@@ -824,6 +831,7 @@ class Scss(object):
_rule.lineno = block.lineno
_rule.options['@content'] = block.unparsed_contents
+ pristine_callee_namespace.use_import(import_key)
self.manage_children(_rule, scope)
@print_timing(10)
@@ -851,9 +859,6 @@ class Scss(object):
names = block.argument.split(',')
for name in names:
name = dequote(name.strip())
- if rule.namespace.has_import(name, rule.source_file.parent_dir):
- # If already imported in this scope, skip
- continue
source_file = None
full_filename, seen_paths = self._find_import(rule, name)
@@ -873,7 +878,7 @@ class Scss(object):
source_file = SourceFile(
full_filename,
source,
- parent_dir=os.path.dirname(full_filename),
+ parent_dir=os.path.realpath(os.path.dirname(full_filename)),
)
self.source_files.append(source_file)
@@ -884,8 +889,14 @@ class Scss(object):
log.warn("File to import not found or unreadable: '%s' (%s)%s", name, rule.file_and_line, load_paths_msg)
continue
+ import_key = (name, source_file.parent_dir)
+ if rule.namespace.has_import(import_key):
+ # If already imported in this scope, skip
+ continue
+
_rule = SassRule(
source_file=source_file,
+ import_key=import_key,
lineno=block.lineno,
unparsed_contents=source_file.contents,
@@ -896,7 +907,7 @@ class Scss(object):
ancestry=rule.ancestry,
namespace=rule.namespace,
)
- rule.namespace.add_import(name, rule.source_file.parent_dir)
+ rule.namespace.add_import(import_key, rule.import_key, rule.file_and_line)
self.manage_children(_rule, scope)
def _find_import(self, rule, name):
@@ -1248,6 +1259,7 @@ class Scss(object):
from scss.rule import RuleAncestry
new_rule = SassRule(
source_file=rule.source_file,
+ import_key=rule.import_key,
lineno=block.lineno,
unparsed_contents=block.unparsed_contents,
@@ -1260,7 +1272,9 @@ class Scss(object):
nested=rule.nested + 1,
)
self.rules.append(new_rule)
+ rule.namespace.use_import(rule.import_key)
self.manage_children(new_rule, scope)
+ new_rule.namespace.warn_unused_imports()
@print_timing(10)
def _nest_rules(self, rule, scope, block):
@@ -1277,6 +1291,7 @@ class Scss(object):
new_rule = SassRule(
source_file=rule.source_file,
+ import_key=rule.import_key,
lineno=block.lineno,
unparsed_contents=block.unparsed_contents,
@@ -1289,7 +1304,9 @@ class Scss(object):
nested=rule.nested + 1,
)
self.rules.append(new_rule)
+ rule.namespace.use_import(rule.import_key)
self.manage_children(new_rule, scope)
+ new_rule.namespace.warn_unused_imports()
@print_timing(3)
def apply_extends(self):
diff --git a/scss/rule.py b/scss/rule.py
index 6d3b856..dc1dd08 100644
--- a/scss/rule.py
+++ b/scss/rule.py
@@ -104,8 +104,7 @@ class MixinScope(Scope):
class ImportScope(Scope):
- def __repr__(self):
- return "<%s(%s) at 0x%x>" % (type(self).__name__, ', '.join('[%s]' % ', '.join(repr(k) for k in sorted(map.keys())) for map in self.maps), id(self))
+ pass
class Namespace(object):
@@ -170,14 +169,27 @@ class Namespace(object):
raise TypeError("Expected a Sass type, while setting %s got %r" % (name, value,))
self._variables.set(name, value, force_local=local_only)
- def has_import(self, name, path=None):
- import_key = (name, path)
+ def has_import(self, import_key):
return import_key in self._imports
- def add_import(self, name, path=None):
+ def add_import(self, import_key, parent_import_key, file_and_line):
self._assert_mutable()
- import_key = (name, path)
- self._imports[import_key] = True
+ if import_key:
+ imports = [0, parent_import_key, file_and_line]
+ self._imports[import_key] = imports
+
+ def use_import(self, import_key):
+ self._assert_mutable()
+ if import_key and import_key in self._imports:
+ imports = self._imports[import_key]
+ imports[0] += 1
+ self.use_import(imports[1])
+
+ def warn_unused_imports(self):
+ for import_key in self._imports.keys():
+ imports = self._imports[import_key]
+ if not imports[0]:
+ log.warn("Unused @import: '%s' (%s)", import_key[0], imports[2])
def _get_callable(self, chainmap, name, arity):
name = normalize_var(name)
@@ -216,7 +228,7 @@ class SassRule(object):
metadata, like `@extend` rules and `@media` nesting.
"""
- def __init__(self, source_file, unparsed_contents=None,
+ def __init__(self, source_file, import_key=None, unparsed_contents=None,
options=None, properties=None,
namespace=None,
lineno=0, extends_selectors=frozenset(),
@@ -224,6 +236,7 @@ class SassRule(object):
nested=-1):
self.source_file = source_file
+ self.import_key = import_key
self.lineno = lineno
self.unparsed_contents = unparsed_contents
diff --git a/scss/tests/files/kronuz/imports-unused.css b/scss/tests/files/kronuz/imports-unused.css
new file mode 100644
index 0000000..fd7e4e6
--- /dev/null
+++ b/scss/tests/files/kronuz/imports-unused.css
@@ -0,0 +1,6 @@
+#test {
+ width: 490px;
+}
+div {
+ width: 990px;
+}
diff --git a/scss/tests/files/kronuz/imports-unused.scss b/scss/tests/files/kronuz/imports-unused.scss
new file mode 100644
index 0000000..127a655
--- /dev/null
+++ b/scss/tests/files/kronuz/imports-unused.scss
@@ -0,0 +1,14 @@
+@option compress:no;
+
+@import "functions-context";
+
+#test {
+ @import "functions-context";
+ @import "imports-unused";
+ @import "menu";
+ width: grid-width(10);
+}
+
+div {
+ width: grid-width(20);
+}