Sascha Peilicke 4d63ecfe25 Fix all PEP-8 / flake8 code issues
Drop testscope because it's empty.
2014-02-02 17:35:38 +01:00

120 lines
3.9 KiB
Python

# -*- coding: utf8 -*-
"""
.. module:: lesscpy.plib.deferred
:synopsis: Deferred mixin call.
Copyright (c)
See LICENSE for details.
.. moduleauthor:: Johann T. Mariusson <jtm@robot.is>
"""
from .node import Node
class Deferred(Node):
def __init__(self, mixin, args, lineno=0):
"""This node represents mixin calls. The calls
to these mixins are deferred until the second
parse cycle. lessc.js allows calls to mixins not
yet defined or known.
args:
mixin (Mixin): Mixin object
args (list): Call arguments
"""
self.tokens = [mixin, args]
self.lineno = lineno
def parse(self, scope, error=False, depth=0):
""" Parse function. We search for mixins
first within current scope then fallback
to global scope. The special scope.deferred
is used when local scope mixins are called
within parent mixins.
If nothing is found we fallback to block-mixin
as lessc.js allows calls to blocks and mixins to
be inter-changable.
clx: This method is a HACK that stems from
poor design elsewhere. I will fix it
when I have more time.
args:
scope (Scope): Current scope
returns:
mixed
"""
res = False
ident, args = self.tokens
ident.parse(scope)
mixins = scope.mixins(ident.raw())
if not mixins:
ident.parse(None)
mixins = scope.mixins(ident.raw())
if depth > 64:
raise SyntaxError('NameError `%s`' % ident.raw(True))
if not mixins:
if scope.deferred:
store = [t for t in scope.deferred.parsed[-1]]
i = 0
while scope.deferred.parsed[-1]:
scope.current = scope.deferred
ident.parse(scope)
mixins = scope.mixins(ident.raw())
scope.current = None
if mixins or i > 64:
break
scope.deferred.parsed[-1].pop()
i += 1
scope.deferred.parsed[-1] = store
if not mixins:
# Fallback to blocks
block = scope.blocks(ident.raw())
if not block:
ident.parse(None)
block = scope.blocks(ident.raw())
if block:
scope.current = scope.real[-1] if scope.real else None
res = block.copy_inner(scope)
scope.current = None
if mixins:
for mixin in mixins:
scope.current = scope.real[-1] if scope.real else None
res = mixin.call(scope, args)
if res:
# Add variables to scope to support
# closures
[scope.add_variable(v) for v in mixin.vars]
scope.deferred = ident
break
if res:
store = [t for t in scope.deferred.parsed[
-1]] if scope.deferred else False
tmp_res = []
for p in res:
if p:
if isinstance(p, Deferred):
tmp_res.append(p.parse(scope, depth=depth + 1))
else:
tmp_res.append(p.parse(scope))
res = tmp_res
#res = [p.parse(scope, depth=depth+1) for p in res if p]
while(any(t for t in res if isinstance(t, Deferred))):
res = [p.parse(scope) for p in res if p]
if store:
scope.deferred.parsed[-1] = store
if error and not res:
raise SyntaxError('NameError `%s`' % ident.raw(True))
return res
def copy(self):
""" Returns self (used when Block objects are copy'd)
returns:
self
"""
return self