Skip to content

Commit 87334e3

Browse files
committed
Deprecate and replace Guava-using APIs in Scopes and QualifiedName
Part of #2975
1 parent 77020bb commit 87334e3

3 files changed

Lines changed: 96 additions & 66 deletions

File tree

org.eclipse.xtext.tests/src/org/eclipse/xtext/naming/QualifiedNameTest.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.io.ByteArrayOutputStream;
1313
import java.io.IOException;
1414
import java.util.Collections;
15+
import java.util.function.Function;
1516

1617
import org.eclipse.emf.ecore.resource.impl.BinaryResourceImpl;
1718
import org.eclipse.emf.ecore.resource.impl.BinaryResourceImpl.EObjectInputStream;
@@ -21,8 +22,6 @@
2122
import org.junit.Assert;
2223
import org.junit.Test;
2324

24-
import com.google.common.base.Function;
25-
2625
/**
2726
* @author Jan Koehnlein - Initial contribution and API
2827
*/
@@ -93,7 +92,7 @@ public void testAppendNull() {
9392
assertTrue(qn.startsWithIgnoreCase(qn2));
9493
assertFalse(qn2.startsWithIgnoreCase(qn));
9594

96-
assertThrows(IllegalArgumentException.class, ()->qn1.startsWith(null));
95+
assertThrows(NullPointerException.class, () -> qn1.startsWith(null));
9796
}
9897

9998
@Test public void testSkip() throws Exception {
@@ -213,12 +212,7 @@ public void testAppendNull() {
213212
}
214213

215214
@Test public void testWrapper() throws Exception {
216-
Function<String, String> identity = new Function<String, String>() {
217-
@Override
218-
public String apply(String from) {
219-
return from;
220-
}
221-
};
215+
Function<String, String> identity = from -> from;
222216
Function<String, QualifiedName> wrapper = QualifiedName.wrapper(identity);
223217
assertEquals(QualifiedName.create(""), wrapper.apply(""));
224218
assertEquals(null, wrapper.apply(null));

org.eclipse.xtext/src/org/eclipse/xtext/naming/QualifiedName.java

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,14 @@
1212
import java.util.Arrays;
1313
import java.util.Collections;
1414
import java.util.List;
15+
import java.util.Objects;
16+
import java.util.function.Function;
1517

1618
import org.eclipse.emf.common.util.CommonUtil;
1719
import org.eclipse.emf.ecore.resource.impl.BinaryResourceImpl.EObjectInputStream;
1820
import org.eclipse.emf.ecore.resource.impl.BinaryResourceImpl.EObjectOutputStream;
1921
import org.eclipse.xtext.util.Strings;
2022

21-
import com.google.common.base.Function;
22-
import com.google.common.base.Preconditions;
23-
2423
/**
2524
* A datatype for dealing with qualified names.
2625
* Instances are usually provided by a {@link IQualifiedNameProvider}.
@@ -239,18 +238,26 @@ public static QualifiedName create(String singleSegment) {
239238
return new QualifiedName(intern(singleSegment));
240239
}
241240

241+
/**
242+
* Wraps a name function to return a qualified name. Returns null if the name function returns null.
243+
* @deprecated Instead use {@link #wrapper(Function)}
244+
*/
245+
@Deprecated(since = "2.35.0", forRemoval = true)
246+
public static <F> com.google.common.base.Function<F, QualifiedName> wrapper(
247+
com.google.common.base.Function<F, String> nameFunction) {
248+
return wrapper((Function<F, String>) nameFunction)::apply;
249+
}
250+
242251
/**
243252
* Wraps a name function to return a qualified name. Returns null if the name function returns null.
244253
*/
245254
public static <F> Function<F, QualifiedName> wrapper(final Function<F, String> nameFunction) {
246-
return new Function<F, QualifiedName>() {
247-
@Override
248-
public QualifiedName apply(F from) {
249-
String name = nameFunction.apply(from);
250-
if (name == null)
251-
return null;
252-
return QualifiedName.create(name);
255+
return from -> {
256+
String name = nameFunction.apply(from);
257+
if (name == null) {
258+
return null;
253259
}
260+
return QualifiedName.create(name);
254261
};
255262
}
256263

@@ -486,7 +493,7 @@ public boolean startsWithIgnoreCase(QualifiedName prefix) {
486493
}
487494

488495
protected boolean startsWith(QualifiedName prefix, boolean ignoreCase) {
489-
Preconditions.checkArgument(prefix != null, "prefix must not be null");
496+
Objects.requireNonNull(prefix, "prefix must not be null");
490497

491498
if (prefix.getSegmentCount() > getSegmentCount()) {
492499
return false;
Lines changed: 75 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2009 itemis AG (http://www.itemis.eu) and others.
2+
* Copyright (c) 2009, 2024 itemis AG (http://www.itemis.eu) and others.
33
* This program and the accompanying materials are made available under the
44
* terms of the Eclipse Public License 2.0 which is available at
55
* http://www.eclipse.org/legal/epl-2.0.
@@ -9,8 +9,13 @@
99
*******************************************************************************/
1010
package org.eclipse.xtext.scoping;
1111

12-
import java.util.ArrayList;
12+
import java.util.LinkedHashMap;
13+
import java.util.LinkedHashSet;
14+
import java.util.List;
1315
import java.util.Map;
16+
import java.util.Objects;
17+
import java.util.Set;
18+
import java.util.function.Function;
1419

1520
import org.eclipse.emf.ecore.EAttribute;
1621
import org.eclipse.emf.ecore.EClass;
@@ -22,14 +27,7 @@
2227
import org.eclipse.xtext.scoping.impl.SimpleScope;
2328
import org.eclipse.xtext.util.SimpleAttributeResolver;
2429

25-
import com.google.common.base.Function;
26-
import com.google.common.base.Predicate;
27-
import com.google.common.base.Predicates;
2830
import com.google.common.collect.Iterables;
29-
import com.google.common.collect.LinkedHashMultimap;
30-
import com.google.common.collect.Lists;
31-
import com.google.common.collect.Maps;
32-
import com.google.common.collect.Multimap;
3331

3432
/**
3533
* This class contains static utility functions to create and work on {@link IScope} and {@link IEObjectDescription}
@@ -40,12 +38,7 @@
4038
public class Scopes {
4139

4240
public static Iterable<IEObjectDescription> selectCompatible(Iterable<IEObjectDescription> exportedObjects, final EClass clazz) {
43-
return Iterables.filter(exportedObjects, new Predicate<IEObjectDescription>() {
44-
@Override
45-
public boolean apply(IEObjectDescription input) {
46-
return EcoreUtil2.isAssignableFrom(clazz,input.getEClass());
47-
}
48-
});
41+
return Iterables.filter(exportedObjects, input -> EcoreUtil2.isAssignableFrom(clazz, input.getEClass()));
4942
}
5043

5144
/**
@@ -60,15 +53,25 @@ public static IScope scopeFor(Iterable<? extends EObject> elements) {
6053
* creates a scope using {@link SimpleAttributeResolver#NAME_RESOLVER} to compute the names
6154
*/
6255
public static IScope scopeFor(Iterable<? extends EObject> elements, IScope outer) {
63-
return scopeFor(elements, QualifiedName.wrapper(SimpleAttributeResolver.NAME_RESOLVER), outer);
56+
return scopeFor(elements, QualifiedName.wrapper((Function<EObject, String>) SimpleAttributeResolver.NAME_RESOLVER), outer);
57+
}
58+
59+
/**
60+
* creates a scope using the passed function to compute the names and sets the passed scope as the parent scope
61+
* @deprecated Instead use {@link #scopeFor(Iterable, Function, IScope)}
62+
*/
63+
@Deprecated(since = "2.35.0", forRemoval = true)
64+
public static <T extends EObject> IScope scopeFor(Iterable<? extends T> elements,
65+
com.google.common.base.Function<T, QualifiedName> nameComputation, IScope outer) {
66+
return scopeFor(elements, (java.util.function.Function<T, QualifiedName>) nameComputation, outer);
6467
}
6568

6669
/**
6770
* creates a scope using the passed function to compute the names and sets the passed scope as the parent scope
6871
*/
6972
public static <T extends EObject> IScope scopeFor(Iterable<? extends T> elements,
70-
final Function<T, QualifiedName> nameComputation, IScope outer) {
71-
return new SimpleScope(outer,scopedElementsFor(elements, nameComputation));
73+
Function<T, QualifiedName> nameComputation, IScope outer) {
74+
return new SimpleScope(outer, scopedElementsFor(elements, nameComputation));
7275
}
7376

7477
/**
@@ -77,7 +80,19 @@ public static <T extends EObject> IScope scopeFor(Iterable<? extends T> elements
7780
* filtered out.
7881
*/
7982
public static Iterable<IEObjectDescription> scopedElementsFor(Iterable<? extends EObject> elements) {
80-
return scopedElementsFor(elements, QualifiedName.wrapper(SimpleAttributeResolver.NAME_RESOLVER));
83+
return scopedElementsFor(elements, QualifiedName.wrapper((Function<EObject, String>) SimpleAttributeResolver.NAME_RESOLVER));
84+
}
85+
86+
/**
87+
* transforms an {@link Iterable} of {@link EObject}s into an {@link Iterable} of {@link IEObjectDescription}s computing
88+
* the name of the elements using the passed {@link Function} If the passed function returns null the object is
89+
* filtered out.
90+
* @deprecated Instead use {@link #scopedElementsFor(Iterable, Function)}
91+
*/
92+
@Deprecated(since = "2.35.0", forRemoval = true)
93+
public static <T extends EObject> Iterable<IEObjectDescription> scopedElementsFor(Iterable<? extends T> elements,
94+
com.google.common.base.Function<T, QualifiedName> nameComputation) {
95+
return scopedElementsFor(elements, (java.util.function.Function<T, QualifiedName>) nameComputation);
8196
}
8297

8398
/**
@@ -86,46 +101,60 @@ public static Iterable<IEObjectDescription> scopedElementsFor(Iterable<? extends
86101
* filtered out.
87102
*/
88103
public static <T extends EObject> Iterable<IEObjectDescription> scopedElementsFor(Iterable<? extends T> elements,
89-
final Function<T, QualifiedName> nameComputation) {
90-
Iterable<IEObjectDescription> transformed = Iterables.transform(elements,
91-
new Function<T, IEObjectDescription>() {
92-
@Override
93-
public IEObjectDescription apply(T from) {
94-
final QualifiedName qualifiedName = nameComputation.apply(from);
95-
if (qualifiedName != null)
96-
return new EObjectDescription(qualifiedName, from, null);
97-
return null;
98-
}
99-
});
100-
return Iterables.filter(transformed, Predicates.notNull());
104+
Function<T, QualifiedName> nameComputation) {
105+
Iterable<IEObjectDescription> transformed = Iterables.transform(elements, from -> {
106+
final QualifiedName qualifiedName = nameComputation.apply(from);
107+
if (qualifiedName != null)
108+
return new EObjectDescription(qualifiedName, from, null);
109+
return null;
110+
});
111+
return Iterables.filter(transformed, Objects::nonNull);
112+
}
113+
114+
/**
115+
* indexes the IEObject description using the given
116+
* @deprecated Instead use {@link #index(Iterable, Function)}
117+
*/
118+
@Deprecated(since = "2.35.0", forRemoval = true)
119+
@SuppressWarnings({ "rawtypes", "unchecked" })
120+
public static <T> com.google.common.collect.Multimap<T, IEObjectDescription> index(
121+
Iterable<IEObjectDescription> descriptions,
122+
com.google.common.base.Function<IEObjectDescription, T> indexer) {
123+
124+
Map<T, Set<IEObjectDescription>> index = index(descriptions, (Function<IEObjectDescription, T>) indexer);
125+
return com.google.common.collect.Multimaps.newMultimap((Map) index, LinkedHashSet::new);
101126
}
102127

103128
/**
104129
* indexes the IEObject description using the given
105130
*/
106-
public static <T> Multimap<T,IEObjectDescription> index(Iterable<IEObjectDescription> descriptions, Function<IEObjectDescription,T> indexer) {
107-
ArrayList<IEObjectDescription> list = Lists.newArrayList(descriptions);
108-
LinkedHashMultimap<T, IEObjectDescription> multimap = LinkedHashMultimap.create(list.size(),1);
109-
for (IEObjectDescription desc : list) {
110-
multimap.put(indexer.apply(desc), desc);
131+
public static <T> Map<T, Set<IEObjectDescription>> index(Iterable<IEObjectDescription> descriptions,
132+
Function<IEObjectDescription, T> indexer) {
133+
Map<T, Set<IEObjectDescription>> multimap = new LinkedHashMap<>();
134+
for (IEObjectDescription desc : descriptions) {
135+
multimap.computeIfAbsent(indexer.apply(desc), n -> new LinkedHashSet<>(1)).add(desc);
111136
}
112137
return multimap;
113138
}
114-
139+
115140
/**
116141
* indexes the IEObject description using the given
142+
* @deprecated Instead use {@link #indexByName(Iterable)}
117143
*/
118-
public static Multimap<QualifiedName,IEObjectDescription> index(Iterable<IEObjectDescription> descriptions) {
119-
return index(descriptions, new Function<IEObjectDescription, QualifiedName>() {
120-
@Override
121-
public QualifiedName apply(IEObjectDescription from) {
122-
return from.getName().toLowerCase();
123-
}
124-
});
144+
@Deprecated(since = "2.35.0", forRemoval = true)
145+
public static com.google.common.collect.Multimap<QualifiedName,IEObjectDescription> index(Iterable<IEObjectDescription> descriptions) {
146+
return index(descriptions, from -> from.getName().toLowerCase());
147+
}
148+
149+
/**
150+
* indexes the IEObject description using the given
151+
*/
152+
public static Map<QualifiedName, Set<IEObjectDescription>> indexByName(Iterable<IEObjectDescription> descriptions) {
153+
return index(descriptions, (Function<IEObjectDescription, QualifiedName>) from -> from.getName().toLowerCase());
125154
}
126155

127156
public static Iterable<IEObjectDescription> filterDuplicates(Iterable<IEObjectDescription> filtered) {
128-
Map<QualifiedName, IEObjectDescription> result = Maps.newLinkedHashMap();
157+
Map<QualifiedName, IEObjectDescription> result = new LinkedHashMap<>();
129158
for (IEObjectDescription e : filtered) {
130159
QualifiedName qualifiedName = e.getName();
131160
if (result.containsKey(qualifiedName)) {
@@ -134,7 +163,7 @@ public static Iterable<IEObjectDescription> filterDuplicates(Iterable<IEObjectDe
134163
result.put(qualifiedName, e);
135164
}
136165
}
137-
return Iterables.filter(result.values(), Predicates.notNull());
166+
return Iterables.filter(result.values(), Objects::nonNull);
138167
}
139168

140169
}

0 commit comments

Comments
 (0)