Goto defintion for releases
This commit is contained in:
@@ -10,6 +10,8 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BinaryOperator;
|
||||
@@ -19,6 +21,7 @@ import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.collect.HashMultiset;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMultiset;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
@@ -64,4 +67,36 @@ public class CollectorUtil {
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> Collector<T, ArrayList<T>, ImmutableList<T>> toImmutableList() {
|
||||
return new Collector<T, ArrayList<T>, ImmutableList<T>>() {
|
||||
|
||||
@Override
|
||||
public Supplier<ArrayList<T>> supplier() {
|
||||
return ArrayList::new;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiConsumer<ArrayList<T>, T> accumulator() {
|
||||
return (a, e) -> a.add(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryOperator<ArrayList<T>> combiner() {
|
||||
return (a1, a2) -> {
|
||||
a1.addAll(a2);
|
||||
return a1;
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public Function<ArrayList<T>, ImmutableList<T>> finisher() {
|
||||
return ImmutableList::copyOf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Collector.Characteristics> characteristics() {
|
||||
return ImmutableSet.of(Collector.Characteristics.UNORDERED);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.yaml.ast;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.util.StaleFallbackCache;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
public class YamlAstCache {
|
||||
|
||||
private final StaleFallbackCache<String, YamlFileAST> asts = new StaleFallbackCache<>();
|
||||
private final YamlParser parser;
|
||||
|
||||
public YamlAstCache() {
|
||||
Yaml yaml = new Yaml();
|
||||
this.parser = new YamlParser(yaml);
|
||||
}
|
||||
|
||||
public YamlASTProvider getAstProvider(boolean allowStaleAsts) {
|
||||
return (IDocument doc) -> {
|
||||
String uri = doc.getUri();
|
||||
if (uri!=null) {
|
||||
return asts.get(uri, doc.getVersion(), allowStaleAsts, () -> {
|
||||
return parser.getAST(doc);
|
||||
});
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
public YamlFileAST getSafeAst(IDocument doc) {
|
||||
return getSafeAst(doc, true);
|
||||
}
|
||||
|
||||
public YamlFileAST getAst(IDocument doc, boolean allowStaleAst) throws Exception {
|
||||
return getAstProvider(allowStaleAst).getAST(doc);
|
||||
}
|
||||
|
||||
public YamlFileAST getSafeAst(IDocument doc, boolean allowStaleAst) {
|
||||
if (doc!=null) {
|
||||
try {
|
||||
return getAst(doc, allowStaleAst);
|
||||
} catch (Exception e) {
|
||||
//ignored
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -164,5 +164,15 @@ public class ASTTypeCache implements ITypeCollector {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection<Node> getNodes(String uri, YType type) {
|
||||
NodeTypes nodeMap = getNodeTypes(uri);
|
||||
if (nodeMap!=null) {
|
||||
Collection<Node> nodes = nodeMap.getNodes(type);
|
||||
if (nodes!=null) {
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.yaml.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
import org.springframework.ide.vscode.commons.util.ExceptionUtil;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
/**
|
||||
* A simple cache implementation that provides an option for lookups to fallback
|
||||
* to a 'stale' cache entry when computing a current one fails.
|
||||
*/
|
||||
public class StaleFallbackCache<K, V>{
|
||||
|
||||
private static class Versioned<T> {
|
||||
int version;
|
||||
T it;
|
||||
public Versioned(int version, T it) {
|
||||
super();
|
||||
this.version = version;
|
||||
this.it = it;
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((it == null) ? 0 : it.hashCode());
|
||||
result = prime * result + version;
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Versioned other = (Versioned) obj;
|
||||
if (it == null) {
|
||||
if (other.it != null)
|
||||
return false;
|
||||
} else if (!it.equals(other.it))
|
||||
return false;
|
||||
if (version != other.version)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Versioned [version=" + version + ", it=" + it + "]";
|
||||
}
|
||||
}
|
||||
|
||||
Map<K, V> staleEntries = new HashMap<>();
|
||||
Cache<K, Versioned<CompletableFuture<V>>> latestEntries = CacheBuilder.newBuilder().build();
|
||||
|
||||
public synchronized V get(K key, int version, boolean allowStaleEntries, Callable<? extends V> valueLoader) throws Exception {
|
||||
Versioned<CompletableFuture<V>> latest = latestEntries.get(key, () -> new Versioned<>(version, load(valueLoader)));
|
||||
if (latest.version!=version) {
|
||||
latestEntries.invalidate(key);
|
||||
keepStaleBackup(key, latest);
|
||||
latest = latestEntries.get(key, () -> new Versioned<>(version, load(valueLoader)));
|
||||
}
|
||||
if (!allowStaleEntries) {
|
||||
return future_get(version, latest);
|
||||
} else {
|
||||
if (latest.it.isCompletedExceptionally()) {
|
||||
V staleValue = staleEntries.get(key);
|
||||
if (staleValue!=null) {
|
||||
return staleValue;
|
||||
}
|
||||
}
|
||||
return future_get(latest.it);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a stale entry is found in the 'latest' map. This method is
|
||||
* responsible for determining if the entry should be kept as a staleBackup,
|
||||
* and store it.
|
||||
*/
|
||||
private void keepStaleBackup(K key, Versioned<CompletableFuture<V>> latest) {
|
||||
try {
|
||||
staleEntries.put(key, latest.it.get());
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
//ignore: This means its a 'bad' entry and so we don't want to keep it
|
||||
// as a 'stale backup'.
|
||||
}
|
||||
}
|
||||
|
||||
private V future_get(int wantedVersion, Versioned<CompletableFuture<V>> versioned) throws Exception {
|
||||
Assert.isLegal(wantedVersion==versioned.version);
|
||||
return future_get(versioned.it);
|
||||
}
|
||||
|
||||
private V future_get(CompletableFuture<V> f) throws Exception {
|
||||
try {
|
||||
return f.get();
|
||||
} catch (InterruptedException e) {
|
||||
throw e;
|
||||
} catch (ExecutionException e) {
|
||||
throw ExceptionUtil.exception(e.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
private CompletableFuture<V> load(Callable<? extends V> valueLoader) {
|
||||
CompletableFuture<V> future = new CompletableFuture<V>();
|
||||
try {
|
||||
V value = valueLoader.call();
|
||||
Assert.isNotNull(value);
|
||||
future.complete(value);
|
||||
} catch (Throwable e) {
|
||||
future.completeExceptionally(e);
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -712,7 +712,7 @@ public class Editor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the position of (the middle of) a snippet of text in the document.
|
||||
* Determines the position of a snippet of text in the document.
|
||||
*
|
||||
* @param contextSnippet A larger snippet containing the actual snippet to look for.
|
||||
* This larger snippet is used to narrow the section of the document
|
||||
@@ -725,6 +725,10 @@ public class Editor {
|
||||
return r==null?null:r.getStart();
|
||||
}
|
||||
|
||||
public Position positionOf(String snippet) throws Exception {
|
||||
return positionOf(snippet, snippet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the range of a snippet of text in the document.
|
||||
*
|
||||
@@ -795,4 +799,5 @@ public class Editor {
|
||||
this.selectionStart = this.selectionEnd = doc.toOffset(position);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user