Fix plugin ordering. Exclude branches from travis

This commit is contained in:
Alexey Andreev 2015-10-12 20:51:46 +03:00
parent c7026c1299
commit f6bc6f2fcf
5 changed files with 77 additions and 17 deletions

View File

@ -4,6 +4,10 @@ jdk:
cache:
directories:
- $HOME/.m2
branches:
only:
- master
- /^release-.+$/
script: >
mvn test \
-Dteavm.test.skip=false \

View File

@ -766,7 +766,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
* obtains all implementation classes that are enumerated there.</p>
*/
public void installPlugins() {
for (TeaVMPlugin plugin : ServiceLoader.load(TeaVMPlugin.class, classLoader)) {
for (TeaVMPlugin plugin : TeaVMPluginLoader.load(classLoader)) {
plugin.install(this);
}
}

View File

@ -73,7 +73,7 @@ public final class TeaVMPluginLoader {
.collect(Collectors.toList());
}
public static List<String> orderPlugins(ClassLoader classLoader, Set<String> classNames) {
static List<String> orderPlugins(ClassLoader classLoader, Set<String> classNames) {
Map<String, PluginDescriptor> descriptors = new HashMap<>();
try {
for (String className : classNames) {
@ -160,11 +160,11 @@ public final class TeaVMPluginLoader {
throw new IllegalStateException("Plugin " + descriptor.name
+ " has both before and after annotations");
}
descriptor.beforeList.addAll(Arrays.asList(descriptor.before));
for (String after : descriptor.after) {
PluginDescriptor afterDescriptor = descriptors.get(after);
if (afterDescriptor != null && afterDescriptor.reachable) {
afterDescriptor.beforeList.add(descriptor.name);
descriptor.afterList.addAll(Arrays.asList(descriptor.after));
for (String before : descriptor.before) {
PluginDescriptor beforeDescriptor = descriptors.get(before);
if (beforeDescriptor != null && beforeDescriptor.reachable) {
beforeDescriptor.afterList.add(descriptor.name);
}
}
}
@ -180,14 +180,15 @@ public final class TeaVMPluginLoader {
}
path.add(descriptor.name);
for (String before : descriptor.beforeList) {
PluginDescriptor beforeDescriptor = descriptors.get(before);
if (beforeDescriptor != null) {
if (visited.contains(before) && !emmited.contains(before)) {
for (String after : descriptor.afterList) {
PluginDescriptor afterDescriptor = descriptors.get(after);
if (afterDescriptor != null && afterDescriptor.reachable) {
if (visited.contains(after) && !emmited.contains(after)) {
List<String> loop = new ArrayList<>();
Collections.reverse(path);
for (String pathElem : path) {
loop.add(pathElem);
if (pathElem.equals(descriptor.name)) {
if (pathElem.equals(afterDescriptor.name)) {
break;
}
}
@ -195,7 +196,7 @@ public final class TeaVMPluginLoader {
throw new IllegalStateException("Circular dependency found: " + loop.stream()
.collect(Collectors.joining(" -> ")));
}
orderDescriptors(beforeDescriptor, descriptors, list, visited, emmited, path);
orderDescriptors(afterDescriptor, descriptors, list, visited, emmited, path);
}
}
@ -260,7 +261,7 @@ public final class TeaVMPluginLoader {
String[] requires = new String[0];
String[] before = new String[0];
String[] after = new String[0];
List<String> beforeList = new ArrayList<>();
List<String> afterList = new ArrayList<>();
boolean reachable;
}
}

View File

@ -15,12 +15,13 @@
*/
package org.teavm.vm;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.Test;
import org.teavm.vm.spi.After;
import org.teavm.vm.spi.Before;
import org.teavm.vm.spi.Requires;
import org.teavm.vm.spi.TeaVMHost;
@ -37,6 +38,25 @@ public class PluginLoaderTest {
assertThat(plugins.size(), is(2));
assertThat(plugins.get(0), is(B.class.getName()));
assertThat(plugins.get(1), is(A.class.getName()));
plugins = order(C.class, D.class);
assertThat(plugins.size(), is(2));
assertThat(plugins.get(0), is(C.class.getName()));
assertThat(plugins.get(1), is(D.class.getName()));
}
@Test
public void respectsPluginDependency() {
List<String> plugins = order(B.class);
assertThat(plugins.size(), is(0));
plugins = order(A.class);
assertThat(plugins.size(), is(1));
}
@Test(expected = IllegalStateException.class)
public void detectsCircularDependency() {
order(Pre.class, Head.class, Tail.class);
}
private List<String> order(Class<?>... classes) {
@ -57,4 +77,39 @@ public class PluginLoaderTest {
public void install(TeaVMHost host) {
}
}
static class C implements TeaVMPlugin {
@Override
public void install(TeaVMHost host) {
}
}
@After(C.class)
@Requires(C.class)
static class D implements TeaVMPlugin {
@Override
public void install(TeaVMHost host) {
}
}
@Before(Head.class)
static class Pre implements TeaVMPlugin {
@Override
public void install(TeaVMHost host) {
}
}
@Before(Tail.class)
static class Head implements TeaVMPlugin {
@Override
public void install(TeaVMHost host) {
}
}
@Before(Head.class)
static class Tail implements TeaVMPlugin {
@Override
public void install(TeaVMHost host) {
}
}
}

View File

@ -243,7 +243,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.15</version>
<version>2.16</version>
<executions>
<execution>
<id>validate</id>