diff options
author | Srikanth Sankaran | 2014-03-14 12:55:51 +0000 |
---|---|---|
committer | Jayaprakash Arthanareeswaran | 2014-03-14 14:50:51 +0000 |
commit | fd6aadcfaa6ea7e0174e1c47fdc6ce06626c6eea (patch) | |
tree | 6c9d69cebf584a0af0082c37fafd80e1774736e2 | |
parent | a1df1743aeff71de75237f6e50af470ebbed4600 (diff) | |
download | eclipse.jdt.core-fd6aadcfaa6ea7e0174e1c47fdc6ce06626c6eea.tar.gz eclipse.jdt.core-fd6aadcfaa6ea7e0174e1c47fdc6ce06626c6eea.tar.xz eclipse.jdt.core-fd6aadcfaa6ea7e0174e1c47fdc6ce06626c6eea.zip |
Fix for Bug 430307 - [1.8][model] NPE trying to get children of aP20140315-1600P20140314-1600P20140314-1525P20140314-1445
LambdaExpression restored from handleIdentifier
Signed-off-by: Srikanth Sankaran <srikanth_sankaran@in.ibm.com>
4 files changed, 154 insertions, 15 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElement8Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElement8Tests.java index 038aa15c42..bbe89265b5 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElement8Tests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElement8Tests.java @@ -520,7 +520,7 @@ public class JavaElement8Tests extends AbstractJavaModelTests { assertEquals("Incorrect java element", IJavaElement.LOCAL_VARIABLE, elements[0].getElementType()); IType lambda = (IType) elements[0].getParent().getParent(); String mem = lambda.getHandleIdentifier(); - String expected = "=\\(\\[Bug430136\\]\\)/src<{X.java[MyFunction~compose~QMyFunction\\<-QV;+QT;>;=)Lambda\\(MyFunction\\)=\"LMyFunction\\<TV;TR;>;!148!174!151"; + String expected = "=\\(\\[Bug430136\\])/src<{X.java[MyFunction~compose~QMyFunction\\<-QV;+QT;>;=)Lambda\\(MyFunction)=\"LMyFunction\\<TV;TR;>;!148!174!151=&apply!1=\"TV;=\"v=\"TR;=\"LX\\~MyFunction\\<LX\\~MyFunction;:1TV;LX\\~MyFunction;:TR;>;.apply\\(TV;)TR;@v!148!148!148!148!Ljava\\/lang\\/Object;!0!true=)"; assertEquals("Incorrect memento", expected, mem); IJavaElement result = JavaCore.create(expected); assertEquals("Incorrect element created", lambda, result); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests18.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests18.java index f7332be73b..c4f1fbbcb4 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests18.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests18.java @@ -21,11 +21,13 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.ICodeAssist; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.ILocalVariable; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.WorkingCopyOwner; import org.eclipse.jdt.internal.core.LambdaExpression; +import org.eclipse.jdt.internal.core.LambdaMethod; public class ResolveTests18 extends AbstractJavaModelTests { ICompilationUnit wc = null; @@ -2424,14 +2426,14 @@ public void test430136() throws CoreException { IMethod lambda = (IMethod) elements[0].getParent(); String memento = lambda.getHandleIdentifier(); assertEquals("Incorrect memento string", - "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!144!161!152=&get!2=\"Ljava.util.List\\<TU;>;=\"x=\"I=\"i=\"TU;=\"LX\\~Getter\\<LX;:TU;>;.get\\(Ljava\\/util\\/List\\<TU;>;I)TU;@x!145!145!145!145!Ljava\\/util\\/List;!0!true@i!148!148!148!148!I!0!true", + "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!144!161!152=&get!2=\"Ljava.util.List\\<TU;>;=\"x=\"I=\"i=\"TU;=\"LX\\~Getter\\<LX;:TU;>;.get\\(Ljava\\/util\\/List\\<TU;>;I)TU;@x!145!145!145!145!Ljava\\/util\\/List;!0!true@i!148!148!148!148!I!0!true=&", memento); IJavaElement result = JavaCore.create(memento); assertEquals("Java elements should be equal", lambda, result); LambdaExpression expression = (LambdaExpression) lambda.getParent(); memento = expression.getHandleIdentifier(); assertEquals("Incorrect memento string", - "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!144!161!152", + "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!144!161!152=&get!2=\"Ljava.util.List\\<TU;>;=\"x=\"I=\"i=\"TU;=\"LX\\~Getter\\<LX;:TU;>;.get\\(Ljava\\/util\\/List\\<TU;>;I)TU;@x!145!145!145!145!Ljava\\/util\\/List;!0!true@i!148!148!148!148!I!0!true=)", memento); result = JavaCore.create(memento); assertEquals("Java elements should be equal", expression, result); @@ -2441,16 +2443,137 @@ public void test430136() throws CoreException { lambda = (IMethod) elements[0].getParent(); memento = lambda.getHandleIdentifier(); assertEquals("Incorrect memento string", - "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!180!197!188=&get!2=\"Ljava.util.List\\<TU;>;=\"x=\"I=\"i=\"TU;=\"LX\\~Getter\\<LX;:TU;>;.get\\(Ljava\\/util\\/List\\<TU;>;I)TU;@x!181!181!181!181!Ljava\\/util\\/List;!0!true@i!184!184!184!184!I!0!true", + "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!180!197!188=&get!2=\"Ljava.util.List\\<TU;>;=\"x=\"I=\"i=\"TU;=\"LX\\~Getter\\<LX;:TU;>;.get\\(Ljava\\/util\\/List\\<TU;>;I)TU;@x!181!181!181!181!Ljava\\/util\\/List;!0!true@i!184!184!184!184!I!0!true=&", memento); result = JavaCore.create(memento); assertEquals("Java elements should be equal", lambda, result); expression = (LambdaExpression) lambda.getParent(); memento = expression.getHandleIdentifier(); assertEquals("Incorrect memento string", - "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!180!197!188", + "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!180!197!188=&get!2=\"Ljava.util.List\\<TU;>;=\"x=\"I=\"i=\"TU;=\"LX\\~Getter\\<LX;:TU;>;.get\\(Ljava\\/util\\/List\\<TU;>;I)TU;@x!181!181!181!181!Ljava\\/util\\/List;!0!true@i!184!184!184!184!I!0!true=)", memento); result = JavaCore.create(memento); assertEquals("Java elements should be equal", expression, result); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=430307, [1.8][model] NPE trying to get children of a LambdaExpression restored from handleIdentifier +public void test430307() throws CoreException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy("/Resolve/src/X.java", + "import java.util.List;\n" + + "interface Getter<E> {\n" + + " E get(List<E> list, int i);\n" + + "}\n" + + "public class X<U> {\n" + + " public void foo(List<U> l) {\n" + + " Getter<U> g= (x, i) -> x.get(i);\n" + + " } \n" + + "}\n" + ); + + String str = this.workingCopies[0].getSource(); + + String selection = "x,"; + int start = str.indexOf(selection); + IJavaElement[] elements = this.workingCopies[0].codeSelect(start, 1); + ILocalVariable local = (ILocalVariable) elements[0]; + String memento = local.getHandleIdentifier(); + assertEquals("Incorrect memento string", + "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!144!161!152=&get!2=\"Ljava.util.List\\<TU;>;=\"x=\"I=\"i=\"TU;=\"LX\\~Getter\\<LX;:TU;>;.get\\(Ljava\\/util\\/List\\<TU;>;I)TU;@x!145!145!145!145!Ljava\\/util\\/List;!0!true@i!148!148!148!148!I!0!true=&@x!145!145!145!145!Ljava.util.List\\<LU;>;!0!true", + memento); + IJavaElement result = JavaCore.create(memento); + assertEquals("Java elements should be equal", local, result); + + IJavaElement parentMethod = result.getParent(); + IJavaElement parentExpr = parentMethod.getParent(); + IMethod lambda = (IMethod) elements[0].getParent(); + memento = lambda.getHandleIdentifier(); + assertEquals("Incorrect memento string", + "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!144!161!152=&get!2=\"Ljava.util.List\\<TU;>;=\"x=\"I=\"i=\"TU;=\"LX\\~Getter\\<LX;:TU;>;.get\\(Ljava\\/util\\/List\\<TU;>;I)TU;@x!145!145!145!145!Ljava\\/util\\/List;!0!true@i!148!148!148!148!I!0!true=&", + memento); + result = JavaCore.create(memento); + assertEquals("Java elements should be equal", lambda, result); + assertEquals("Java elements should be equal", result, parentMethod); + LambdaExpression expression = (LambdaExpression) lambda.getParent(); + memento = expression.getHandleIdentifier(); + assertEquals("Incorrect memento string", + "=Resolve/src<{X.java[X~foo~QList\\<QU;>;=)Lambda\\(Getter)=\"LGetter\\<TU;>;!144!161!152=&get!2=\"Ljava.util.List\\<TU;>;=\"x=\"I=\"i=\"TU;=\"LX\\~Getter\\<LX;:TU;>;.get\\(Ljava\\/util\\/List\\<TU;>;I)TU;@x!145!145!145!145!Ljava\\/util\\/List;!0!true@i!148!148!148!148!I!0!true=)", + memento); + LambdaExpression recreatedType = (LambdaExpression) JavaCore.create(memento); + assertEquals("Java elements should be equal", expression, recreatedType); + assertEquals("Java elements should be equal", recreatedType, parentExpr); + LambdaMethod child = (LambdaMethod) recreatedType.getChildren()[0]; + assertEquals("Java elements should be equal", lambda, child); +} +public void test430307a() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy("/Resolve/src/X.java", + "interface I {\n" + + " I doit(I xyz);\n" + + "}\n" + + "public class X { \n" + + " public static void main(String[] args) {\n" + + " I i = (pqr) -> {\n" + + " return (xyz) -> {\n" + + " return (abc) -> abc; \n" + + " };\n" + + " };\n" + + " }\n" + + "}\n"); + String str = this.workingCopies[0].getSource(); + + String selection = "abc)"; + int start = str.indexOf(selection); + IJavaElement[] elements = this.workingCopies[0].codeSelect(start, 3); + ILocalVariable local = (ILocalVariable) elements[0]; + String memento = local.getHandleIdentifier(); + assertEquals( + "Incorrect memento string", + "=Resolve/src<{X.java[X~main~\\[QString;=)Lambda\\(I)=\"LI;!103!169!110=&doit!1=\"LI;=\"pqr=\"LI;=\"LX\\~I;.doit\\(LI;)" + + "LI;@pqr!104!106!104!106!LI;!0!true=&=)Lambda\\(I)=\"LI;!124!164!131=&doit!1=\"LI;=\"xyz=\"LI;=\"LX\\~I;.doit\\(LI;)" + + "LI;@xyz!125!127!125!127!LI;!0!true=&=)Lambda\\(I)=\"LI;!146!157!153=&doit!1=\"LI;=\"abc=\"LI;=\"LX\\~I;.doit\\(LI;)" + + "LI;@abc!147!149!147!149!LI;!0!true=&@abc!147!149!147!149!LI;!0!true", + memento); + IJavaElement result = JavaCore.create(memento); + assertEquals("Java elements should be equal", local, result); + + IJavaElement parentMethod = result.getParent(); + IJavaElement parentExpr = parentMethod.getParent(); + assertEquals("Java elements should be equal", parentMethod, local.getParent()); + assertEquals("Java elements should be equal", parentExpr, local.getParent().getParent()); + + selection = "xyz)"; + start = str.lastIndexOf(selection); + elements = this.workingCopies[0].codeSelect(start, 3); + local = (ILocalVariable) elements[0]; + memento = local.getHandleIdentifier(); + assertEquals("Incorrect memento string", + "=Resolve/src<{X.java[X~main~\\[QString;=)Lambda\\(I)=\"LI;!103!169!110=&doit!1=\"LI;=\"pqr=\"LI;=\"LX\\~I;.doit\\(LI;)" + + "LI;@pqr!104!106!104!106!LI;!0!true=&=)Lambda\\(I)=\"LI;!124!164!131=&doit!1=\"LI;=\"xyz=\"LI;=\"LX\\~I;.doit\\(LI;)" + + "LI;@xyz!125!127!125!127!LI;!0!true=&@xyz!125!127!125!127!LI;!0!true", + memento); + result = JavaCore.create(memento); + assertEquals("Java elements should be equal", local, result); + + parentMethod = result.getParent(); + parentExpr = parentMethod.getParent(); + assertEquals("Java elements should be equal", parentMethod, local.getParent()); + assertEquals("Java elements should be equal", parentExpr, local.getParent().getParent()); + + selection = "pqr)"; + start = str.indexOf(selection); + elements = this.workingCopies[0].codeSelect(start, 3); + local = (ILocalVariable) elements[0]; + memento = local.getHandleIdentifier(); + assertEquals("Incorrect memento string", + "=Resolve/src<{X.java[X~main~\\[QString;=)Lambda\\(I)=\"LI;!103!169!110=&doit!1=\"LI;=\"pqr=\"LI;=\"LX\\~I;.doit\\(LI;)" + + "LI;@pqr!104!106!104!106!LI;!0!true=&@pqr!104!106!104!106!LI;!0!true", + memento); + result = JavaCore.create(memento); + assertEquals("Java elements should be equal", local, result); + + parentMethod = result.getParent(); + parentExpr = parentMethod.getParent(); + assertEquals("Java elements should be equal", parentMethod, local.getParent()); + assertEquals("Java elements should be equal", parentExpr, local.getParent().getParent()); +} } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LambdaExpression.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LambdaExpression.java index b1d0d55dbe..2736fc0bd4 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LambdaExpression.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LambdaExpression.java @@ -131,11 +131,13 @@ public class LambdaExpression extends SourceType { * @see JavaElement#getHandleMemento(StringBuffer) */ protected void getHandleMemento(StringBuffer buff) { - getHandleMemento(buff, true); + getHandleMemento(buff, true, true); + // lambda method and lambda expression cannot share the same memento - add a trailing discriminator. + appendEscapedDelimiter(buff, getHandleMementoDelimiter()); } - protected void getHandleMemento(StringBuffer buff, boolean memoizeParent) { - if (memoizeParent) + protected void getHandleMemento(StringBuffer buff, boolean serializeParent, boolean serializeChild) { + if (serializeParent) ((JavaElement)getParent()).getHandleMemento(buff); appendEscapedDelimiter(buff, getHandleMementoDelimiter()); escapeMementoName(buff, this.name); @@ -147,6 +149,8 @@ public class LambdaExpression extends SourceType { buff.append(this.sourceEnd); buff.append(JEM_COUNT); buff.append(this.arrowPosition); + if (serializeChild) + this.lambdaMethod.getHandleMemento(buff, false); } public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner workingCopyOwner) { @@ -179,7 +183,17 @@ public class LambdaExpression extends SourceType { } this.lambdaMethod.elementInfo.arguments = parameters; this.elementInfo.children = new IJavaElement[] { this.lambdaMethod }; - return this.lambdaMethod; + if (!memento.hasMoreTokens()) + return this.lambdaMethod; + switch (memento.nextToken().charAt(0)) { + case JEM_LAMBDA_METHOD: + if (!memento.hasMoreTokens()) + return this.lambdaMethod; + return this.lambdaMethod.getHandleFromMemento(memento, workingCopyOwner); + case JEM_LAMBDA_EXPRESSION: + default: + return this; + } } public IJavaElement[] getChildren() throws JavaModelException { @@ -209,8 +223,7 @@ public class LambdaExpression extends SourceType { if (primaryParent instanceof JavaElement) { JavaElement ancestor = (JavaElement) primaryParent; StringBuffer buffer = new StringBuffer(32); - getHandleMemento(buffer, false); - this.lambdaMethod.getHandleMemento(buffer, false); + getHandleMemento(buffer, false, true); String memento = buffer.toString(); return ancestor.getHandleFromMemento(new MementoTokenizer(memento), DefaultWorkingCopyOwner.PRIMARY).getParent(); } @@ -220,4 +233,4 @@ public class LambdaExpression extends SourceType { public String[] getSuperInterfaceTypeSignatures() throws JavaModelException { return new String[] { this.interphase }; } -}
\ No newline at end of file +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LambdaMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LambdaMethod.java index a6912a7322..cf3e7c81a3 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LambdaMethod.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LambdaMethod.java @@ -134,9 +134,10 @@ public class LambdaMethod extends SourceMethod { return this.elementInfo; } - public void getHandleMemento(StringBuffer buff, boolean memoizeParent) { - if (memoizeParent) - ((JavaElement) getParent()).getHandleMemento(buff); + public void getHandleMemento(StringBuffer buff, boolean serializeParent) { + if (serializeParent) { + ((LambdaExpression) getParent()).getHandleMemento(buff, true, false); + } appendEscapedDelimiter(buff, getHandleMementoDelimiter()); escapeMementoName(buff, getElementName()); buff.append(JEM_COUNT); @@ -159,6 +160,8 @@ public class LambdaMethod extends SourceMethod { } public void getHandleMemento(StringBuffer buff) { getHandleMemento(buff, true); + // lambda method and lambda expression cannot share the same memento - add a trailing discriminator. + appendEscapedDelimiter(buff, getHandleMementoDelimiter()); } protected char getHandleMementoDelimiter() { |