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:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user