Skip to content

Commit

Permalink
Strenghtened scope protection for detached rulesets. #186
Browse files Browse the repository at this point in the history
  • Loading branch information
jurcovicovam committed Jul 1, 2014
1 parent fdbffec commit 666542b
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@
public interface ExpressionFilter {

Expression apply(Expression input);

boolean accepts(String name, Expression value);

}
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ private ExpressionFilter toEvaluationFilter() {
public Expression apply(Expression input) {
return evaluate(input);
}

@Override
public boolean accepts(String name, Expression value) {
return true;
}
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ public T getValue(M key) {
return null;
}

public void remove(M key) {
Iterator<Level<M, T>> di = levels.descendingIterator();
while (di.hasNext()) {
Level<M, T> level = di.next();
if (level.contains(key))
level.remove(key);
}
}

public Set<Entry<M, T>> getAllEntries() {
Set<Entry<M, T>> result = new HashSet<Entry<M,T>>();
Iterator<Level<M, T>> iterator = levels.descendingIterator();
Expand Down Expand Up @@ -151,6 +160,10 @@ public T getValue(M key) {
return storage.get(key);
}

public void remove(M key) {
storage.remove(key);
}

public boolean contains(M key) {
return storage.containsKey(key);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ public Expression getValue(String name) {
return coolStorage.getValue(name);
}

public void remove(String name) {
coolStorage.remove(name);
}

public void store(AbstractVariableDeclaration node) {
store(node.getVariable().getName(), node.getValue());
}
Expand Down Expand Up @@ -48,7 +52,8 @@ public void addFilteredVariables(ExpressionFilter filter, VariablesDeclarationsS
for (Entry<String, Expression> entry : variablesSource.coolStorage.getAllEntries()) {
String name = entry.getKey();
Expression value = entry.getValue();
store(name, filter.apply(value));
if (filter.accepts(name, value))
store(name, filter.apply(value));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import com.github.sommeri.less4j.core.compiler.scopes.ScopeFactory;
import com.github.sommeri.less4j.core.problems.ProblemsHandler;

class MixinsSolver {
class MixinsRulesetsSolver {

private final ProblemsHandler problemsHandler;
private final ReferencesSolver parentSolver;
Expand All @@ -35,15 +35,15 @@ class MixinsSolver {
private final DefaultGuardHelper defaultGuardHelper;
private final CallerCalleeScopeJoiner scopeManipulation = new CallerCalleeScopeJoiner();

public MixinsSolver(ReferencesSolver parentSolver, AstNodesStack semiCompiledNodes, ProblemsHandler problemsHandler, Configuration configuration) {
public MixinsRulesetsSolver(ReferencesSolver parentSolver, AstNodesStack semiCompiledNodes, ProblemsHandler problemsHandler, Configuration configuration) {
this.parentSolver = parentSolver;
this.semiCompiledNodes = semiCompiledNodes;
this.problemsHandler = problemsHandler;
this.configuration = configuration;
this.defaultGuardHelper = new DefaultGuardHelper(problemsHandler);
}

private BodyCompilationResult resolveCalledBody(final IScope callerScope, final BodyOwner<?> bodyOwner, final IScope bodyWorkingScope) {
private BodyCompilationResult resolveCalledBody(final IScope callerScope, final BodyOwner<?> bodyOwner, final IScope bodyWorkingScope, final ScopeProtection protectionLevel) {
final ExpressionsEvaluator expressionEvaluator = new ExpressionsEvaluator(bodyWorkingScope, problemsHandler, configuration);

final IScope referencedMixinScope = bodyWorkingScope;
Expand All @@ -57,7 +57,7 @@ public BodyCompilationResult run() {

// collect variables and mixins to be imported
IScope returnValues = ScopeFactory.createDummyScope();
returnValues.addFilteredVariables(new ImportedScopeFilter(expressionEvaluator, callerScope), referencedMixinScope);
returnValues.addFilteredVariables(new ImportedScopeFilter(expressionEvaluator, callerScope, protectionLevel), referencedMixinScope);
List<FullMixinDefinition> unmodifiedMixinsToImport = referencedMixinScope.getAllMixins();

List<FullMixinDefinition> allMixinsToImport = scopeManipulation.mixinsToImport(callerScope, referencedMixinScope, unmodifiedMixinsToImport);
Expand Down Expand Up @@ -121,7 +121,7 @@ public void run() {
if (guardValue != GuardValue.DO_NOT_USE) {
//OPTIMIZATION POSSIBLE: there is no need to compile mixins at this point, some of them are not going to be
//used and create snapshot operation is cheap now. It should be done later on.
BodyCompilationResult compiled = resolveCalledBody(callerScope, fullMixin.getMixin(), mixinWorkingScope);
BodyCompilationResult compiled = resolveCalledBody(callerScope, fullMixin.getMixin(), mixinWorkingScope, ScopeProtection.LOCAL_ONLY);
//mark the mixin according to its default() function use
compiled.setGuardValue(guardValue);
//store the mixin as candidate
Expand Down Expand Up @@ -149,7 +149,7 @@ public void run() {

public GeneralBody buildDetachedRulesetReplacement(DetachedRulesetReference reference, IScope callerScope, DetachedRuleset detachedRuleset, IScope detachedRulesetScope) {
IScope mixinWorkingScope = scopeManipulation.joinIfIndependent(callerScope, detachedRulesetScope);
BodyCompilationResult compiled = resolveCalledBody(callerScope, detachedRuleset, mixinWorkingScope);
BodyCompilationResult compiled = resolveCalledBody(callerScope, detachedRuleset, mixinWorkingScope, ScopeProtection.FULL);
GeneralBody result = new GeneralBody(reference.getUnderlyingStructure());

result.addMembers(compiled.getReplacement());
Expand Down Expand Up @@ -186,11 +186,13 @@ class ImportedScopeFilter implements ExpressionFilter {
private final ExpressionsEvaluator expressionEvaluator;
private final IScope importTargetScope;
private final CallerCalleeScopeJoiner scopeManipulation = new CallerCalleeScopeJoiner();
private final ScopeProtection protectionLevel;

public ImportedScopeFilter(ExpressionsEvaluator expressionEvaluator, IScope importTargetScope) {
public ImportedScopeFilter(ExpressionsEvaluator expressionEvaluator, IScope importTargetScope, ScopeProtection protectionLevel) {
super();
this.expressionEvaluator = expressionEvaluator;
this.importTargetScope = importTargetScope;
this.protectionLevel = protectionLevel;
}

public Expression apply(Expression input) {
Expand All @@ -207,6 +209,14 @@ private IScope apply(IScope input) {
return scopeManipulation.joinIfIndependentAndPreserveContent(importTargetScope, input);
}

@Override
public boolean accepts(String name, Expression value) {
if (protectionLevel==ScopeProtection.LOCAL_ONLY)
return true;

return importTargetScope.getValue(name)==null;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class ReferencesSolver {

public static final String ALL_ARGUMENTS = "@arguments";
private ASTManipulator manipulator = new ASTManipulator();
private final MixinsSolver mixinsSolver;
private final MixinsRulesetsSolver mixinsSolver;
private final ProblemsHandler problemsHandler;
private final Configuration configuration;
private final AstNodesStack semiCompiledNodes = new AstNodesStack();
Expand All @@ -52,7 +52,7 @@ public ReferencesSolver(ProblemsHandler problemsHandler, Configuration configura
this.problemsHandler = problemsHandler;
this.configuration = configuration;
this.stringInterpolator = new StringInterpolator(problemsHandler);
this.mixinsSolver = new MixinsSolver(this, semiCompiledNodes, problemsHandler, configuration);
this.mixinsSolver = new MixinsRulesetsSolver(this, semiCompiledNodes, problemsHandler, configuration);
}

public void solveReferences(final ASTCssNode node, final IScope scope) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.github.sommeri.less4j.core.compiler.stages;

public enum ScopeProtection {
LOCAL_ONLY, FULL
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
color: black;
one: 1px;
four: magic-frame;
visible-one: hidden and if you see this in the output its a bug;
visible-one: visible;
visible-two: visible;
}
.wrap-selector {
Expand Down

0 comments on commit 666542b

Please sign in to comment.