Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Rennie2013-03-18 21:10:47 +0000
committerMike Rennie2013-03-18 21:10:47 +0000
commit83655c5d1780a74e2d7c6b667c44ad80f8afb577 (patch)
tree5952c8c6a894d1cf2d84c7bd46a912988eeb74d0
parent3a250add62581c54025d36f5f414dad9724cb75b (diff)
downloadeclipse.pde.ui-83655c5d1780a74e2d7c6b667c44ad80f8afb577.tar.gz
eclipse.pde.ui-83655c5d1780a74e2d7c6b667c44ad80f8afb577.tar.xz
eclipse.pde.ui-83655c5d1780a74e2d7c6b667c44ad80f8afb577.zip
Bug 403258 - Use problem on anonymous type in incorrect locationN20130318-2000I20130319-1000
-rw-r--r--apitools/org.eclipse.pde.api.tools.tests/src/org/eclipse/pde/api/tools/builder/tests/usage/ClassUsageTests.java89
-rw-r--r--apitools/org.eclipse.pde.api.tools.tests/test-builder/usage/class/testc11.java47
-rw-r--r--apitools/org.eclipse.pde.api.tools.tests/test-builder/usage/class/testc12.java32
-rw-r--r--apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/AbstractIllegalTypeReference.java246
-rw-r--r--apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/IllegalExtendsProblemDetector.java252
-rw-r--r--apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/IllegalImplementsProblemDetector.java35
-rw-r--r--apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/ApiProblemFactory.java4
-rw-r--r--apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/problemmessages.properties10
-rw-r--r--apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/provisional/problems/IApiProblem.java14
9 files changed, 452 insertions, 277 deletions
diff --git a/apitools/org.eclipse.pde.api.tools.tests/src/org/eclipse/pde/api/tools/builder/tests/usage/ClassUsageTests.java b/apitools/org.eclipse.pde.api.tools.tests/src/org/eclipse/pde/api/tools/builder/tests/usage/ClassUsageTests.java
index b818057c68..90aecebfca 100644
--- a/apitools/org.eclipse.pde.api.tools.tests/src/org/eclipse/pde/api/tools/builder/tests/usage/ClassUsageTests.java
+++ b/apitools/org.eclipse.pde.api.tools.tests/src/org/eclipse/pde/api/tools/builder/tests/usage/ClassUsageTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2009 IBM Corporation and others.
+ * Copyright (c) 2008, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -159,7 +159,7 @@ public class ClassUsageTests extends UsageTest {
});
String typename = "testC3";
setExpectedMessageArgs(new String[][] {
- {"IExtInterface1", "INoImpl1", typename},
+ {"IExtInterface1", typename, "INoImpl1"},
});
deployUsageTest(typename, inc);
}
@@ -218,10 +218,10 @@ public class ClassUsageTests extends UsageTest {
});
String typename = "testC5";
setExpectedMessageArgs(new String[][] {
- {"IExtInterface1", "INoImpl1", typename},
- {"IExtInterface2", "INoImpl1", typename},
- {"IExtInterface3", "INoImpl1", typename},
- {"IExtInterface4", "INoImpl4", typename}
+ {"IExtInterface1", typename, "INoImpl1"},
+ {"IExtInterface2", typename, "INoImpl1"},
+ {"IExtInterface3", typename, "INoImpl1"},
+ {"IExtInterface4", typename, "INoImpl4"}
});
deployUsageTest(typename, inc);
}
@@ -321,6 +321,82 @@ public class ClassUsageTests extends UsageTest {
}
/**
+ * Tests that the correct markers are created and placed for classes with inner types
+ * that illegally implement interfaces
+ *
+ * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=403258
+ * @throws Exception
+ */
+ public void _testLocalClassIllegalImplements1I() throws Exception {
+ x19(true);
+ }
+
+ /**
+ * Tests that the correct markers are created and placed for local types
+ * that illegally implement interfaces
+ *
+ * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=403258
+ * @throws Exception
+ */
+ public void _testLocalClassIllegalImplements1F() throws Exception {
+ x19(false);
+ }
+
+ private void x19(boolean inc) {
+ setExpectedProblemIds(new int[] {
+ getProblemId(IApiProblem.ILLEGAL_IMPLEMENT, IApiProblem.LOCAL_TYPE),
+ getProblemId(IApiProblem.ILLEGAL_IMPLEMENT, IApiProblem.INDIRECT_LOCAL_REFERENCE),
+ getProblemId(IApiProblem.ILLEGAL_IMPLEMENT, IApiProblem.LOCAL_TYPE),
+ getProblemId(IApiProblem.ILLEGAL_IMPLEMENT, IApiProblem.INDIRECT_LOCAL_REFERENCE)
+ });
+ String typename = "testc11";
+ setExpectedMessageArgs(new String[][] {
+ {"local1", "x.y.z.testc11.method1()", "INoImpl2"},
+ {"local2", "x.y.z.testc11.method1()", "INoImpl2", "INoImpl5"},
+ {"local3", "x.y.z.outer.inner2.method2()", "INoImpl3"},
+ {"local4", "x.y.z.outer.inner2.method2()", "INoImpl2", "INoImpl6"}
+ });
+ deployUsageTest(typename, inc);
+ }
+
+ /**
+ * Tests that the correct markers are created and placed for local types
+ * that illegally implement interfaces, where there are more than one local type in the
+ * compilation unit indirectly implementing the same interface via the same proxy interface
+ *
+ * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=403258
+ * @throws Exception
+ */
+ public void _testLocalClassIllegaImplements2I() throws Exception {
+ x20(true);
+ }
+
+ /**
+ * Tests that the correct markers are created and placed for local types
+ * that illegally implement interfaces, where there are more than one local type in the
+ * compilation unit indirectly implementing the same interface via the same proxy interface
+ *
+ * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=403258
+ * @throws Exception
+ */
+ public void _testLocalClassIllegalImplements2F() throws Exception {
+ x20(false);
+ }
+
+ private void x20(boolean inc) {
+ setExpectedProblemIds(new int[] {
+ getProblemId(IApiProblem.ILLEGAL_IMPLEMENT, IApiProblem.INDIRECT_LOCAL_REFERENCE),
+ getProblemId(IApiProblem.ILLEGAL_IMPLEMENT, IApiProblem.INDIRECT_LOCAL_REFERENCE)
+ });
+ setExpectedMessageArgs(new String[][] {
+ {"local2", "x.y.z.testc12.method1()", "INoImpl2", "INoImpl5"},
+ {"local4", "x.y.z.outerc12.inner2.method2()", "INoImpl2", "INoImpl5"}
+ });
+ String typename = "testc12";
+ deployUsageTest(typename, inc);
+ }
+
+ /**
* Tests an anonymous type defined in the return statement of a method illegally extending a
* restricted type using a full build.
*
@@ -601,4 +677,5 @@ public class ClassUsageTests extends UsageTest {
});
deployUsageTest(typename, inc);
}
+
}
diff --git a/apitools/org.eclipse.pde.api.tools.tests/test-builder/usage/class/testc11.java b/apitools/org.eclipse.pde.api.tools.tests/test-builder/usage/class/testc11.java
new file mode 100644
index 0000000000..0070182b8c
--- /dev/null
+++ b/apitools/org.eclipse.pde.api.tools.tests/test-builder/usage/class/testc11.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) Mar 15, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package x.y.z;
+import i.INoImpl2;
+import i.INoImpl3;
+import i.INoImpl5;
+import i.INoImpl6;
+
+public class testc11 {
+ public void method1() {
+ class local1 implements INoImpl2 { //direct illegal implement
+
+ }
+ local1 l1 = new local1();
+ System.out.println(l1);
+ class local2 implements INoImpl5 { //indirect illegal implement
+
+ }
+ local2 l2 = new local2();
+ System.out.println(l2);
+ }
+}
+
+class outer {
+ class inner2 {
+ void method2() {
+ class local3 implements INoImpl3 { //direct illegal implement
+
+ }
+ local3 l3 = new local3();
+ System.out.println(l3);
+ class local4 implements INoImpl6 { //indirect illegal implement
+
+ }
+ local4 l4 = new local4();
+ System.out.println(l4);
+ }
+ }
+}
diff --git a/apitools/org.eclipse.pde.api.tools.tests/test-builder/usage/class/testc12.java b/apitools/org.eclipse.pde.api.tools.tests/test-builder/usage/class/testc12.java
new file mode 100644
index 0000000000..37f41f5d67
--- /dev/null
+++ b/apitools/org.eclipse.pde.api.tools.tests/test-builder/usage/class/testc12.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) Mar 15, 2013 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package x.y.z;
+import i.INoImpl5;
+
+public class testc12 {
+ public void method1() {
+ class local2 implements INoImpl5 { //indirect illegal implement
+ }
+ local2 l2 = new local2();
+ System.out.println(l2);
+ }
+}
+
+class outerc12 {
+ class inner2 {
+ void method2() {
+ class local4 implements INoImpl5 { //indirect illegal implement
+ }
+ local4 l4 = new local4();
+ System.out.println(l4);
+ }
+ }
+}
diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/AbstractIllegalTypeReference.java b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/AbstractIllegalTypeReference.java
index 7b4683b358..7459868d1e 100644
--- a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/AbstractIllegalTypeReference.java
+++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/AbstractIllegalTypeReference.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2010 IBM Corporation and others.
+ * Copyright (c) 2008, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -14,16 +14,33 @@ import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
+import org.eclipse.jdt.core.dom.ITypeBinding;
+import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
+import org.eclipse.pde.api.tools.internal.model.ApiType;
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.IReferenceTypeDescriptor;
+import org.eclipse.pde.api.tools.internal.provisional.model.IApiElement;
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.model.IApiType;
import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
+import org.eclipse.pde.api.tools.internal.util.Signatures;
/**
@@ -35,6 +52,62 @@ import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
public abstract class AbstractIllegalTypeReference extends AbstractProblemDetector {
/**
+ * Class used to look up the name of the enclosing method for an {@link IApiType} when we do not have any
+ * enclosing method infos (pre Java 1.5 class files
+ */
+ class MethodFinder extends ASTVisitor {
+ IMethod method = null;
+ private IType jtype = null;
+ private ApiType type = null;
+
+ public MethodFinder(ApiType type, IType jtype) {
+ this.type = type;
+ this.jtype = jtype;
+ }
+ public boolean visit(AnonymousClassDeclaration node) {
+ if(method == null) {
+ ITypeBinding binding = node.resolveBinding();
+ String binaryName = binding.getBinaryName();
+ if(type.getName().endsWith(binaryName)) {
+ try {
+ IJavaElement element = jtype.getCompilationUnit().getElementAt(node.getStartPosition());
+ if(element != null) {
+ IJavaElement ancestor = element.getAncestor(IJavaElement.METHOD);
+ if(ancestor != null) {
+ method = (IMethod) ancestor;
+ }
+ }
+ }
+ catch(JavaModelException jme) {}
+ return false;
+ }
+ }
+ return true;
+ }
+ public boolean visit(TypeDeclaration node) {
+ if(method == null && node.isLocalTypeDeclaration()) {
+ ITypeBinding binding = node.resolveBinding();
+ String binaryName = binding.getBinaryName();
+ if(type.getName().endsWith(binaryName)) {
+ try {
+ IJavaElement element = jtype.getCompilationUnit().getElementAt(node.getStartPosition());
+ if(element.getElementType() == IJavaElement.TYPE) {
+ IType ltype = (IType) element;
+ IJavaElement parent = ltype.getParent();
+ if(parent.getElementType() == IJavaElement.METHOD) {
+ method = (IMethod) parent;
+ }
+ }
+ }
+ catch(JavaModelException jme) {}
+ return false;
+ }
+ }
+ return true;
+ }
+ };
+
+ /**
* Map of fully qualified type names to associated component IDs that
* represent illegal references
*/
@@ -81,10 +154,131 @@ public abstract class AbstractIllegalTypeReference extends AbstractProblemDetect
Object componentId = fIllegalTypes.get(type.getName());
return isReferenceFromComponent(reference, componentId);
}
+
+ /**
+ * Returns the enclosing {@link IMethod} for the given type or <code>null</code>
+ * if it cannot be computed
+ * @param type
+ * @param jtype
+ * @param reference
+ * @param document
+ * @return the {@link IMethod} enclosing the given type or <code>null</code>
+ * @throws CoreException
+ */
+ protected IMethod getEnclosingMethod(final IType jtype, IReference reference, IDocument document) throws CoreException {
+ IApiMember member = reference.getMember();
+ if((member.getType() == IApiElement.TYPE)) {
+ ApiType type = (ApiType) member;
+ IApiMethod apimethod = type.getEnclosingMethod();
+ if(apimethod != null) {
+ String signature = Signatures.processMethodSignature(apimethod);
+ String methodname = Signatures.getMethodName(apimethod);
+ IMethod method = jtype.getMethod(methodname, Signature.getParameterTypes(signature));
+ if(method.exists()) {
+ return method;
+ }
+ }
+ else {
+ //try to look it up
+ IMethod method = null;
+ if(reference.getLineNumber() > -1) {
+ try {
+ int offset = document.getLineOffset(reference.getLineNumber());
+ method = quickLookup(jtype, document, reference, offset);
+ }
+ catch(BadLocationException ble) {}
+ }
+ if(method == null) {
+ //look it up the hard way
+ ISourceRange range = jtype.getCompilationUnit().getSourceRange();
+ ASTParser parser = ASTParser.newParser(AST.JLS4);
+ parser.setSource(jtype.getCompilationUnit());
+ parser.setSourceRange(range.getOffset(), range.getLength());
+ parser.setResolveBindings(true);
+ ASTNode ptype = parser.createAST(null);
+ MethodFinder finder = new MethodFinder(type, jtype);
+ ptype.accept(finder);
+ method = finder.method;
+ }
+ if(method != null && method.exists()) {
+ ApiType etype = (ApiType) type.getEnclosingType();
+ IApiMethod[] methods = etype.getMethods();
+ String msig = null;
+ for (int i = 0; i < methods.length; i++) {
+ msig = methods[i].getSignature();
+ if(Signatures.getMethodName(methods[i]).equals(method.getElementName()) &&
+ Signatures.matchesSignatures(msig.replace('/', '.'), method.getSignature())) {
+ type.setEnclosingMethodInfo(methods[i].getName(), msig);
+ }
+ }
+ return method;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Performs a quick look-up using the offset into the the {@link ICompilationUnit}
+ * @param jtype
+ * @param document
+ * @param reference
+ * @param offset
+ * @return
+ * @throws JavaModelException
+ */
+ protected IMethod quickLookup(final IType jtype, IDocument document, IReference reference, int offset) throws JavaModelException {
+ if(offset > -1) {
+ IJavaElement element = jtype.getCompilationUnit().getElementAt(offset);
+ if(element != null) {
+ IJavaElement ancestor = element.getAncestor(IJavaElement.METHOD);
+ if (ancestor != null) {
+ return (IMethod) ancestor;
+ }
+ }
+ }
+ return null;
+ }
+
/* (non-Javadoc)
* @see org.eclipse.pde.api.tools.internal.search.AbstractProblemDetector#getSourceRange(org.eclipse.jdt.core.IType, org.eclipse.jface.text.IDocument, org.eclipse.pde.api.tools.internal.provisional.model.IReference)
*/
protected Position getSourceRange(IType type, IDocument doc, IReference reference) throws CoreException, BadLocationException {
+ IApiMember member = reference.getMember();
+ if(member.getType() == IApiElement.TYPE) {
+ ApiType ltype = (ApiType) member;
+ IMethod method = null;
+ if(ltype.isAnonymous()) {
+ // has a side-effect on reference.getMember().setEnclosingMethodInfo(..)
+ getEnclosingMethod(type, reference, doc);
+ if(reference.getLineNumber() < 0) {
+ return defaultSourcePosition(type, reference);
+ }
+ String name = getSimpleTypeName(reference.getResolvedReference());
+ Position pos = getMethodNameRange(true, name, doc, reference);
+ if(pos == null) {
+ return defaultSourcePosition(type, reference);
+ }
+ return pos;
+ }
+ if(ltype.isLocal()) {
+ String name = ltype.getSimpleName();
+ ICompilationUnit cunit = type.getCompilationUnit();
+ if(cunit.isWorkingCopy()) {
+ cunit.reconcile(AST.JLS4, false, null, null);
+ }
+ IType localtype = type;
+ method = getEnclosingMethod(type, reference, doc);
+ if(method != null) {
+ localtype = method.getType(name, 1);
+ }
+ if(localtype.exists()) {
+ ISourceRange range = localtype.getNameRange();
+ return new Position(range.getOffset(), range.getLength());
+ }
+ return defaultSourcePosition(type, reference);
+ }
+ }
ISourceRange range = type.getNameRange();
Position pos = null;
if(range != null) {
@@ -107,6 +301,39 @@ public abstract class AbstractIllegalTypeReference extends AbstractProblemDetect
* @see org.eclipse.pde.api.tools.internal.search.AbstractProblemDetector#getMessageArgs(org.eclipse.pde.api.tools.internal.provisional.model.IReference)
*/
protected String[] getMessageArgs(IReference reference) throws CoreException {
+ IApiMember member = reference.getMember();
+ if(member.getType() == IApiElement.TYPE) {
+ ApiType ltype = (ApiType) member;
+ String simpleTypeName = getSimpleTypeName(reference.getResolvedReference());
+ if(ltype.isAnonymous()) {
+ IApiType etype = ltype.getEnclosingType();
+ String signature = Signatures.getQualifiedTypeSignature(etype);
+ IApiMethod method = ltype.getEnclosingMethod();
+ if(method != null) {
+ signature = Signatures.getQualifiedMethodSignature(method);
+ }
+ return new String[] {signature, simpleTypeName};
+ }
+ if(ltype.isLocal()) {
+ //local types are always defined in methods, include enclosing method infos in message
+ IApiType etype = ltype.getEnclosingType();
+ IApiMethod method = ltype.getEnclosingMethod();
+ if(method != null) {
+ String methodsig = Signatures.getQualifiedMethodSignature(method);
+ return new String[] {
+ Signatures.getAnonymousTypeName(ltype.getName()),
+ methodsig,
+ simpleTypeName
+ };
+ }
+ else {
+ return new String[] {
+ Signatures.getAnonymousTypeName(ltype.getName()),
+ getSimpleTypeName(etype),
+ simpleTypeName};
+ }
+ }
+ }
return new String[] {
getSimpleTypeName(reference.getResolvedReference()),
getSimpleTypeName(reference.getMember())};
@@ -116,6 +343,13 @@ public abstract class AbstractIllegalTypeReference extends AbstractProblemDetect
* @see org.eclipse.pde.api.tools.internal.search.AbstractProblemDetector#getQualifiedMessageArgs(org.eclipse.pde.api.tools.internal.provisional.model.IReference)
*/
protected String[] getQualifiedMessageArgs(IReference reference) throws CoreException {
+ IApiMember member = reference.getMember();
+ if(member.getType() == IApiElement.TYPE) {
+ ApiType ltype = (ApiType) member;
+ if(ltype.isLocal() || ltype.isAnonymous()) {
+ return getMessageArgs(reference);
+ }
+ }
return new String[] {
getQualifiedTypeName(reference.getResolvedReference()),
getQualifiedTypeName(reference.getMember())};
@@ -125,6 +359,16 @@ public abstract class AbstractIllegalTypeReference extends AbstractProblemDetect
* @see org.eclipse.pde.api.tools.internal.search.AbstractProblemDetector#getProblemFlags(org.eclipse.pde.api.tools.internal.provisional.model.IReference)
*/
protected int getProblemFlags(IReference reference) {
+ IApiMember member = reference.getMember();
+ if(member.getType() == IApiElement.TYPE) {
+ IApiType type = (IApiType) reference.getMember();
+ if(type.isLocal()) {
+ return IApiProblem.LOCAL_TYPE;
+ }
+ if(type.isAnonymous()) {
+ return IApiProblem.ANONYMOUS_TYPE;
+ }
+ }
return IApiProblem.NO_FLAGS;
}
}
diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/IllegalExtendsProblemDetector.java b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/IllegalExtendsProblemDetector.java
index c430ca9196..fb5336aeb4 100644
--- a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/IllegalExtendsProblemDetector.java
+++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/IllegalExtendsProblemDetector.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2011 IBM Corporation and others.
+ * Copyright (c) 2008, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,31 +10,9 @@
*******************************************************************************/
package org.eclipse.pde.api.tools.internal.builder;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.IJavaElement;
-import org.eclipse.jdt.core.IMethod;
-import org.eclipse.jdt.core.ISourceRange;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.Signature;
-import org.eclipse.jdt.core.dom.AST;
-import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.ASTParser;
-import org.eclipse.jdt.core.dom.ASTVisitor;
-import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
-import org.eclipse.jdt.core.dom.ITypeBinding;
-import org.eclipse.jdt.core.dom.TypeDeclaration;
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.Position;
-import org.eclipse.pde.api.tools.internal.model.ApiType;
import org.eclipse.pde.api.tools.internal.provisional.builder.IReference;
-import org.eclipse.pde.api.tools.internal.provisional.model.IApiMethod;
-import org.eclipse.pde.api.tools.internal.provisional.model.IApiType;
import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemTypes;
-import org.eclipse.pde.api.tools.internal.util.Signatures;
/**
* Detects when a type illegally extends another type.
@@ -43,62 +21,6 @@ import org.eclipse.pde.api.tools.internal.util.Signatures;
*/
public class IllegalExtendsProblemDetector extends AbstractIllegalTypeReference {
- /**
- * Class used to look up the name of the enclosing method for an {@link IApiType} when we do not have any
- * enclosing method infos (pre Java 1.5 class files
- */
- class MethodFinder extends ASTVisitor {
- IMethod method = null;
- private IType jtype = null;
- private ApiType type = null;
-
- public MethodFinder(ApiType type, IType jtype) {
- this.type = type;
- this.jtype = jtype;
- }
- public boolean visit(AnonymousClassDeclaration node) {
- if(method == null) {
- ITypeBinding binding = node.resolveBinding();
- String binaryName = binding.getBinaryName();
- if(type.getName().endsWith(binaryName)) {
- try {
- IJavaElement element = jtype.getCompilationUnit().getElementAt(node.getStartPosition());
- if(element != null) {
- IJavaElement ancestor = element.getAncestor(IJavaElement.METHOD);
- if(ancestor != null) {
- method = (IMethod) ancestor;
- }
- }
- }
- catch(JavaModelException jme) {}
- return false;
- }
- }
- return true;
- }
- public boolean visit(TypeDeclaration node) {
- if(method == null && node.isLocalTypeDeclaration()) {
- ITypeBinding binding = node.resolveBinding();
- String binaryName = binding.getBinaryName();
- if(type.getName().endsWith(binaryName)) {
- try {
- IJavaElement element = jtype.getCompilationUnit().getElementAt(node.getStartPosition());
- if(element.getElementType() == IJavaElement.TYPE) {
- IType ltype = (IType) element;
- IJavaElement parent = ltype.getParent();
- if(parent.getElementType() == IJavaElement.METHOD) {
- method = (IMethod) parent;
- }
- }
- }
- catch(JavaModelException jme) {}
- return false;
- }
- }
- return true;
- }
- };
-
/* (non-Javadoc)
* @see org.eclipse.pde.api.tools.internal.provisional.search.IApiProblemDetector#getReferenceKinds()
*/
@@ -114,181 +36,9 @@ public class IllegalExtendsProblemDetector extends AbstractIllegalTypeReference
}
/* (non-Javadoc)
- * @see org.eclipse.pde.api.tools.internal.builder.AbstractIllegalTypeReference#getProblemFlags(org.eclipse.pde.api.tools.internal.provisional.builder.IReference)
- */
- protected int getProblemFlags(IReference reference) {
- IApiType type = (IApiType) reference.getMember();
- if(type.isLocal()) {
- return IApiProblem.LOCAL_TYPE;
- }
- if(type.isAnonymous()) {
- return IApiProblem.ANONYMOUS_TYPE;
- }
- return super.getProblemFlags(reference);
- }
-
- /* (non-Javadoc)
* @see org.eclipse.pde.api.tools.internal.search.AbstractIllegalTypeReference#getSeverityKey()
*/
protected String getSeverityKey() {
return IApiProblemTypes.ILLEGAL_EXTEND;
}
-
- /* (non-Javadoc)
- * @see org.eclipse.pde.api.tools.internal.builder.AbstractIllegalTypeReference#getMessageArgs(org.eclipse.pde.api.tools.internal.provisional.builder.IReference)
- */
- protected String[] getMessageArgs(IReference reference) throws CoreException {
- ApiType ltype = (ApiType) reference.getMember();
- String simpleTypeName = getSimpleTypeName(reference.getResolvedReference());
- if(ltype.isAnonymous()) {
- IApiType etype = ltype.getEnclosingType();
- String signature = Signatures.getQualifiedTypeSignature(etype);
- IApiMethod method = ltype.getEnclosingMethod();
- if(method != null) {
- signature = Signatures.getQualifiedMethodSignature(method);
- }
- return new String[] {signature, simpleTypeName};
- }
- if(ltype.isLocal()) {
- //local types are always defined in methods, include enclosing method infos in message
- IApiType etype = ltype.getEnclosingType();
- IApiMethod method = ltype.getEnclosingMethod();
- if(method != null) {
- String methodsig = Signatures.getQualifiedMethodSignature(method);
- return new String[] {
- Signatures.getAnonymousTypeName(ltype.getName()),
- methodsig,
- simpleTypeName
- };
- }
- else {
- return new String[] {
- Signatures.getAnonymousTypeName(ltype.getName()),
- getSimpleTypeName(etype),
- simpleTypeName};
- }
- }
- return super.getMessageArgs(reference);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.pde.api.tools.internal.builder.AbstractIllegalTypeReference#getQualifiedMessageArgs(org.eclipse.pde.api.tools.internal.provisional.builder.IReference)
- */
- protected String[] getQualifiedMessageArgs(IReference reference) throws CoreException {
- ApiType ltype = (ApiType) reference.getMember();
- if(ltype.isLocal() || ltype.isAnonymous()) {
- return this.getMessageArgs(reference);
- }
- return super.getQualifiedMessageArgs(reference);
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.pde.api.tools.internal.builder.AbstractIllegalTypeReference#getSourceRange(org.eclipse.jdt.core.IType, org.eclipse.jface.text.IDocument, org.eclipse.pde.api.tools.internal.provisional.builder.IReference)
- */
- protected Position getSourceRange(IType type, IDocument doc, IReference reference) throws CoreException, BadLocationException {
- ApiType ltype = (ApiType) reference.getMember();
- IMethod method = null;
- if(ltype.isAnonymous()) {
- // has a side-effect on reference.getMember().setEnclosingMethodInfo(..)
- getEnclosingMethod(type, reference, doc);
- if(reference.getLineNumber() < 0) {
- return defaultSourcePosition(type, reference);
- }
- String name = getSimpleTypeName(reference.getResolvedReference());
- Position pos = getMethodNameRange(true, name, doc, reference);
- if(pos == null) {
- return defaultSourcePosition(type, reference);
- }
- return pos;
- }
- if(ltype.isLocal()) {
- String name = ltype.getSimpleName();
- ICompilationUnit cunit = type.getCompilationUnit();
- if(cunit.isWorkingCopy()) {
- cunit.reconcile(AST.JLS4, false, null, null);
- }
- IType localtype = type;
- method = getEnclosingMethod(type, reference, doc);
- if(method != null) {
- localtype = method.getType(name, 1);
- }
- if(localtype.exists()) {
- ISourceRange range = localtype.getNameRange();
- return new Position(range.getOffset(), range.getLength());
- }
- return defaultSourcePosition(type, reference);
- }
- return super.getSourceRange(type, doc, reference);
- }
- /**
- * Returns the enclosing {@link IMethod} for the given type or <code>null</code>
- * if it cannot be computed
- * @param type
- * @param jtype
- * @param reference
- * @param document
- * @return the {@link IMethod} enclosing the given type or <code>null</code>
- * @throws CoreException
- */
- private IMethod getEnclosingMethod(final IType jtype, IReference reference, IDocument document) throws CoreException {
- ApiType type = (ApiType) reference.getMember();
- IApiMethod apimethod = type.getEnclosingMethod();
- if(apimethod != null) {
- String signature = Signatures.processMethodSignature(apimethod);
- String methodname = Signatures.getMethodName(apimethod);
- IMethod method = jtype.getMethod(methodname, Signature.getParameterTypes(signature));
- if(method.exists()) {
- return method;
- }
- }
- else {
- //try to look it up
- IMethod method = null;
- if(reference.getLineNumber() > -1) {
- try {
- int offset = document.getLineOffset(reference.getLineNumber());
- method = quickLookup(jtype, document, reference, offset);
- }
- catch(BadLocationException ble) {}
- }
- if(method == null) {
- //look it up the hard way
- ISourceRange range = jtype.getCompilationUnit().getSourceRange();
- ASTParser parser = ASTParser.newParser(AST.JLS4);
- parser.setSource(jtype.getCompilationUnit());
- parser.setSourceRange(range.getOffset(), range.getLength());
- parser.setResolveBindings(true);
- ASTNode ptype = parser.createAST(null);
- MethodFinder finder = new MethodFinder(type, jtype);
- ptype.accept(finder);
- method = finder.method;
- }
- if(method != null && method.exists()) {
- ApiType etype = (ApiType) type.getEnclosingType();
- IApiMethod[] methods = etype.getMethods();
- String msig = null;
- for (int i = 0; i < methods.length; i++) {
- msig = methods[i].getSignature();
- if(Signatures.getMethodName(methods[i]).equals(method.getElementName()) &&
- Signatures.matchesSignatures(msig.replace('/', '.'), method.getSignature())) {
- type.setEnclosingMethodInfo(methods[i].getName(), msig);
- }
- }
- return method;
- }
- }
- return null;
- }
- private IMethod quickLookup(final IType jtype, IDocument document, IReference reference, int offset) throws JavaModelException {
- if(offset > -1) {
- IJavaElement element = jtype.getCompilationUnit().getElementAt(offset);
- if(element != null) {
- IJavaElement ancestor = element.getAncestor(IJavaElement.METHOD);
- if (ancestor != null) {
- return (IMethod) ancestor;
- }
- }
- }
- return null;
- }
}
diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/IllegalImplementsProblemDetector.java b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/IllegalImplementsProblemDetector.java
index 95f744b502..f301bcf85c 100644
--- a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/IllegalImplementsProblemDetector.java
+++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/builder/IllegalImplementsProblemDetector.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2012 IBM Corporation and others.
+ * Copyright (c) 2008, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -116,33 +116,35 @@ public class IllegalImplementsProblemDetector extends AbstractIllegalTypeReferen
* @see org.eclipse.pde.api.tools.internal.search.AbstractIllegalTypeReference#getMessageArgs(org.eclipse.pde.api.tools.internal.provisional.model.IReference)
*/
protected String[] getMessageArgs(IReference reference) throws CoreException {
- if(isIllegalType(reference)) {
- return super.getMessageArgs(reference);
- }
- if(fRestrictedInterfaces.size() > 0) {
+ String[] args = super.getMessageArgs(reference);
+ if(!isIllegalType(reference) && fRestrictedInterfaces.size() > 0) {
IApiType type = (IApiType) reference.getResolvedReference();
IApiType inter = (IApiType) fRestrictedInterfaces.get(type.getName());
if(inter != null) {
- return new String[] {getSimpleTypeName(type), inter.getSimpleName(), getSimpleTypeName(reference.getMember())};
+ String[] newargs = new String[args.length+1];
+ System.arraycopy(args, 0, newargs, 0, args.length);
+ newargs[args.length] = getSimpleTypeName(inter);
+ return newargs;
}
}
- return super.getMessageArgs(reference);
+ return args;
}
/* (non-Javadoc)
* @see org.eclipse.pde.api.tools.internal.search.AbstractIllegalTypeReference#getMessageArgs(org.eclipse.pde.api.tools.internal.provisional.model.IReference)
*/
protected String[] getQualifiedMessageArgs(IReference reference) throws CoreException {
- if(isIllegalType(reference)) {
- return super.getQualifiedMessageArgs(reference);
- }
- if(fRestrictedInterfaces.size() > 0) {
+ String[] args = super.getQualifiedMessageArgs(reference);
+ if(!isIllegalType(reference) && fRestrictedInterfaces.size() > 0) {
IApiType type = (IApiType) reference.getResolvedReference();
IApiType inter = (IApiType) fRestrictedInterfaces.get(type.getName());
if(inter != null) {
- return new String[] {getQualifiedTypeName(type), inter.getName(), getQualifiedTypeName(reference.getMember())};
+ String[] newargs = new String[args.length+1];
+ System.arraycopy(args, 0, newargs, 0, args.length);
+ newargs[args.length] = inter.getName();
+ return newargs;
}
}
- return super.getQualifiedMessageArgs(reference);
+ return args;
}
/* (non-Javadoc)
@@ -152,6 +154,10 @@ public class IllegalImplementsProblemDetector extends AbstractIllegalTypeReferen
if(isIllegalType(reference)) {
return super.getProblemFlags(reference);
}
+ IApiType type = (IApiType) reference.getMember();
+ if(type.isLocal()) {
+ return IApiProblem.INDIRECT_LOCAL_REFERENCE;
+ }
return IApiProblem.INDIRECT_REFERENCE;
}
@@ -217,7 +223,8 @@ public class IllegalImplementsProblemDetector extends AbstractIllegalTypeReferen
if(!comp.equals(originalcomponent)) {
annot = comp.getApiDescription().resolveAnnotations(Factory.typeDescriptor(inters[i].getName()));
if(annot != null && RestrictionModifiers.isImplementRestriction(annot.getRestrictions())) {
- return fRestrictedInterfaces.put(entryinterface, inters[i]) == null;
+ fRestrictedInterfaces.put(entryinterface, inters[i]);
+ return true;
}
}
return findRestrictedSuperinterfaces(originalcomponent, entryinterface, inters[i]);
diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/ApiProblemFactory.java b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/ApiProblemFactory.java
index dc38f62dcf..d9670d09bd 100644
--- a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/ApiProblemFactory.java
+++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/ApiProblemFactory.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2011 IBM Corporation and others.
+ * Copyright (c) 2008, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -459,6 +459,8 @@ public class ApiProblemFactory {
switch(flags) {
case IApiProblem.NO_FLAGS: return 8;
case IApiProblem.INDIRECT_REFERENCE: return 24;
+ case IApiProblem.LOCAL_TYPE: return 18;
+ case IApiProblem.INDIRECT_LOCAL_REFERENCE: return 37;
}
break;
}
diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/problemmessages.properties b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/problemmessages.properties
index 3939aafd0f..4dddfabfcb 100644
--- a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/problemmessages.properties
+++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/problems/problemmessages.properties
@@ -1,5 +1,5 @@
###############################################################################
-# Copyright (c) 2008, 2011 IBM Corporation and others.
+# Copyright (c) 2008, 2013 IBM Corporation and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
@@ -11,6 +11,10 @@
# remove messages for 38, 42,
# 45, 46, 47, 48, 49, 50, 51, 52, 53, 57, 58, 59, 60, 62, 63, 65, 68, 70, 71, 74, 75, 80,
# 82, 83, 88, 90, 93, 05
+
+#AVAILABLE MESSAGES
+# 27
+
#api baseline
1 = An API baseline has not been set for the current workspace.
31 = API analysis aborted for ''{0}'' since its build path is incomplete
@@ -44,8 +48,9 @@
15 = {1}.{2} declared as non-API type {0}
16 = {1}.{2} has non-API return type {0}
17 = {1}.{2} has non-API parameter type {0}
+18 = The local type {0} defined in {1} illegally implements {2}
22 = Tag ''{0}'' is already defined on this element
-24 = {2} illegally implements {1} via {0}
+24 = {1} illegally implements {2} via {0}
25 = The local type {0} defined in {1} illegally extends {2}
28 = An anonymous type defined in {0} illegally extends {1}
30 = The API problem filter for: ''{0}'' is no longer used
@@ -53,6 +58,7 @@
34 = The constructor {1} referenced in {0} is not defined in the bundle''s required execution environment: {2}
35 = The field {1}.{2} referenced in {0} is not defined in the bundle''s required execution environment: {3}
36 = The type {1} referenced in {0} is not defined in the bundle''s required execution environment: {2}
+37 = The local type {0} defined in {1} illegally implements {3} via {2}
109 = Constructor for {1} with non-API parameter type {0}
110 = {1} illegally references constructor {0}
111 = {1} illegally references method {0}.{2}
diff --git a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/provisional/problems/IApiProblem.java b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/provisional/problems/IApiProblem.java
index 3940c7945c..33af66e714 100644
--- a/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/provisional/problems/IApiProblem.java
+++ b/apitools/org.eclipse.pde.api.tools/src/org/eclipse/pde/api/tools/internal/provisional/problems/IApiProblem.java
@@ -403,12 +403,22 @@ public interface IApiProblem {
/**
* Flags to indicate an indirect reference
* <br>
- * Value is: <code>10</code>
+ * Value is: <code>12</code>
+ *
+ * @see #getFlags()
+ * @see #CATEGORY_USAGE
+ */
+ public static final int INDIRECT_REFERENCE = 12;
+
+ /**
+ * Flags to indicate an indirect reference from a local type
+ * <br>
+ * Value is: <code>13</code>
*
* @see #getFlags()
* @see #CATEGORY_USAGE
*/
- public static final int INDIRECT_REFERENCE = 10;
+ public static final int INDIRECT_LOCAL_REFERENCE = 13;
/**
* Constant representing the value of a default API profile {@link IApiProblem} kind.

Back to the top