Closed twhoff closed 8 years ago
I will have a look at this, thank you for report. Hopefully it will be just a small bug, I hope. In case you find smaller example, let me know please.
Minimized example:
test {
@value: identifier;
extract-identifier: extract(@value, 1);
}
Hmm, I didn't notice there was a difference between Node LESS and LESS4J here - but this does actually work in Node and not in LESS4J (as LESS4J expects list but gets identifier) - however - I don't think that this is the same issue as what I'm experiencing.
In my case, it seems to be a problem with the way LESS4J is treating the list evaluation - it appears to be something to do with nested extract() statements causing LESS4J to see a list when it should actually see an identifier.
In the example: .in-1(20px; col-1, 100px; col-2; col-3, hidden; col-4; m);
- col-2 should be treated as an identifier, but it is being treated as a list.
The best way I can explain the logic is like this:
LOOP THROUGH parameters_list
@parameter: extract(parameters_list, index);
// LESS4J & NODE LESS both see @parameter = extract(parameter_list, index)
// NOT @parameter = col-2 - but LESS4J doesn't evaluate this when calculating length for
// mixin guard expression
// OUTPUT
// Node LESS
LENGTH(@parameter) OUTPUT -> 1
// LESS4J
LENGTH(@parameter) OUTPUT -> 1
// MIXIN GUARD EVALUATION
// Node LESS
WHEN (length(@col-args) > 1) -> LENGTH IS 1 -- GUARD IS FALSE
// LESS4J
WHEN (length(@col-args) > 1) -> LENGTH IS 2 -- GUARD IS TRUE
The problem lies in the mixin guard evaluation. (I think)
Then, when it reaches this point: @col-width: extract(@col-args, length(@col-args));
LESS4J evaluates it like this:
// @col-args = col-2
// LENGTH @col-args now evaluates correctly to 1
@col-width: extract(extract(@col-args, length(@col-args)), length(@col-args));
-> @col-width: extract(col-2, 1);
--> [col-2COMMA1]
That's my theory ;)
I should also mention, the way I've been getting around the issue is by scoping the extract() call within a separate mixin like this:
.loop(@counter) when (@counter > 1) {
// Bubbles @-col-args into scope
.extract-col-args(@col-args; @counter);
// This now correctly evaluates length in mixin guard to 1 - so this mixin doesn't execute
.is-fixed-column(@-col-args); // Return value is passed to mixin as parameter
.is-fixed-column(@col-args) when (length(@col-args) > 1) {
// Do stuff
}
}
.extract-col-args(@list; @index) {
@-col-args: extract(@list, @index);
}
Hope this helps!
In my case, it seems to be a problem with the way LESS4J is treating the list evaluation - it appears to be something to do with nested extract() statements causing LESS4J to see a list when it should actually see an identifier.
The problem is that extract function in less4j was implemented to throw error when argument was not list. The error you run into happens because extract seen identifier instead of list. When I made it accept identifier, your code started to work too :). I need 15 more minutes max till I can do commit.
In any case, I will make release today and then you can test it all in the context. If it still throws an error after, let me know.
Released, you can try it.
Thanks, I will try! - will need to wait for Maven release 1.17.2
Maven should be available by now.
I've been running into a weird issue with the extract() method getting confused about what it should be extracting... The code I'm writing works fine in the Node compiler, but in LESS4J I get an error.
Sorry for the long example, but it's hard to replicate with a basic example.
LESS
Node compiler output
LESS4J
Using the debug console, I can see that it's failing because it thinks col-2 is a list, it has this notation: [col-2COMMA1] - it seems to be something to do with the way extract is resolved: extract(extract(2, 1), 1) - something like that?