package com.github.sommeri.less4j.core.compiler.stages;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.github.sommeri.less4j.LessCompiler.Configuration;
import com.github.sommeri.less4j.LessSource;
import com.github.sommeri.less4j.core.ast.ASTCssNode;
import com.github.sommeri.less4j.core.ast.Import;
import com.github.sommeri.less4j.core.ast.StyleSheet;
import com.github.sommeri.less4j.core.compiler.scopes.IScope;
import com.github.sommeri.less4j.core.compiler.scopes.PlaceholderScope;
import com.github.sommeri.less4j.core.compiler.stages.SingleImportSolver.AlreadyImportedSources;
import com.github.sommeri.less4j.core.problems.ProblemsHandler;
public class ImportsAndScopeSolver {
private final ProblemsHandler problemsHandler;
private final Configuration configuration;
private SingleImportSolver importsSolver;
private Set<LessSource> allImportedSources;
public ImportsAndScopeSolver(ProblemsHandler problemsHandler, Configuration configuration) {
this.problemsHandler = problemsHandler;
this.configuration = configuration;
}
public IScope buildImportsAndScope(StyleSheet less, LessSource source) {
importsSolver = new SingleImportSolver(problemsHandler, configuration);
allImportedSources = new HashSet<LessSource>();
InitialScopeExtractor scopeBuilder = new InitialScopeExtractor();
IScope scope = scopeBuilder.extractScope(less);
List<PlaceholderScope> importsPlaceholders = scopeBuilder.getImportsPlaceholders();
solveNestedImports(importsPlaceholders);
return scope;
}
private void solveNestedImports(List<PlaceholderScope> importsPlaceholders) {
solveNestedImports(importsPlaceholders, new AlreadyImportedSources(allImportedSources));
}
private void solveNestedImports(List<PlaceholderScope> importsPlaceholders, AlreadyImportedSources alreadyImportedSources) {
for (PlaceholderScope placeholder : importsPlaceholders) {
List<PlaceholderScope> nextLevelOfImports = importIntoPlaceholder(placeholder, alreadyImportedSources);
if (!nextLevelOfImports.isEmpty()) {
Import processedImport = (Import) placeholder.getOwner();
if (processedImport.isImportMultiple())
solveNestedImports(nextLevelOfImports);
else
solveNestedImports(nextLevelOfImports, alreadyImportedSources);
}
}
}
private List<PlaceholderScope> importIntoPlaceholder(PlaceholderScope placeholder, AlreadyImportedSources alreadyImportedSources) {
Import encounteredImport = (Import) placeholder.getOwner();
ReferencesSolver referencesSolver = new ReferencesSolver(problemsHandler, configuration);
referencesSolver.solveReferences(encounteredImport, placeholder.getParent());
ASTCssNode importedAst = importsSolver.importEncountered(encounteredImport, placeholder.getOwner().getSource(), alreadyImportedSources);
if (importedAst != null) {
InitialScopeExtractor importedAstScopeBuilder = new InitialScopeExtractor();
IScope addThisIntoScopeTree = importedAstScopeBuilder.extractScope(importedAst);
placeholder.replaceSelf(addThisIntoScopeTree);
return importedAstScopeBuilder.getImportsPlaceholders();
} else {
placeholder.removeSelf();
}
return Collections.emptyList();
}
public Set<LessSource> getImportedSources() {
return allImportedSources;
}
}