Fix constant evaluation.

If you try to access a constant through CssResource interface
with a definition referring to a function or another constant,
the returned value was not correct.

This patch fixes also the AssertionError introduced in
a previous (reverted) patch when using constants with custom
function.

Bug: issue 9113
Change-Id: Icc5adc94990ddb627d119f8bab06870ffc66450a
diff --git a/user/src/com/google/gwt/resources/gss/CollectAndRemoveConstantDefinitions.java b/user/src/com/google/gwt/resources/gss/CollectAndRemoveConstantDefinitions.java
new file mode 100644
index 0000000..dda7ff6
--- /dev/null
+++ b/user/src/com/google/gwt/resources/gss/CollectAndRemoveConstantDefinitions.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2014 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.gss;
+
+import com.google.gwt.thirdparty.common.css.compiler.ast.CssCompilerPass;
+import com.google.gwt.thirdparty.common.css.compiler.ast.CssDefinitionNode;
+import com.google.gwt.thirdparty.common.css.compiler.ast.CssTree;
+import com.google.gwt.thirdparty.common.css.compiler.ast.MutatingVisitController;
+import com.google.gwt.thirdparty.common.css.compiler.passes.CollectConstantDefinitions;
+
+/**
+ * A pass that collects the constant definitions inside the tree. This pass removes the constant
+ * definitions during the collect.
+ */
+public class CollectAndRemoveConstantDefinitions extends CollectConstantDefinitions
+    implements CssCompilerPass {
+
+  private final MutatingVisitController visitController;
+
+  public CollectAndRemoveConstantDefinitions(CssTree tree) {
+    this(tree.getMutatingVisitController());
+  }
+
+  public CollectAndRemoveConstantDefinitions(MutatingVisitController visitController) {
+    super(visitController);
+
+    this.visitController = visitController;
+  }
+
+  @Override
+  public boolean enterDefinition(CssDefinitionNode node) {
+    super.enterDefinition(node);
+
+    visitController.removeCurrentNode();
+
+    return false;
+  }
+}
diff --git a/user/src/com/google/gwt/resources/gss/ConstantResolver.java b/user/src/com/google/gwt/resources/gss/ConstantResolver.java
deleted file mode 100644
index 22a92dd..0000000
--- a/user/src/com/google/gwt/resources/gss/ConstantResolver.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2015 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.gss;
-
-import com.google.gwt.thirdparty.common.css.compiler.ast.CssCompilerPass;
-import com.google.gwt.thirdparty.common.css.compiler.ast.CssConstantReferenceNode;
-import com.google.gwt.thirdparty.common.css.compiler.ast.CssDefinitionNode;
-import com.google.gwt.thirdparty.common.css.compiler.ast.CssTree;
-import com.google.gwt.thirdparty.common.css.compiler.ast.CssValueNode;
-import com.google.gwt.thirdparty.common.css.compiler.ast.DefaultTreeVisitor;
-import com.google.gwt.thirdparty.common.css.compiler.ast.MutatingVisitController;
-import com.google.gwt.thirdparty.common.css.compiler.passes.CollectConstantDefinitions;
-import com.google.gwt.thirdparty.common.css.compiler.passes.ConstantDefinitions;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A compiler pass that resolves constants to their values.
- */
-public class ConstantResolver extends DefaultTreeVisitor implements CssCompilerPass {
-
-  private final MutatingVisitController visitController;
-  private CssTree cssTree;
-  private ConstantDefinitions constantDefinitions;
-
-  public ConstantResolver(CssTree cssTree, MutatingVisitController visitController) {
-    this.cssTree = cssTree;
-    this.visitController = visitController;
-  }
-
-  @Override
-  public boolean enterDefinition(CssDefinitionNode node) {
-    List<CssValueNode> newParameters = new ArrayList<>();
-    for (CssValueNode parameter : node.getParameters()) {
-      if (parameter instanceof CssConstantReferenceNode) {
-        CssConstantReferenceNode cssConstantParameter = (CssConstantReferenceNode) parameter;
-        String constantName = cssConstantParameter.getValue();
-        // Retrieve the actual value of this constant
-        CssDefinitionNode constantDefinition = constantDefinitions.getConstantDefinition(constantName);
-        newParameters.addAll(constantDefinition.getParameters());
-      } else {
-        // Here we are just collecting unchanged parameters so they will get readded
-        // to the parameter list
-        newParameters.add(parameter);
-      }
-    }
-    node.setParameters(newParameters);
-    return true;
-  }
-
-  @Override
-  public void runPass() {
-    CollectConstantDefinitions constantDefinitionsCollector =
-        new CollectConstantDefinitions(cssTree);
-    constantDefinitionsCollector.runPass();
-    constantDefinitions = constantDefinitionsCollector.getConstantDefinitions();
-
-    visitController.startVisit(this);
-  }
-}
diff --git a/user/src/com/google/gwt/resources/rg/GssResourceGenerator.java b/user/src/com/google/gwt/resources/rg/GssResourceGenerator.java
index 89c9168..73520af 100644
--- a/user/src/com/google/gwt/resources/rg/GssResourceGenerator.java
+++ b/user/src/com/google/gwt/resources/rg/GssResourceGenerator.java
@@ -45,7 +45,7 @@
 import com.google.gwt.resources.ext.ResourceGeneratorUtil;
 import com.google.gwt.resources.ext.SupportsGeneratorResultCaching;
 import com.google.gwt.resources.gss.BooleanConditionCollector;
-import com.google.gwt.resources.gss.ConstantResolver;
+import com.google.gwt.resources.gss.CollectAndRemoveConstantDefinitions;
 import com.google.gwt.resources.gss.CreateRuntimeConditionalNodes;
 import com.google.gwt.resources.gss.CssPrinter;
 import com.google.gwt.resources.gss.ExtendedEliminateConditionalNodes;
@@ -719,7 +719,6 @@
     new ProcessKeyframes(cssTree.getMutatingVisitController(), errorManager, true, true).runPass();
     new ProcessRefiners(cssTree.getMutatingVisitController(), errorManager, true).runPass();
     new MarkNonFlippableNodes(cssTree.getMutatingVisitController(), errorManager).runPass();
-    new ConstantResolver(cssTree, cssTree.getMutatingVisitController()).runPass();
   }
 
   private ConstantDefinitions optimizeTree(CssParsingResult cssParsingResult, ResourceContext context,
@@ -761,7 +760,7 @@
     collectConstantDefinitionsPass.runPass();
 
     ReplaceConstantReferences replaceConstantReferences = new ReplaceConstantReferences(cssTree,
-        collectConstantDefinitionsPass.getConstantDefinitions(), true, errorManager, false);
+        collectConstantDefinitionsPass.getConstantDefinitions(), false, errorManager, false);
     replaceConstantReferences.runPass();
 
     new ImageSpriteCreator(cssTree.getMutatingVisitController(), context, errorManager).runPass();
@@ -770,6 +769,10 @@
     new ResolveCustomFunctionNodes(cssTree.getMutatingVisitController(), errorManager,
         gssFunctionMap, true, allowedNonStandardFunctions).runPass();
 
+    // collect the final value of the constants and remove them.
+    collectConstantDefinitionsPass = new CollectAndRemoveConstantDefinitions(cssTree);
+    collectConstantDefinitionsPass.runPass();
+
     if (simplifyCss) {
       // Eliminate empty rules.
       new EliminateEmptyRulesetNodes(cssTree.getMutatingVisitController()).runPass();
diff --git a/user/test/com/google/gwt/resources/client/gss/GssResourceTest.java b/user/test/com/google/gwt/resources/client/gss/GssResourceTest.java
index 3bd3117..1e6cbfa 100644
--- a/user/test/com/google/gwt/resources/client/gss/GssResourceTest.java
+++ b/user/test/com/google/gwt/resources/client/gss/GssResourceTest.java
@@ -180,9 +180,11 @@
   }
 
   public void testConstantAccess() {
-    assertEquals("#012345", res().constants().COLOR1());
-    assertEquals("#012345", res().constants().MYCOLOR());
-    assertEquals("#012345", res().constants().MYCOLOR1());
+    assertEquals("10px", res().constants().padding2());
+    assertEquals("#012345", res().constants().color1());
+    assertEquals("#012345", res().constants().mycolor());
+    assertEquals("#012345", res().constants().mycolor1());
+    assertEquals(10, res().constants().margin());
   }
 
   public void testEmpty() {
diff --git a/user/test/com/google/gwt/resources/client/gss/TestResources.java b/user/test/com/google/gwt/resources/client/gss/TestResources.java
index 8e9ec5d..42d0b47 100644
--- a/user/test/com/google/gwt/resources/client/gss/TestResources.java
+++ b/user/test/com/google/gwt/resources/client/gss/TestResources.java
@@ -166,9 +166,15 @@
    * Used to test constants that use other constants.
    */
   interface Constants extends CssResource {
-    String COLOR1();
-    String MYCOLOR();
-    String MYCOLOR1();
+    String color1();
+
+    int margin();
+
+    String mycolor();
+
+    String mycolor1();
+
+    String padding2();
   }
 
   /**
diff --git a/user/test/com/google/gwt/resources/client/gss/constants.gss b/user/test/com/google/gwt/resources/client/gss/constants.gss
index f297b65..e19f114 100644
--- a/user/test/com/google/gwt/resources/client/gss/constants.gss
+++ b/user/test/com/google/gwt/resources/client/gss/constants.gss
@@ -1,3 +1,16 @@
-@def COLOR1 #012345;
+@if (is("custom.one", "bar")) {
+  @def COLOR1 #012345;
+}
+@else {
+  @def COLOR1 #543210;
+}
+
 @def MYCOLOR COLOR1;
 @def MYCOLOR1 MYCOLOR;
+
+@def PADDING add(5px, 5px);
+@def PADDING2 PADDING;
+
+@def MARGIN1 5px;
+@def MARGIN2 5px;
+@def MARGIN add(MARGIN1, MARGIN2);