Add a utility visitor to extract all CSS class selector names used in a stylesheet.
Patch by: bobv
Review by: rjrjr
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@6018 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/resources/css/ExtractClassNamesVisitor.java b/user/src/com/google/gwt/resources/css/ExtractClassNamesVisitor.java
new file mode 100644
index 0000000..c01464f
--- /dev/null
+++ b/user/src/com/google/gwt/resources/css/ExtractClassNamesVisitor.java
@@ -0,0 +1,70 @@
+/*
+ * 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.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 java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Matcher;
+
+/**
+ * Collect all CSS class names in a stylesheet.
+ */
+public class ExtractClassNamesVisitor extends CssVisitor {
+ private final Set<String> found = new HashSet<String>();
+
+ /**
+ * Package-protected for testing.
+ */
+ ExtractClassNamesVisitor() {
+ }
+
+ @Override
+ public void endVisit(CssExternalSelectors x, Context ctx) {
+ found.addAll(x.getClasses());
+ }
+
+ @Override
+ public void endVisit(CssSelector x, Context ctx) {
+ Matcher m = CssSelector.CLASS_SELECTOR_PATTERN.matcher(x.getSelector());
+ while (m.find()) {
+ found.add(m.group(1));
+ }
+ }
+
+ /**
+ * Extract all CSS class names in the provided stylesheet.
+ */
+ public Set<String> exec(CssStylesheet sheet) {
+ ExtractClassNamesVisitor v = new ExtractClassNamesVisitor();
+ v.accept(sheet);
+ return v.found;
+ }
+
+ /**
+ * Package-protected for testing.
+ *
+ * @return
+ */
+ Set<String> getFoundClasses() {
+ return found;
+ }
+}
diff --git a/user/src/com/google/gwt/resources/css/ast/CssSelector.java b/user/src/com/google/gwt/resources/css/ast/CssSelector.java
index 5d52ed1..b6067ce 100644
--- a/user/src/com/google/gwt/resources/css/ast/CssSelector.java
+++ b/user/src/com/google/gwt/resources/css/ast/CssSelector.java
@@ -15,10 +15,14 @@
*/
package com.google.gwt.resources.css.ast;
+import java.util.regex.Pattern;
+
/**
- *
+ * An opaque view of a selector.
*/
public class CssSelector extends CssNode {
+ public static final Pattern CLASS_SELECTOR_PATTERN = Pattern.compile("\\.([^ :>+#.]*)");
+
/*
* TODO: Evaluate whether or not we need to have a type hierarchy of
* selectors.
diff --git a/user/src/com/google/gwt/resources/rg/CssResourceGenerator.java b/user/src/com/google/gwt/resources/rg/CssResourceGenerator.java
index 744d25f..307fb1c 100644
--- a/user/src/com/google/gwt/resources/rg/CssResourceGenerator.java
+++ b/user/src/com/google/gwt/resources/rg/CssResourceGenerator.java
@@ -115,7 +115,6 @@
* obfuscated names for the CssResource that is being generated.
*/
private final Map<String, Map<JMethod, String>> classReplacementsWithPrefix;
- private final Pattern classSelectorPattern = Pattern.compile("\\.([^ :>+#.]*)");
private final Set<String> cssDefs = new HashSet<String>();
private final Set<String> externalClasses;
private final TreeLogger logger;
@@ -184,7 +183,7 @@
sel = sel.trim();
if (strict) {
- Matcher m = classSelectorPattern.matcher(sel);
+ Matcher m = CssSelector.CLASS_SELECTOR_PATTERN.matcher(sel);
while (m.find()) {
String classSelector = m.group(1);
if (!replacedClasses.contains(classSelector)
diff --git a/user/test/com/google/gwt/resources/ResourcesSuite.java b/user/test/com/google/gwt/resources/ResourcesSuite.java
index 2a754cb..7826df2 100644
--- a/user/test/com/google/gwt/resources/ResourcesSuite.java
+++ b/user/test/com/google/gwt/resources/ResourcesSuite.java
@@ -21,6 +21,7 @@
import com.google.gwt.resources.client.ImageResourceTest;
import com.google.gwt.resources.client.NestedBundleTest;
import com.google.gwt.resources.client.TextResourceTest;
+import com.google.gwt.resources.css.ExtractClassNamesVisitorTest;
import com.google.gwt.resources.rg.CssNodeClonerTest;
import com.google.gwt.resources.rg.CssReorderTest;
import com.google.gwt.resources.rg.CssRtlTest;
@@ -38,6 +39,7 @@
suite.addTestSuite(CssReorderTest.class);
suite.addTestSuite(CssRtlTest.class);
suite.addTestSuite(CssNodeClonerTest.class);
+ suite.addTestSuite(ExtractClassNamesVisitorTest.class);
suite.addTestSuite(ImageResourceTest.class);
suite.addTestSuite(ImageResourceNoInliningTest.class);
suite.addTestSuite(NestedBundleTest.class);
diff --git a/user/test/com/google/gwt/resources/css/ExtractClassNamesVisitorTest.java b/user/test/com/google/gwt/resources/css/ExtractClassNamesVisitorTest.java
new file mode 100644
index 0000000..532a9d4
--- /dev/null
+++ b/user/test/com/google/gwt/resources/css/ExtractClassNamesVisitorTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.resources.rg.CssTestCase;
+
+import java.util.Arrays;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * A test for {@link ExtractClassNamesVisitor}.
+ */
+public class ExtractClassNamesVisitorTest extends CssTestCase {
+
+ public void test() throws UnableToCompleteException {
+ ExtractClassNamesVisitor v = new ExtractClassNamesVisitor();
+
+ test(TreeLogger.NULL, "extractClassNames", false, v);
+
+ Set<String> expected = new TreeSet<String>(Arrays.asList("selector1",
+ "selector2", "selector3", "external1", "external2", "external3"));
+ Set<String> actual = new TreeSet<String>(v.getFoundClasses());
+
+ assertEquals(expected, actual);
+ }
+}
diff --git a/user/test/com/google/gwt/resources/css/extractClassNames_expected.css b/user/test/com/google/gwt/resources/css/extractClassNames_expected.css
new file mode 100644
index 0000000..1459ed4
--- /dev/null
+++ b/user/test/com/google/gwt/resources/css/extractClassNames_expected.css
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+.selector1 {
+ right: 1px;
+}
+
+.selector2 .selector3 {
+}
+
+fail {
+}
+
+@external external1 .external2, .external3;
diff --git a/user/test/com/google/gwt/resources/css/extractClassNames_test.css b/user/test/com/google/gwt/resources/css/extractClassNames_test.css
new file mode 100644
index 0000000..1459ed4
--- /dev/null
+++ b/user/test/com/google/gwt/resources/css/extractClassNames_test.css
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+.selector1 {
+ right: 1px;
+}
+
+.selector2 .selector3 {
+}
+
+fail {
+}
+
+@external external1 .external2, .external3;
diff --git a/user/test/com/google/gwt/resources/rg/CssTestCase.java b/user/test/com/google/gwt/resources/rg/CssTestCase.java
index 19075c7..01e7555 100644
--- a/user/test/com/google/gwt/resources/rg/CssTestCase.java
+++ b/user/test/com/google/gwt/resources/rg/CssTestCase.java
@@ -37,7 +37,7 @@
* Contains functions for golden-output tests that are concerned with structural
* modifications to the CSS AST.
*/
-class CssTestCase extends TestCase {
+public class CssTestCase extends TestCase {
/**
* Triggers an assertion if a CssNode is traversed more than once.