Skip to content

Commit edfab69

Browse files
committed
change the handlers
Signed-off-by: Shi Chen <[email protected]>
1 parent 57a73be commit edfab69

File tree

2 files changed

+218
-228
lines changed

2 files changed

+218
-228
lines changed

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/TypeHierarchyHandler.java

Lines changed: 136 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
* Contributors:
1111
* Microsoft Corporation - initial API and implementation
1212
*******************************************************************************/
13-
package org.eclipse.jdt.ls.core.internal.commands;
13+
package org.eclipse.jdt.ls.core.internal.handlers;
1414

1515
import java.util.ArrayList;
16+
import java.util.Arrays;
17+
import java.util.Collections;
1618
import java.util.HashMap;
1719
import java.util.List;
1820
import java.util.Map;
@@ -35,89 +37,150 @@
3537
import org.eclipse.jdt.ls.core.internal.JDTUtils.LocationType;
3638
import org.eclipse.jdt.ls.core.internal.JSONUtility;
3739
import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
38-
import org.eclipse.jdt.ls.core.internal.handlers.DocumentSymbolHandler;
3940
import org.eclipse.lsp4j.Location;
4041
import org.eclipse.lsp4j.Position;
4142
import org.eclipse.lsp4j.Range;
4243
import org.eclipse.lsp4j.SymbolKind;
44+
import org.eclipse.lsp4j.SymbolTag;
4345
import org.eclipse.lsp4j.TextDocumentIdentifier;
44-
import org.eclipse.lsp4j.legacy.typeHierarchy.ResolveTypeHierarchyItemParams;
45-
import org.eclipse.lsp4j.legacy.typeHierarchy.TypeHierarchyDirection;
46-
import org.eclipse.lsp4j.legacy.typeHierarchy.TypeHierarchyItem;
47-
import org.eclipse.lsp4j.legacy.typeHierarchy.TypeHierarchyParams;
46+
import org.eclipse.lsp4j.TypeHierarchyItem;
47+
import org.eclipse.lsp4j.TypeHierarchyPrepareParams;
48+
import org.eclipse.lsp4j.TypeHierarchySubtypesParams;
49+
import org.eclipse.lsp4j.TypeHierarchySupertypesParams;
4850

49-
public class TypeHierarchyCommand {
51+
public class TypeHierarchyHandler {
5052

51-
public TypeHierarchyItem typeHierarchy(TypeHierarchyParams params, IProgressMonitor monitor) {
53+
public enum TypeHierarchyDirection {
54+
Subtype, Supertype;
55+
}
56+
57+
private static class TypeHierarchyItemData {
58+
private String handleIdentifier;
59+
private String methodIdentifier;
60+
private String methodName;
61+
62+
public TypeHierarchyItemData(String handleIdentifier, String methodIdentifier, String methodName) {
63+
this.handleIdentifier = handleIdentifier;
64+
this.methodIdentifier = methodIdentifier;
65+
this.methodName = methodName;
66+
}
67+
68+
private static TypeHierarchyItemData getTypeHierarchyItemData(Object data) {
69+
if (data == null) {
70+
return null;
71+
}
72+
Map<String, String> map = JSONUtility.toModel(data, Map.class);
73+
String handleIdentifier = map.get("element");
74+
String methodIdentifier = map.get("method");
75+
String methodName = map.get("method_name");
76+
return new TypeHierarchyItemData(handleIdentifier, methodIdentifier, methodName);
77+
}
78+
}
79+
80+
public List<TypeHierarchyItem> prepareTypeHierarchy(TypeHierarchyPrepareParams params, IProgressMonitor monitor) {
5281
if (params == null) {
53-
return null;
82+
return Collections.emptyList();
5483
}
5584
TextDocumentIdentifier textDocument = params.getTextDocument();
5685
if (textDocument == null) {
57-
return null;
86+
return Collections.emptyList();
5887
}
5988
Position position = params.getPosition();
6089
String uri = textDocument.getUri();
61-
TypeHierarchyDirection direction = params.getDirection();
62-
int resolve = params.getResolve();
63-
return getTypeHierarchy(uri, position, direction, resolve, null, monitor);
90+
return getTypeHierarchyItems(uri, position, monitor);
6491
}
6592

66-
public TypeHierarchyItem resolveTypeHierarchy(ResolveTypeHierarchyItemParams params, IProgressMonitor monitor) {
67-
if (params == null) {
68-
return null;
93+
private List<TypeHierarchyItem> getTypeHierarchyItems(String uri, Position position, IProgressMonitor monitor) {
94+
if (uri == null || position == null) {
95+
return Collections.emptyList();
6996
}
70-
TypeHierarchyItem item = params.getItem();
71-
if (item == null) {
72-
return null;
97+
try {
98+
IMember member = getMember(uri, position, monitor);
99+
IMethod targetMethod = null;
100+
if (member instanceof IMethod) {
101+
targetMethod = (IMethod) member;
102+
}
103+
TypeHierarchyItem item = targetMethod == null ? TypeHierarchyHandler.toTypeHierarchyItem(member) : TypeHierarchyHandler.toTypeHierarchyItem(member, false, targetMethod);
104+
if (item == null) {
105+
return Collections.emptyList();
106+
}
107+
return Arrays.asList(item);
108+
} catch (JavaModelException e) {
109+
return Collections.emptyList();
73110
}
74-
Range range = item.getRange();
75-
if (range == null) {
76-
return null;
111+
}
112+
113+
public List<TypeHierarchyItem> getSupertypeItems(TypeHierarchySupertypesParams params, IProgressMonitor monitor) {
114+
return getTypeHierarchyItems(params.getItem(), TypeHierarchyDirection.Supertype, monitor);
115+
}
116+
117+
public List<TypeHierarchyItem> getSubtypeItems(TypeHierarchySubtypesParams params, IProgressMonitor monitor) {
118+
return getTypeHierarchyItems(params.getItem(), TypeHierarchyDirection.Subtype, monitor);
119+
}
120+
121+
private List<TypeHierarchyItem> getTypeHierarchyItems(TypeHierarchyItem item, TypeHierarchyDirection direction, IProgressMonitor monitor) {
122+
TypeHierarchyItemData data = TypeHierarchyItemData.getTypeHierarchyItemData(item.getData());
123+
if (data == null) {
124+
return Collections.emptyList();
77125
}
78-
Position position = range.getStart();
79-
String uri = item.getUri();
80-
TypeHierarchyDirection direction = params.getDirection();
81-
int resolve = params.getResolve();
82-
return getTypeHierarchy(uri, position, direction, resolve, item, monitor);
126+
IJavaElement element = JavaCore.create(data.handleIdentifier);
127+
IMember member = null;
128+
IMethod targetMethod = null;
129+
if (data.methodIdentifier != null) {
130+
targetMethod = (IMethod) JavaCore.create(data.methodIdentifier);
131+
}
132+
if (element instanceof IType || element instanceof IMethod) {
133+
member = (IMember) element;
134+
} else if (element instanceof IOrdinaryClassFile classFile) {
135+
member = classFile.getType();
136+
} else {
137+
return Collections.emptyList();
138+
}
139+
return resolveTypeHierarchyItems(member, targetMethod, direction, monitor);
83140
}
84141

85-
private TypeHierarchyItem getTypeHierarchy(String uri, Position position, TypeHierarchyDirection direction, int resolve, TypeHierarchyItem itemInput, IProgressMonitor monitor) {
86-
if (uri == null || position == null || direction == null) {
87-
return null;
142+
private List<TypeHierarchyItem> resolveTypeHierarchyItems(IMember member, IMethod targetMethod, TypeHierarchyDirection direction, IProgressMonitor monitor) {
143+
if (monitor.isCanceled()) {
144+
return Collections.emptyList();
145+
}
146+
IType type = null;
147+
if (member instanceof IType) {
148+
type = (IType) member;
149+
} else {
150+
type = member.getDeclaringType();
88151
}
89152
try {
90-
IMember member = null;
91-
IMethod targetMethod = null;
92-
if (itemInput == null) {
93-
member = getMember(uri, position, monitor);
94-
if (member instanceof IMethod) {
95-
targetMethod = (IMethod) member;
96-
}
153+
ITypeHierarchy typeHierarchy = null;
154+
List<TypeHierarchyItem> items = new ArrayList<>();
155+
IType[] hierarchyTypes = null;
156+
if (direction == TypeHierarchyDirection.Supertype) {
157+
typeHierarchy = type.newSupertypeHierarchy(DefaultWorkingCopyOwner.PRIMARY, monitor);
158+
hierarchyTypes = typeHierarchy.getSupertypes(type);
97159
} else {
98-
Map<String, String> data = JSONUtility.toModel(itemInput.getData(), Map.class);
99-
String handleIdentifier = data.get("element");
100-
IJavaElement element = JavaCore.create(handleIdentifier);
101-
String methodIdentifier = data.get("method");
102-
if (methodIdentifier != null) {
103-
targetMethod = (IMethod) JavaCore.create(methodIdentifier);
104-
}
105-
if (element instanceof IType || element instanceof IMethod) {
106-
member = (IMember) element;
107-
} else if (element instanceof IOrdinaryClassFile classFile) {
108-
member = classFile.getType();
160+
ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, true);
161+
typeHierarchy = type.newTypeHierarchy(workingCopies, monitor);
162+
hierarchyTypes = typeHierarchy.getSubtypes(type);
163+
}
164+
for (IType hierarchyType : hierarchyTypes) {
165+
TypeHierarchyItem item = null;
166+
if (targetMethod != null) {
167+
IMethod[] matches = hierarchyType.findMethods(targetMethod);
168+
boolean excludeMember = matches == null || matches.length == 0;
169+
// Do not show java.lang.Object unless target method is based there
170+
if (!excludeMember || !"java.lang.Object".equals(hierarchyType.getFullyQualifiedName())) {
171+
item = TypeHierarchyHandler.toTypeHierarchyItem(excludeMember ? hierarchyType : matches[0], excludeMember, targetMethod);
172+
}
109173
} else {
110-
return null;
174+
item = TypeHierarchyHandler.toTypeHierarchyItem(hierarchyType);
111175
}
176+
if (item == null) {
177+
continue;
178+
}
179+
items.add(item);
112180
}
113-
TypeHierarchyItem item = TypeHierarchyCommand.toTypeHierarchyItem(member);
114-
if (item == null) {
115-
return null;
116-
}
117-
resolve(item, member, targetMethod, direction, resolve, monitor);
118-
return item;
181+
return items;
119182
} catch (JavaModelException e) {
120-
return null;
183+
return Collections.emptyList();
121184
}
122185
}
123186

@@ -160,10 +223,10 @@ private static TypeHierarchyItem toTypeHierarchyItem(IMember member, boolean exc
160223
if (location == null || selectLocation == null) {
161224
return null;
162225
}
163-
TypeHierarchyItem item = new TypeHierarchyItem();
164-
item.setRange(location.getRange());
165-
item.setUri(location.getUri());
166-
item.setSelectionRange(selectLocation.getRange());
226+
227+
Range range = location.getRange();
228+
String uri = location.getUri();
229+
Range selectionRange = selectLocation.getRange();
167230

168231
IType type = null;
169232
if (member instanceof IType) {
@@ -172,20 +235,25 @@ private static TypeHierarchyItem toTypeHierarchyItem(IMember member, boolean exc
172235
type = member.getDeclaringType();
173236
}
174237

238+
String name = null;
239+
String detail = null;
175240
String fullyQualifiedName = type.getFullyQualifiedName();
176241
int index = fullyQualifiedName.lastIndexOf('.');
177242
if (index >= 1 && index < fullyQualifiedName.length() - 1 && !type.isAnonymous()) {
178-
item.setName(fullyQualifiedName.substring(index + 1));
179-
item.setDetail(fullyQualifiedName.substring(0, index));
243+
name = fullyQualifiedName.substring(index + 1);
244+
detail = fullyQualifiedName.substring(0, index);
180245
} else {
181-
item.setName(JDTUtils.getName(type));
246+
name = JDTUtils.getName(type);
182247
IPackageFragment packageFragment = type.getPackageFragment();
183248
if (packageFragment != null) {
184-
item.setDetail(packageFragment.getElementName());
249+
detail = packageFragment.getElementName();
185250
}
186251
}
187-
item.setKind(excludeMember ? SymbolKind.Null : DocumentSymbolHandler.mapKind(type));
188-
item.setDeprecated(JDTUtils.isDeprecated(member));
252+
SymbolKind kind = excludeMember ? SymbolKind.Null : DocumentSymbolHandler.mapKind(type);
253+
List<SymbolTag> tags = new ArrayList<>();
254+
if (JDTUtils.isDeprecated(member)) {
255+
tags.add(SymbolTag.Deprecated);
256+
}
189257
Map<String, String> data = new HashMap<>();
190258
data.put("element", member.getHandleIdentifier());
191259
if (targetMethod != null) {
@@ -195,6 +263,8 @@ private static TypeHierarchyItem toTypeHierarchyItem(IMember member, boolean exc
195263
data.put("method", member.getHandleIdentifier());
196264
data.put("method_name", member.getElementName());
197265
}
266+
TypeHierarchyItem item = new TypeHierarchyItem(name, kind, uri, range, selectionRange, detail);
267+
item.setTags(tags);
198268
item.setData(data);
199269
return item;
200270
}
@@ -206,68 +276,4 @@ private static Location getLocation(IMember member, LocationType locationType) t
206276
}
207277
return location;
208278
}
209-
210-
private void resolve(TypeHierarchyItem item, IMember member, IMethod targetMethod, TypeHierarchyDirection direction, int resolve, IProgressMonitor monitor) throws JavaModelException {
211-
if (monitor.isCanceled() || resolve <= 0) {
212-
return;
213-
}
214-
215-
IType type = null;
216-
if (member instanceof IType) {
217-
type = (IType) member;
218-
} else {
219-
type = member.getDeclaringType();
220-
}
221-
222-
ITypeHierarchy typeHierarchy;
223-
if (direction == TypeHierarchyDirection.Parents) {
224-
typeHierarchy = type.newSupertypeHierarchy(DefaultWorkingCopyOwner.PRIMARY, monitor);
225-
} else {
226-
ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, true);
227-
typeHierarchy = type.newTypeHierarchy(workingCopies, monitor);
228-
}
229-
if (direction == TypeHierarchyDirection.Children || direction == TypeHierarchyDirection.Both) {
230-
List<TypeHierarchyItem> childrenItems = new ArrayList<>();
231-
IType[] children = typeHierarchy.getSubtypes(type);
232-
for (IType childType : children) {
233-
TypeHierarchyItem childItem = null;
234-
if (targetMethod != null) {
235-
IMethod[] matches = childType.findMethods(targetMethod);
236-
boolean excludeMember = matches == null || matches.length == 0;
237-
childItem = TypeHierarchyCommand.toTypeHierarchyItem(excludeMember ? childType : matches[0], excludeMember, targetMethod);
238-
} else {
239-
childItem = TypeHierarchyCommand.toTypeHierarchyItem(childType);
240-
}
241-
if (childItem == null) {
242-
continue;
243-
}
244-
resolve(childItem, childType, targetMethod, direction, resolve - 1, monitor);
245-
childrenItems.add(childItem);
246-
}
247-
item.setChildren(childrenItems);
248-
}
249-
if (direction == TypeHierarchyDirection.Parents || direction == TypeHierarchyDirection.Both) {
250-
List<TypeHierarchyItem> parentsItems = new ArrayList<>();
251-
IType[] parents = typeHierarchy.getSupertypes(type);
252-
for (IType parentType : parents) {
253-
TypeHierarchyItem parentItem = null;
254-
if (targetMethod != null) {
255-
IMethod[] matches = parentType.findMethods(targetMethod);
256-
boolean excludeMember = matches == null || matches.length == 0;
257-
// Do not show java.lang.Object unless target method is based there
258-
if (!excludeMember || !"java.lang.Object".equals(parentType.getFullyQualifiedName())) {
259-
parentItem = TypeHierarchyCommand.toTypeHierarchyItem(excludeMember ? parentType : matches[0], excludeMember, targetMethod);
260-
}
261-
} else {
262-
parentItem = TypeHierarchyCommand.toTypeHierarchyItem(parentType);
263-
}
264-
if (parentItem == null) {
265-
continue;
266-
}
267-
resolve(parentItem, parentType, targetMethod, direction, resolve - 1, monitor);
268-
parentsItems.add(parentItem);
269-
}
270-
item.setParents(parentsItems);
271-
}
272-
}
273279
}

0 commit comments

Comments
 (0)