blob: 555199d3931da5c378e37491d7272a02fa143aa1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2013 IBM Corporation and others.
*
* 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
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.pde.api.tools.internal.builder;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.pde.api.tools.internal.model.MethodKey;
import org.eclipse.pde.api.tools.internal.provisional.builder.IReference;
import org.eclipse.pde.api.tools.internal.provisional.descriptors.IElementDescriptor;
import org.eclipse.pde.api.tools.internal.provisional.descriptors.IMethodDescriptor;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiMember;
import org.eclipse.pde.api.tools.internal.provisional.model.IApiMethod;
import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
/**
* Abstract implementation for illegal method references i.e. method calls,
* constructor invocation, etc
*
* @since 1.1
*/
public abstract class AbstractIllegalMethodReference extends AbstractProblemDetector {
/**
* Map of {@link org.eclipse.pde.api.tools.internal.model.MethodKey} to
* {@link org.eclipse.pde.api.tools.internal.provisional.descriptors.IMethodDescriptor}
*/
private Map<MethodKey, IMethodDescriptor> fIllegalMethods = new HashMap<>();
/**
* Map of
* {@link org.eclipse.pde.api.tools.internal.provisional.descriptors.IMethodDescriptor}
* to associated component IDs
*/
private Map<IMethodDescriptor, String> fMethodComponents = new HashMap<>();
/**
* Adds the given type as not to be extended.
*
* @param type a type that is marked no extend
* @param componentId the component the type is located in
*/
void addIllegalMethod(IMethodDescriptor method, String componentId) {
fIllegalMethods.put(new MethodKey(method.getEnclosingType().getQualifiedName(), method.getName(), method.getSignature(), true), method);
fMethodComponents.put(method, componentId);
}
@Override
public boolean considerReference(IReference reference) {
MethodKey key = new MethodKey(reference.getReferencedTypeName(), reference.getReferencedMemberName(), reference.getReferencedSignature(), true);
if (super.considerReference(reference) && fIllegalMethods.containsKey(key)) {
retainReference(reference);
return true;
}
if ((reference.getReferenceFlags() & IReference.F_DEFAULT_METHOD) > 0) {
IApiMember member = reference.getResolvedReference();
if (member == null) {
try {
((Reference) reference).resolve();
member = reference.getResolvedReference();
} catch (CoreException ce) {
// do nothing, skip it
}
if (member instanceof IApiMethod) {
IApiMethod method = (IApiMethod) member;
if (method.isDefaultMethod()) {
return considerReference(reference);
}
}
}
}
return false;
}
@Override
protected boolean isProblem(IReference reference, IProgressMonitor monitor) {
if (!super.isProblem(reference, monitor)) {
return false;
}
IApiMember method = reference.getResolvedReference();
String componentId = fMethodComponents.get(method.getHandle());
// TODO: would it be faster to store component objects and use identity
// instead of equals?
return isReferenceFromComponent(reference, componentId);
}
@Override
protected int getElementType(IReference reference) {
return IElementDescriptor.METHOD;
}
@Override
protected int getProblemFlags(IReference reference) {
IApiMethod method = (IApiMethod) reference.getResolvedReference();
if (method.isConstructor()) {
return IApiProblem.CONSTRUCTOR_METHOD;
}
return IApiProblem.METHOD;
}
}