blob: 10157ac343c2457b2c21f3e37230e2772ff60810 [file] [log] [blame]
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
* Copyright 2004, 2006 Fraunhofer Gesellschaft, Munich, Germany,
* for its Fraunhofer Institute for Computer Architecture and Software
* Technology (FIRST), Berlin, Germany and Technical University Berlin,
* Germany.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Please visit http://www.eclipse.org/objectteams for updates and contact.
*
* Contributors:
* Fraunhofer FIRST - Initial API and implementation
* Technical University Berlin - Initial API and implementation
**********************************************************************/
package org.eclipse.objectteams.otdt.core.hierarchy;
import java.util.HashMap;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.objectteams.otdt.core.TypeHelper;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
/**
* Strategy for the {@link OTTypeHierarchyTraverser}.
* @author svacina
*/
public class InheritedMethodsRequestor extends TraverseRequestor
{
private HashMap<String, IMethod> _result;
private boolean _overwriteCollectedMethods;
private boolean _checkVisibility;
/**
* Create a requestor the will collect inherited methods.
* @param type the focus type of the traversal
* @param overwriteCollectedMethods if methods with the same signature should overwrite previously collected methods
* @param checkVisibility if method visibility should be checked.
*/
public InheritedMethodsRequestor(IType type,
boolean overwriteCollectedMethods,
boolean checkVisibility)
{
// TODO (jsv): can this class cope with IOTTypes as well? If not, it should use its correspondingJavaElement()
_result = new HashMap<String, IMethod>();
_focusType = type;
_overwriteCollectedMethods = overwriteCollectedMethods;
_checkVisibility = checkVisibility;
}
@Override
void report(IType type, HierarchyContext context) {
boolean checkVisibility;
try {
if (!_checkVisibility) {
checkVisibility = false;
} else if (type.isInterface()) {
if (_focusType.isInterface())
checkVisibility = false;
else
return;
} else {
if (context.isFocusType)
checkVisibility = false;
else
checkVisibility = context.isExplicitSuperclass || context.isBehindExplicitInheritance;
}
writeMethodsToResult(type,checkVisibility);
} catch (JavaModelException e) {
// TODO(jsv)handle exception
e.printStackTrace();
}
}
private void writeMethodsToResult(
IType type,
boolean checkVisibility) throws JavaModelException
{
IMethod[] methods = type.getMethods();
IMethod currMethod = null;
for (int methodIdx = 0; methodIdx < methods.length; methodIdx++)
{
currMethod = methods[methodIdx];
if (currMethod.getElementName().startsWith(IOTConstants.OT_DOLLAR))
continue;
if (currMethod.isConstructor())
continue;
// TODO(jsv) check completeness
if (checkVisibility)
{
// private
if (Flags.isPrivate(currMethod.getFlags()))
continue;
else if ( Flags.isPublic(currMethod.getFlags())
|| Flags.isProtected(currMethod.getFlags()) )
storeMethod(currMethod);
else if (type.getPackageFragment().equals(_focusType.getPackageFragment()))
storeMethod(currMethod);
else
continue;
} else {
storeMethod(currMethod);
}
}
}
private void storeMethod(IMethod method)
{
String key = TypeHelper.getMethodSignature(method);
if (!_overwriteCollectedMethods) {
if (!_result.containsKey(key))
_result.put(key, method);
} else {
_result.put(key, method);
}
}
/**
* Retrieve the result of the traverse operation.
* @return a non-null array of methods.
*/
public IMethod[] getResult() {
return _result.values().toArray(new IMethod[_result.size()]);
}
}