diff options
| author | Mike Rennie | 2013-03-18 21:10:47 +0000 |
|---|---|---|
| committer | Mike Rennie | 2013-03-18 21:10:47 +0000 |
| commit | 83655c5d1780a74e2d7c6b667c44ad80f8afb577 (patch) | |
| tree | 5952c8c6a894d1cf2d84c7bd46a912988eeb74d0 | |
| parent | 3a250add62581c54025d36f5f414dad9724cb75b (diff) | |
| download | eclipse.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
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. |
