blob: eb4617f3098527df8d5f515225d9f6b6f99ae60e [file] [log] [blame]
/*
* Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.resources.css;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.resources.css.ast.Context;
import com.google.gwt.resources.css.ast.CssExternalSelectors;
import com.google.gwt.resources.css.ast.CssSelector;
import com.google.gwt.resources.css.ast.CssStylesheet;
import com.google.gwt.resources.css.ast.CssVisitor;
import com.google.gwt.resources.rg.CssResourceGenerator;
import java.util.HashSet;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.regex.Matcher;
/**
* Collect all CSS class names in a stylesheet.
*/
public class ExtractClassNamesVisitor extends CssVisitor {
/**
* Extract all CSS class names in the provided stylesheet.
*/
public static Set<String> exec(CssStylesheet sheet) {
return exec(sheet, new JClassType[0]);
}
/**
* Extract all CSS class names in the provided stylesheet, modulo those
* imported from another context.
*/
public static Set<String> exec(CssStylesheet sheet, JClassType... imports) {
SortedSet<String> ignoredPrefixes = new TreeSet<String>();
for (JClassType clazz : imports) {
String prefix = CssResourceGenerator.getImportPrefix(clazz);
ignoredPrefixes.add(prefix);
}
ExtractClassNamesVisitor v = new ExtractClassNamesVisitor(ignoredPrefixes);
v.accept(sheet);
return v.found;
}
private final Set<String> found = new HashSet<String>();
private final SortedSet<String> ignoredPrefixes;
/**
* Package-protected for testing.
*/
ExtractClassNamesVisitor(SortedSet<String> ignoredPrefixes) {
this.ignoredPrefixes = ignoredPrefixes;
}
@Override
public void endVisit(CssExternalSelectors x, Context ctx) {
addAll(x.getClasses());
}
@Override
public void endVisit(CssSelector x, Context ctx) {
Matcher m = CssSelector.CLASS_SELECTOR_PATTERN.matcher(x.getSelector());
while (m.find()) {
add(m.group(1));
}
}
/**
* Package-protected for testing.
*/
Set<String> getFoundClasses() {
return found;
}
private void add(String selector) {
SortedSet<String> headSet = ignoredPrefixes.headSet(selector);
if (headSet.isEmpty() || !selector.startsWith(headSet.last())) {
found.add(selector);
}
}
private void addAll(Iterable<String> selectors) {
for (String selector : selectors) {
add(selector);
}
}
}