Extract util.runtime module out of util

Cleanup module dependencies: a lot of modules depended on 'frontend.java' just
to use something from 'util' module, exported by 'frontend.java', whereas they
really need nothing from 'frontend.java'. Also 'frontend.java' just exported
'util', not using anything from it.

Create a new 'util.runtime' module, which will be available at runtime. Make
'util' export 'util.runtime' and make all modules who needed these utils depend
on 'util' directly instead of 'frontend.java'
This commit is contained in:
Alexander Udalov
2013-09-17 19:26:32 +04:00
parent 15efeaba22
commit 8e59e789dc
21 changed files with 30 additions and 7 deletions
@@ -0,0 +1,145 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* 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 org.jetbrains.jet.utils;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
public class DFS {
public static <N, R> R dfs(@NotNull Collection<N> nodes, @NotNull Neighbors<N> neighbors, @NotNull Visited<N> visited, @NotNull NodeHandler<N, R> handler) {
for (N node : nodes) {
doDfs(node, neighbors, visited, handler);
}
return handler.result();
}
public static <N, R> R dfs(
@NotNull Collection<N> nodes,
@NotNull Neighbors<N> neighbors,
@NotNull NodeHandler<N, R> handler
) {
return dfs(nodes, neighbors, new VisitedWithSet<N>(), handler);
}
public static <N, R> R dfsFromNode(@NotNull N node, @NotNull Neighbors<N> neighbors, @NotNull Visited<N> visited, @NotNull NodeHandler<N, R> handler) {
doDfs(node, neighbors, visited, handler);
return handler.result();
}
public static <N> void dfsFromNode(
@NotNull N node,
@NotNull Neighbors<N> neighbors,
@NotNull Visited<N> visited
) {
dfsFromNode(node, neighbors, visited, new AbstractNodeHandler<N, Void>() {
@Override
public Void result() {
return null;
}
});
}
public static <N> List<N> topologicalOrder(@NotNull Iterable<N> nodes, @NotNull Neighbors<N> neighbors, @NotNull Visited<N> visited) {
TopologicalOrder<N> handler = new TopologicalOrder<N>();
for (N node : nodes) {
doDfs(node, neighbors, visited, handler);
}
return handler.result();
}
public static <N> List<N> topologicalOrder(@NotNull Iterable<N> nodes, @NotNull Neighbors<N> neighbors) {
return topologicalOrder(nodes, neighbors, new VisitedWithSet<N>());
}
private static <N> void doDfs(@NotNull N current, @NotNull Neighbors<N> neighbors, @NotNull Visited<N> visited, @NotNull NodeHandler<N, ?> handler) {
if (!visited.checkAndMarkVisited(current)) {
return;
}
handler.beforeChildren(current);
for (N neighbor : neighbors.getNeighbors(current)) {
doDfs(neighbor, neighbors, visited, handler);
}
handler.afterChildren(current);
}
public interface NodeHandler<N, R> {
void beforeChildren(N current);
void afterChildren(N current);
R result();
}
public interface Neighbors<N> {
@NotNull
Iterable<N> getNeighbors(N current);
}
public interface Visited<N> {
boolean checkAndMarkVisited(N current);
}
public static abstract class AbstractNodeHandler<N, R> implements NodeHandler<N, R> {
@Override
public void beforeChildren(N current) {
}
@Override
public void afterChildren(N current) {
}
}
public static class VisitedWithSet<N> implements Visited<N> {
private final Set<N> visited;
public VisitedWithSet() {
this(Sets.<N>newHashSet());
}
public VisitedWithSet(@NotNull Set<N> visited) {
this.visited = visited;
}
@Override
public boolean checkAndMarkVisited(N current) {
return visited.add(current);
}
}
public static abstract class NodeHandlerWithListResult<N, R> extends AbstractNodeHandler<N, List<R>> {
protected final LinkedList<R> result = Lists.newLinkedList();
@Override
public List<R> result() {
return result;
}
}
public static class TopologicalOrder<N> extends NodeHandlerWithListResult<N, N> {
@Override
public void afterChildren(N current) {
result.addFirst(current);
}
}
}
@@ -0,0 +1,54 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* 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 org.jetbrains.jet.utils;
import java.io.Closeable;
public class ExceptionUtils {
private ExceptionUtils() {
}
/**
* Translate exception to unchecked exception.
*
* Return type is specified to make it possible to use it like this:
* throw ExceptionUtils.rethrow(e);
* In this case compiler knows that code after this rethrowing won't be executed.
*/
public static RuntimeException rethrow(Throwable e) {
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
}
else if (e instanceof Error) {
throw (Error) e;
}
else {
throw new RuntimeException(e);
}
}
public static void closeQuietly(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (Throwable ignored) {
}
}
}
}
@@ -0,0 +1,54 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* 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 org.jetbrains.jet.utils;
import com.intellij.util.NotNullFunction;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
public abstract class NotNullMemoizedFunction<K, V> extends NullableMemoizedFunction<K, V> implements NotNullFunction<K, V> {
public static <K, V> NotNullFunction<K, V> create(@NotNull final NotNullFunction<K, V> compute) {
return new NotNullMemoizedFunction<K, V>() {
@NotNull
@Override
protected V compute(@NotNull K input) {
return compute.fun(input);
}
};
}
public NotNullMemoizedFunction(@NotNull Map<K, Object> map) {
super(map);
}
public NotNullMemoizedFunction() {
super();
}
@NotNull
@Override
public V fun(@NotNull K input) {
//noinspection ConstantConditions
return super.fun(input);
}
@NotNull
@Override
protected abstract V compute(@NotNull K input);
}
@@ -0,0 +1,65 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* 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 org.jetbrains.jet.utils;
import com.intellij.util.Function;
import com.intellij.util.NullableFunction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
public abstract class NullableMemoizedFunction<K, V> implements NullableFunction<K, V> {
public static <K, V> NullableFunction<K, V> create(@NotNull final Function<K, V> compute) {
return new NullableMemoizedFunction<K, V>() {
@Nullable
@Override
protected V compute(@NotNull K input) {
return compute.fun(input);
}
};
}
private final Map<K, Object> cache;
public NullableMemoizedFunction(@NotNull Map<K, Object> map) {
this.cache = map;
}
public NullableMemoizedFunction() {
this(new HashMap<K, Object>());
}
@Override
@Nullable
public V fun(@NotNull K input) {
Object value = cache.get(input);
if (value != null) return WrappedValues.unescapeNull(value);
V typedValue = compute(input);
Object oldValue = cache.put(input, WrappedValues.escapeNull(typedValue));
assert oldValue == null : "Race condition detected";
return typedValue;
}
@Nullable
protected abstract V compute(@NotNull K input);
}
@@ -0,0 +1,67 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* 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 org.jetbrains.jet.utils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class WrappedValues {
private static final Object NULL_VALUE = new Object();
private final static class ThrowableWrapper {
private final Throwable throwable;
private ThrowableWrapper(@NotNull Throwable throwable) {
this.throwable = throwable;
}
@NotNull
public Throwable getThrowable() {
return throwable;
}
}
private WrappedValues() {
}
@Nullable
@SuppressWarnings("unchecked")
public static <V> V unescapeNull(@NotNull Object value) {
if (value == NULL_VALUE) return null;
return (V) value;
}
@NotNull
public static <V> Object escapeNull(@Nullable V value) {
if (value == null) return NULL_VALUE;
return value;
}
@NotNull
public static Object escapeThrowable(@NotNull Throwable throwable) {
return new ThrowableWrapper(throwable);
}
@Nullable
public static <V> V unescapeExceptionOrNull(@NotNull Object value) {
if (value instanceof ThrowableWrapper) {
throw ExceptionUtils.rethrow(((ThrowableWrapper) value).getThrowable());
}
return unescapeNull(value);
}
}
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="PROVIDED" name="intellij-core" level="project" />
</component>
</module>