use of org.eclipse.jdt.core.IMethod in project eclipse.jdt.ls by eclipse.
the class RippleMethodFinder method findAllDeclarations.
private void findAllDeclarations(IProgressMonitor monitor, WorkingCopyOwner owner) throws CoreException {
fDeclarations = new ArrayList<>();
class MethodRequestor extends SearchRequestor {
@Override
public void acceptSearchMatch(SearchMatch match) throws CoreException {
IMethod method = (IMethod) match.getElement();
boolean isBinary = method.isBinary();
if (!isBinary) {
fDeclarations.add(method);
}
}
}
int limitTo = IJavaSearchConstants.DECLARATIONS | IJavaSearchConstants.IGNORE_DECLARING_TYPE | IJavaSearchConstants.IGNORE_RETURN_TYPE;
int matchRule = SearchPattern.R_ERASURE_MATCH | SearchPattern.R_CASE_SENSITIVE;
SearchPattern pattern = SearchPattern.createPattern(fMethod, limitTo, matchRule);
MethodRequestor requestor = new MethodRequestor();
SearchEngine searchEngine = owner != null ? new SearchEngine(owner) : new SearchEngine();
searchEngine.search(pattern, new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() }, createSearchScope(), requestor, monitor);
}
use of org.eclipse.jdt.core.IMethod in project eclipse.jdt.ls by eclipse.
the class RippleMethodFinder method findAllRippleMethods.
private IMethod[] findAllRippleMethods(IProgressMonitor pm, WorkingCopyOwner owner) throws CoreException {
// $NON-NLS-1$
pm.beginTask("", 4);
findAllDeclarations(pm, owner);
// check for bug 81058:
if (!fDeclarations.contains(fMethod)) {
// $NON-NLS-1$
Assert.isTrue(false, "Search for method declaration did not find original element: " + fMethod.toString());
}
createHierarchyOfDeclarations(new SubProgressMonitor(pm, 1), owner);
createTypeToMethod();
createUnionFind();
if (pm.isCanceled()) {
throw new OperationCanceledException();
}
fHierarchy = null;
fRootTypes = null;
Map<IType, List<IType>> partitioning = new HashMap<>();
for (Iterator<IType> iter = fTypeToMethod.keySet().iterator(); iter.hasNext(); ) {
IType type = iter.next();
IType rep = fUnionFind.find(type);
List<IType> types = partitioning.get(rep);
if (types == null) {
types = new ArrayList<>();
}
types.add(type);
partitioning.put(rep, types);
}
Assert.isTrue(partitioning.size() > 0);
if (partitioning.size() == 1) {
return fDeclarations.toArray(new IMethod[fDeclarations.size()]);
}
// Multiple partitions; must look out for nasty marriage cases
// (types inheriting method from two ancestors, but without redeclaring it).
IType methodTypeRep = fUnionFind.find(fMethod.getDeclaringType());
List<IType> relatedTypes = partitioning.get(methodTypeRep);
boolean hasRelatedInterfaces = false;
List<IMethod> relatedMethods = new ArrayList<>();
for (Iterator<IType> iter = relatedTypes.iterator(); iter.hasNext(); ) {
IType relatedType = iter.next();
relatedMethods.add(fTypeToMethod.get(relatedType));
if (relatedType.isInterface()) {
hasRelatedInterfaces = true;
}
}
// Definition: An alien type is a type that is not a related type. The set of
// alien types diminishes as new types become related (a.k.a marry a relatedType).
List<IMethod> alienDeclarations = new ArrayList<>(fDeclarations);
fDeclarations = null;
alienDeclarations.removeAll(relatedMethods);
List<IType> alienTypes = new ArrayList<>();
boolean hasAlienInterfaces = false;
for (Iterator<IMethod> iter = alienDeclarations.iterator(); iter.hasNext(); ) {
IMethod alienDeclaration = iter.next();
IType alienType = alienDeclaration.getDeclaringType();
alienTypes.add(alienType);
if (alienType.isInterface()) {
hasAlienInterfaces = true;
}
}
if (alienTypes.size() == 0) {
return relatedMethods.toArray(new IMethod[relatedMethods.size()]);
}
if (!hasRelatedInterfaces && !hasAlienInterfaces) {
return relatedMethods.toArray(new IMethod[relatedMethods.size()]);
}
// find all subtypes of related types:
HashSet<IType> relatedSubTypes = new HashSet<>();
List<IType> relatedTypesToProcess = new ArrayList<>(relatedTypes);
while (relatedTypesToProcess.size() > 0) {
// TODO: would only need subtype hierarchies of all top-of-ripple relatedTypesToProcess
for (Iterator<IType> iter = relatedTypesToProcess.iterator(); iter.hasNext(); ) {
if (pm.isCanceled()) {
throw new OperationCanceledException();
}
IType relatedType = iter.next();
ITypeHierarchy hierarchy = getCachedHierarchy(relatedType, owner, new SubProgressMonitor(pm, 1));
if (hierarchy == null) {
hierarchy = relatedType.newTypeHierarchy(owner, new SubProgressMonitor(pm, 1));
}
IType[] allSubTypes = hierarchy.getAllSubtypes(relatedType);
for (int i = 0; i < allSubTypes.length; i++) {
relatedSubTypes.add(allSubTypes[i]);
}
}
// processed; make sure loop terminates
relatedTypesToProcess.clear();
HashSet<IType> marriedAlienTypeReps = new HashSet<>();
for (Iterator<IType> iter = alienTypes.iterator(); iter.hasNext(); ) {
if (pm.isCanceled()) {
throw new OperationCanceledException();
}
IType alienType = iter.next();
IMethod alienMethod = fTypeToMethod.get(alienType);
ITypeHierarchy hierarchy = getCachedHierarchy(alienType, owner, new SubProgressMonitor(pm, 1));
if (hierarchy == null) {
hierarchy = alienType.newTypeHierarchy(owner, new SubProgressMonitor(pm, 1));
}
IType[] allSubtypes = hierarchy.getAllSubtypes(alienType);
for (int i = 0; i < allSubtypes.length; i++) {
IType subtype = allSubtypes[i];
if (relatedSubTypes.contains(subtype)) {
if (JavaModelUtil.isVisibleInHierarchy(alienMethod, subtype.getPackageFragment())) {
marriedAlienTypeReps.add(fUnionFind.find(alienType));
} else {
// not overridden
}
}
}
}
if (marriedAlienTypeReps.size() == 0) {
return relatedMethods.toArray(new IMethod[relatedMethods.size()]);
}
for (Iterator<IType> iter = marriedAlienTypeReps.iterator(); iter.hasNext(); ) {
IType marriedAlienTypeRep = iter.next();
List<IType> marriedAlienTypes = partitioning.get(marriedAlienTypeRep);
for (Iterator<IType> iterator = marriedAlienTypes.iterator(); iterator.hasNext(); ) {
IType marriedAlienInterfaceType = iterator.next();
relatedMethods.add(fTypeToMethod.get(marriedAlienInterfaceType));
}
// not alien any more
alienTypes.removeAll(marriedAlienTypes);
// process freshly married types again
relatedTypesToProcess.addAll(marriedAlienTypes);
}
}
fRootReps = null;
fRootHierarchies = null;
fTypeToMethod = null;
fUnionFind = null;
return relatedMethods.toArray(new IMethod[relatedMethods.size()]);
}
use of org.eclipse.jdt.core.IMethod in project eclipse.jdt.ls by eclipse.
the class RippleMethodFinder method createTypeToMethod.
private void createTypeToMethod() {
fTypeToMethod = new HashMap<>();
for (Iterator<IMethod> iter = fDeclarations.iterator(); iter.hasNext(); ) {
IMethod declaration = iter.next();
fTypeToMethod.put(declaration.getDeclaringType(), declaration);
}
}
use of org.eclipse.jdt.core.IMethod in project liferay-ide by liferay.
the class ServiceMethodHyperlinkDetector method detectHyperlinks.
public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, boolean canShowMultipleHyperlinks) {
IHyperlink[] retval = null;
ITextEditor textEditor = (ITextEditor) getAdapter(ITextEditor.class);
if (textEditor == null) {
return retval;
}
ITypeRoot input = EditorUtility.getEditorInputJavaElement(textEditor, false);
IAction openAction = textEditor.getAction("OpenEditor");
if (_shouldDetectHyperlinks(textEditor, input, openAction, region)) {
IDocumentProvider documentProvider = textEditor.getDocumentProvider();
IEditorInput editorInput = textEditor.getEditorInput();
IDocument document = documentProvider.getDocument(editorInput);
int offset = region.getOffset();
IRegion wordRegion = JavaWordFinder.findWord(document, offset);
if (_isRegionValid(document, wordRegion)) {
IJavaElement[] elements = new IJavaElement[0];
long modStamp = documentProvider.getModificationStamp(editorInput);
if (input.equals(_lastInput) && (modStamp == _lastModStamp) && wordRegion.equals(_lastWordRegion)) {
elements = _lastElements;
} else {
try {
elements = ((ICodeAssist) input).codeSelect(wordRegion.getOffset(), wordRegion.getLength());
elements = _selectOpenableElements(elements);
_lastInput = input;
_lastModStamp = modStamp;
_lastWordRegion = wordRegion;
_lastElements = elements;
} catch (JavaModelException jme) {
}
}
if (elements.length != 0) {
List<IHyperlink> links = new ArrayList<>(elements.length);
for (IJavaElement element : elements) {
if (element instanceof IMethod) {
_addHyperlinks(links, wordRegion, (SelectionDispatchAction) openAction, (IMethod) element, elements.length > 1, (JavaEditor) textEditor);
}
}
if (ListUtil.isNotEmpty(links)) {
if (canShowMultipleHyperlinks) {
retval = links.toArray(new IHyperlink[0]);
} else {
retval = new IHyperlink[] { links.get(0) };
}
}
}
}
}
return retval;
}
use of org.eclipse.jdt.core.IMethod in project liferay-ide by liferay.
the class ServiceMethodHyperlinkDetector method _getServiceImplMethod.
private IMethod _getServiceImplMethod(IMethod method) {
IMethod retval = null;
try {
IJavaElement methodClass = method.getParent();
IType methodClassType = method.getDeclaringType();
String methodClassName = methodClass.getElementName();
if (methodClassName.endsWith("Util") && JdtFlags.isPublic(method) && JdtFlags.isStatic(method)) {
String packageName = methodClassType.getPackageFragment().getElementName();
String baseServiceName = methodClassName.substring(0, methodClassName.length() - 4);
/*
* as per liferay standard real implementation will be in impl package and Impl suffix
* e.g. com.example.service.FooUtil.getBar() --> com.example.service.impl.FooImpl.getBar()
*/
String fullyQualifiedName = packageName + ".impl." + baseServiceName + "Impl";
IType implType = _findType(methodClass, fullyQualifiedName);
if (implType != null) {
IMethod[] methods = implType.findMethods(method);
if (ListUtil.isEmpty(methods)) {
ITypeHierarchy hierarchy = implType.newSupertypeHierarchy(new NullProgressMonitor());
IType currentType = implType;
while ((retval == null) && (currentType != null)) {
methods = currentType.findMethods(method);
if (ListUtil.isNotEmpty(methods)) {
retval = methods[0];
} else {
currentType = hierarchy.getSuperclass(currentType);
}
}
} else {
retval = methods[0];
}
}
}
} catch (Exception e) {
}
return retval;
}
Aggregations