Author: [email protected]
Date: Mon Jul 13 16:05:32 2009
New Revision: 5727
Added:
trunk/dev/core/test/com/google/gwt/dev/cfg/
trunk/dev/core/test/com/google/gwt/dev/cfg/ModuleDefTest.java
Modified:
trunk/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
trunk/dev/core/src/com/google/gwt/dev/cfg/ModuleDefSchema.java
Log:
Ensure that a <define-linker> after an <add-linker> will correctly replace
the previously-defined implementation.
Patch by: bobv
Review by: scottb
Modified: trunk/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java
==============================================================================
--- trunk/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java (original)
+++ trunk/dev/core/src/com/google/gwt/dev/cfg/ModuleDef.java Mon Jul 13
16:05:32 2009
@@ -72,9 +72,9 @@
return true;
}
- private final Set<Class<? extends Linker>> activeLinkers = new
LinkedHashSet<Class<? extends Linker>>();
+ private final Set<String> activeLinkers = new LinkedHashSet<String>();
- private Class<? extends Linker> activePrimaryLinker;
+ private String activePrimaryLinker;
private final List<String> entryPointTypeNames = new ArrayList<String>();
@@ -134,9 +134,9 @@
LinkerOrder order = clazz.getAnnotation(LinkerOrder.class);
if (order.value() == Order.PRIMARY) {
- activePrimaryLinker = clazz;
+ activePrimaryLinker = name;
} else {
- activeLinkers.add(clazz);
+ activeLinkers.add(name);
}
}
@@ -196,7 +196,36 @@
entryPointTypeNames.clear();
}
- public void defineLinker(String name, Class<? extends Linker> linker) {
+ /**
+ * Associate a Linker class with a symbolic name. If the name had been
+ * previously assigned, this method will redefine the name. If the
redefined
+ * linker had been previously added to the set of active linkers, the old
+ * active linker will be replaced with the new linker.
+ */
+ public void defineLinker(TreeLogger logger, String name,
+ Class<? extends Linker> linker) throws UnableToCompleteException {
+ Class<? extends Linker> old = getLinker(name);
+ if (old != null) {
+ // Redefining an existing name
+ if (activePrimaryLinker.equals(name)) {
+ // Make sure the new one is also a primary linker
+ if (!linker.getAnnotation(LinkerOrder.class).value().equals(
+ Order.PRIMARY)) {
+ logger.log(TreeLogger.ERROR, "Redefining primary linker " + name
+ + " with non-primary implementation " + linker.getName());
+ throw new UnableToCompleteException();
+ }
+
+ } else if (activeLinkers.contains(name)) {
+ // Make sure it's a not a primary linker
+ if (linker.getAnnotation(LinkerOrder.class).value().equals(
+ Order.PRIMARY)) {
+ logger.log(TreeLogger.ERROR, "Redefining non-primary linker " +
name
+ + " with primary implementation " + linker.getName());
+ throw new UnableToCompleteException();
+ }
+ }
+ }
linkerTypesByName.put(name, linker);
}
@@ -225,11 +254,17 @@
}
public Set<Class<? extends Linker>> getActiveLinkers() {
- return activeLinkers;
+ Set<Class<? extends Linker>> toReturn = new LinkedHashSet<Class<?
extends Linker>>();
+ for (String linker : activeLinkers) {
+ assert linkerTypesByName.containsKey(linker) : linker;
+ toReturn.add(linkerTypesByName.get(linker));
+ }
+ return toReturn;
}
public Class<? extends Linker> getActivePrimaryLinker() {
- return activePrimaryLinker;
+ assert linkerTypesByName.containsKey(activePrimaryLinker) :
activePrimaryLinker;
+ return linkerTypesByName.get(activePrimaryLinker);
}
public String[] getAllPublicFiles() {
Modified: trunk/dev/core/src/com/google/gwt/dev/cfg/ModuleDefSchema.java
==============================================================================
--- trunk/dev/core/src/com/google/gwt/dev/cfg/ModuleDefSchema.java
(original)
+++ trunk/dev/core/src/com/google/gwt/dev/cfg/ModuleDefSchema.java Mon Jul
13 16:05:32 2009
@@ -250,7 +250,7 @@
+ LinkerOrder.class.getName() + " annotation", null);
throw new UnableToCompleteException();
}
- moduleDef.defineLinker(name.name, linker);
+ moduleDef.defineLinker(logger, name.name, linker);
return null;
}
Added: trunk/dev/core/test/com/google/gwt/dev/cfg/ModuleDefTest.java
==============================================================================
--- (empty file)
+++ trunk/dev/core/test/com/google/gwt/dev/cfg/ModuleDefTest.java Mon Jul
13 16:05:32 2009
@@ -0,0 +1,155 @@
+/*
+ * 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.dev.cfg;
+
+import com.google.gwt.core.ext.Linker;
+import com.google.gwt.core.ext.LinkerContext;
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.core.ext.linker.ArtifactSet;
+import com.google.gwt.core.ext.linker.LinkerOrder;
+import com.google.gwt.core.ext.linker.LinkerOrder.Order;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Runs tests directly on ModuleDef.
+ */
+public class ModuleDefTest extends TestCase {
+
+ static class FakeLinker extends Linker {
+ @Override
+ public String getDescription() {
+ return null;
+ }
+
+ @Override
+ public ArtifactSet link(TreeLogger logger, LinkerContext context,
+ ArtifactSet artifacts) throws UnableToCompleteException {
+ return null;
+ }
+
+ @Override
+ public ArtifactSet relink(TreeLogger logger, LinkerContext context,
+ ArtifactSet newArtifacts) throws UnableToCompleteException {
+ return null;
+ }
+ }
+
+ @LinkerOrder(Order.POST)
+ static class FakeLinkerPost extends FakeLinker {
+ }
+
+ @LinkerOrder(Order.POST)
+ static class FakeLinkerPost2 extends FakeLinker {
+ }
+
+ @LinkerOrder(Order.PRE)
+ static class FakeLinkerPre extends FakeLinker {
+ }
+
+ @LinkerOrder(Order.PRE)
+ static class FakeLinkerPre2 extends FakeLinker {
+ }
+
+ @LinkerOrder(Order.PRIMARY)
+ static class FakeLinkerPrimary extends FakeLinker {
+ }
+
+ @LinkerOrder(Order.PRIMARY)
+ static class FakeLinkerPrimary2 extends FakeLinker {
+ }
+
+ public void testLinkerOrder() throws UnableToCompleteException {
+ ModuleDef def = new ModuleDef("fake");
+
+ def.defineLinker(TreeLogger.NULL, "pre", FakeLinkerPre.class);
+ def.defineLinker(TreeLogger.NULL, "pre2", FakeLinkerPre2.class);
+ def.defineLinker(TreeLogger.NULL, "post", FakeLinkerPost.class);
+ def.defineLinker(TreeLogger.NULL, "post2", FakeLinkerPost2.class);
+ def.defineLinker(TreeLogger.NULL, "primary", FakeLinkerPrimary.class);
+
+ def.addLinker("pre2");
+ def.addLinker("pre");
+ def.addLinker("post");
+ def.addLinker("post2");
+ def.addLinker("primary");
+
+ Class<?>[] expectedClasses = {
+ FakeLinkerPre2.class, FakeLinkerPre.class, FakeLinkerPost.class,
+ FakeLinkerPost2.class};
+ assertEquals(FakeLinkerPrimary.class, def.getActivePrimaryLinker());
+ // Test iteration order
+ assertEquals(Arrays.asList(expectedClasses),
+ new ArrayList<Class<? extends Linker>>(def.getActiveLinkers()));
+ }
+
+ public void testLinkerRedefinition() throws UnableToCompleteException {
+ ModuleDef def = new ModuleDef("fake");
+
+ def.defineLinker(TreeLogger.NULL, "pre", FakeLinkerPre.class);
+ def.defineLinker(TreeLogger.NULL, "post", FakeLinkerPost.class);
+ def.defineLinker(TreeLogger.NULL, "primary", FakeLinkerPrimary.class);
+ def.addLinker("pre");
+ def.addLinker("post");
+ def.addLinker("primary");
+
+ def.defineLinker(TreeLogger.NULL, "pre", FakeLinkerPre2.class);
+ def.defineLinker(TreeLogger.NULL, "post", FakeLinkerPost2.class);
+ def.defineLinker(TreeLogger.NULL, "primary", FakeLinkerPrimary2.class);
+ // Intentional duplication
+ def.addLinker("post");
+
+ Class<?>[] expectedClasses = {FakeLinkerPre2.class,
FakeLinkerPost2.class};
+ assertEquals(FakeLinkerPrimary2.class, def.getActivePrimaryLinker());
+ // Test iteration order
+ assertEquals(Arrays.asList(expectedClasses),
+ new ArrayList<Class<? extends Linker>>(def.getActiveLinkers()));
+ }
+
+ public void testLinkerRedefinitionErrors() throws
UnableToCompleteException {
+ ModuleDef def = new ModuleDef("fake");
+
+ def.defineLinker(TreeLogger.NULL, "pre", FakeLinkerPre.class);
+ def.defineLinker(TreeLogger.NULL, "post", FakeLinkerPost.class);
+ def.defineLinker(TreeLogger.NULL, "primary", FakeLinkerPrimary.class);
+ def.addLinker("pre");
+ def.addLinker("post");
+ def.addLinker("primary");
+
+ try {
+ def.defineLinker(TreeLogger.NULL, "pre", FakeLinkerPrimary.class);
+ fail();
+ } catch (UnableToCompleteException e) {
+ // OK
+ }
+ try {
+ def.defineLinker(TreeLogger.NULL, "post", FakeLinkerPrimary.class);
+ fail();
+ } catch (UnableToCompleteException e) {
+ // OK
+ }
+ try {
+ def.defineLinker(TreeLogger.NULL, "primary", FakeLinkerPre.class);
+ fail();
+ } catch (UnableToCompleteException e) {
+ // OK
+ }
+ }
+}
--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---