| author | Jesper Moller | 2013-03-01 11:41:15 (EST) |
|---|---|---|
| committer | Mike Rennie | 2013-03-01 11:41:15 (EST) |
| commit | 1aedb345895fdc00d22405a63e97e9aff1443747 (patch) (side-by-side diff) | |
| tree | e84ec646add82b0638a3a6d7fce11d4a92002a41 | |
| parent | 26d128807758fa7f90ef77c98d735ae429f88671 (diff) | |
| download | eclipse.jdt.debug-1aedb345895fdc00d22405a63e97e9aff1443747.zip eclipse.jdt.debug-1aedb345895fdc00d22405a63e97e9aff1443747.tar.gz eclipse.jdt.debug-1aedb345895fdc00d22405a63e97e9aff1443747.tar.bz2 | |
Bug 341232 - Eclipse is not able to set the simplest of conditional
breakpoints and reports that the condition has compilation errors when
it doesn't
7 files changed, 209 insertions, 30 deletions
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java index fc3c7d6..ef43203 100644 --- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java +++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Jesper Steen Moller - bug 341232 *******************************************************************************/ package org.eclipse.jdt.debug.tests; @@ -360,6 +361,7 @@ public abstract class AbstractDebugTest extends TestCase implements IEvaluation cfgs.add(createLaunchConfiguration(jp, "a.b.c.MethodBreakpoints")); cfgs.add(createLaunchConfiguration(jp, "a.b.c.IntegerAccess")); cfgs.add(createLaunchConfiguration(jp, "a.b.c.StepIntoSelectionWithGenerics")); + cfgs.add(createLaunchConfiguration(jp, "a.b.c.ConditionalsNearGenerics")); loaded15 = true; waitForBuild(); } diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java index af076ff..1c336f5 100644 --- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java +++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java @@ -22,6 +22,7 @@ import org.eclipse.jdt.debug.testplugin.JavaProjectHelper; import org.eclipse.jdt.debug.tests.breakpoints.BreakpointListenerTests; import org.eclipse.jdt.debug.tests.breakpoints.BreakpointLocationVerificationTests; import org.eclipse.jdt.debug.tests.breakpoints.BreakpointWorkingSetTests; +import org.eclipse.jdt.debug.tests.breakpoints.ConditionalBreakpoints15Tests; import org.eclipse.jdt.debug.tests.breakpoints.ConditionalBreakpointsTests; import org.eclipse.jdt.debug.tests.breakpoints.DeferredBreakpointTests; import org.eclipse.jdt.debug.tests.breakpoints.ExceptionBreakpointTests; @@ -182,6 +183,7 @@ public class AutomatedSuite extends DebugSuite { addTest(new TestSuite(MethodBreakpointTests15.class)); addTest(new TestSuite(TestIntegerAccessUnboxing15.class)); addTest(new TestSuite(StepIntoSelectionWithGenerics.class)); + addTest(new TestSuite(ConditionalBreakpoints15Tests.class)); } //Sourcelookup tests diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ConditionalBreakpoints15Tests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ConditionalBreakpoints15Tests.java new file mode 100644 index 0000000..af41b34 --- a/dev/null +++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/ConditionalBreakpoints15Tests.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2012 Jesper Steen Moller 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: + * Jesper Steen Moller - initial API and implementation, adapted from + * Stefan Mandels contribution in bug 341232, and existing debug tests + *******************************************************************************/ +package org.eclipse.jdt.debug.tests.breakpoints; + +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.debug.core.IJavaLineBreakpoint; +import org.eclipse.jdt.debug.core.IJavaThread; +import org.eclipse.jdt.debug.tests.AbstractDebugTest; + +/** + * Tests conditional breakpoints. + */ +public class ConditionalBreakpoints15Tests extends AbstractDebugTest { + + /** + * Constructor + * @param name + */ + public ConditionalBreakpoints15Tests(String name) { + super(name); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.debug.tests.AbstractDebugTest#getProjectContext() + */ + @Override + protected IJavaProject getProjectContext() { + return get15Project(); + } + + /** + * Tests a breakpoint with a simple condition + * @throws Exception + */ + public void testSimpleConditionalBreakpointOnParameterizedType() throws Exception { + String typeName = "a.b.c.ConditionalsNearGenerics"; + String innerTypeName = "a.b.c.ConditionalsNearGenerics.ItemIterator"; + IJavaLineBreakpoint bp1 = createConditionalLineBreakpoint(33, typeName, "false", true); + IJavaLineBreakpoint bp2 = createConditionalLineBreakpoint(39, typeName, "false", true); + IJavaLineBreakpoint bp3 = createConditionalLineBreakpoint(52, innerTypeName, "false", true); + IJavaLineBreakpoint bp4 = createConditionalLineBreakpoint(53, innerTypeName, "true", true); + + IJavaThread thread= null; + try { + thread= launchToLineBreakpoint(typeName, bp4); // If compiled correctly, this will jump over bp1-bp3 !! + + bp1.delete(); + bp2.delete(); + bp3.delete(); + bp4.delete(); + } finally { + terminateAndRemove(thread); + removeAllBreakpoints(); + } + } + + } diff --git a/org.eclipse.jdt.debug.tests/testsource-j2se-1.5/a/b/c/ConditionalsNearGenerics.java b/org.eclipse.jdt.debug.tests/testsource-j2se-1.5/a/b/c/ConditionalsNearGenerics.java new file mode 100644 index 0000000..93565a0 --- a/dev/null +++ b/org.eclipse.jdt.debug.tests/testsource-j2se-1.5/a/b/c/ConditionalsNearGenerics.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2012 Jesper Steen Moller 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: + * Jesper Steen Moller - initial API and implementation, adapted from + * Stefan Mandels contribution in bug 341232 + *******************************************************************************/ +package a.b.c; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +public class ConditionalsNearGenerics { + + private String name; + + public ConditionalsNearGenerics() { + // set a conditional breakpoint in next line: use true as expression + this.name = "bug"; + } + + public static void main(String[] args) throws Exception { + new ConditionalsNearGenerics().bug(); + } + + public void bug() throws Exception { + char[] chars = name.toCharArray(); + System.out.println(chars); + tokenize(Arrays.asList(1,2,3), name); + } + + //FIXME delete following method, then the breakpoint shall work + public <T extends Number> Iterator<T> tokenize(List<T> list, String input) { + new ItemIterator<Item>(input); + return list.iterator(); + } + + public interface Item { + + } + + private class ItemIterator<T extends Item> implements Iterator<T> { + + private String input; + + public ItemIterator(String input) { + this.input = input; + System.out.println("From ItemIterator!"); + } + + @Override + public boolean hasNext() { + return false; + } + + @Override + public T next() { + return null; + } + + @Override + public void remove() { + } + + } +}
\ No newline at end of file diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java index 165fb7a..f35e2da 100644 --- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java +++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Jesper Steen Moller - bug 341232 *******************************************************************************/ package org.eclipse.jdt.internal.debug.eval.ast.engine; @@ -336,7 +337,7 @@ public class ASTEvaluationEngine implements IAstEvaluationEngine { // } unit = parseCompilationUnit( - mapper.getSource(receivingType, javaProject, + mapper.getSource(receivingType, frame.getLineNumber(), javaProject, frame.isStatic()).toCharArray(), mapper.getCompilationUnitName(), javaProject); } catch (CoreException e) { @@ -428,7 +429,7 @@ public class ASTEvaluationEngine implements IAstEvaluationEngine { if (javaTypes.length > 0) { IJavaReferenceType recType = (IJavaReferenceType) javaTypes[0]; unit = parseCompilationUnit( - mapper.getSource(recType, getJavaProject(), false) + mapper.getSource(recType, -1, getJavaProject(), false) .toCharArray(), mapper.getCompilationUnitName(), javaProject); } else { @@ -493,7 +494,7 @@ public class ASTEvaluationEngine implements IAstEvaluationEngine { try { unit = parseCompilationUnit( - mapper.getSource(type, javaProject, false).toCharArray(), + mapper.getSource(type, -1, javaProject, false).toCharArray(), mapper.getCompilationUnitName(), javaProject); } catch (CoreException e) { InstructionSequence expression = new InstructionSequence(snippet); diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationSourceGenerator.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationSourceGenerator.java index f21a3b9..d752a0f 100644 --- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationSourceGenerator.java +++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/EvaluationSourceGenerator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 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 @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Jesper Steen Moller - bug 341232 *******************************************************************************/ package org.eclipse.jdt.internal.debug.eval.ast.engine; @@ -137,7 +138,7 @@ public class EvaluationSourceGenerator { } private void createEvaluationSourceFromSource(String source, IType type, - boolean createInAStaticMethod, IJavaProject project) + int line, boolean createInAStaticMethod, IJavaProject project) throws DebugException { ASTParser parser = ASTParser.newParser(AST.JLS4); parser.setSource(source.toCharArray()); @@ -146,7 +147,7 @@ public class EvaluationSourceGenerator { parser.setCompilerOptions(options); CompilationUnit unit = (CompilationUnit) parser.createAST(null); SourceBasedSourceGenerator visitor = new SourceBasedSourceGenerator( - type, createInAStaticMethod, fLocalVariableTypeNames, + type, line, createInAStaticMethod, fLocalVariableTypeNames, fLocalVariableNames, fCodeSnippet, sourceLevel); unit.accept(visitor); @@ -217,7 +218,7 @@ public class EvaluationSourceGenerator { return objectToEvaluationSourceMapper; } - public String getSource(IJavaReferenceType type, IJavaProject javaProject, + public String getSource(IJavaReferenceType type, int line, IJavaProject javaProject, boolean isStatic) throws CoreException { if (fSource == null) { IType iType = JavaDebugUtils.resolveType(type); @@ -230,7 +231,7 @@ public class EvaluationSourceGenerator { } if (baseSource != null) { createEvaluationSourceFromSource(baseSource, iType, - isStatic, javaProject); + line, isStatic, javaProject); } } if (fSource == null) { diff --git a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/SourceBasedSourceGenerator.java b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/SourceBasedSourceGenerator.java index dbbd7d9..837bac0 100644 --- a/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/SourceBasedSourceGenerator.java +++ b/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/SourceBasedSourceGenerator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 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 @@ -7,13 +7,17 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Jesper Steen Moller - bug 341232 *******************************************************************************/ package org.eclipse.jdt.internal.debug.eval.ast.engine; -import java.util.HashSet; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.Set; +import java.util.Map; +import java.util.Stack; import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.IType; @@ -131,6 +135,7 @@ public class SourceBasedSourceGenerator extends ASTVisitor { private String fError; private IType fType; + private int fLine; private StringBuffer fSource; @@ -149,7 +154,12 @@ public class SourceBasedSourceGenerator extends ASTVisitor { private int fSourceMajorLevel; private int fSourceMinorLevel; - private Set<String> fTypeParameters = new HashSet<String>(); + private Stack<Map<String, String>> fTypeParameterStack = new Stack<Map<String, String>>(); + private Map<String, String> fMatchingTypeParameters = null; + private CompilationUnit fCompilationUnit; + { + fTypeParameterStack.push(Collections.<String,String>emptyMap()); + } /** * if the <code>createInAnInstanceMethod</code> flag is set, the method @@ -158,6 +168,8 @@ public class SourceBasedSourceGenerator extends ASTVisitor { * * @param type * the root {@link IType} + * @param sourcePosition + * the reference position in the type's source * @param createInAStaticMethod * if the source should be generated * @param localTypesNames @@ -170,10 +182,11 @@ public class SourceBasedSourceGenerator extends ASTVisitor { * the desired source level */ public SourceBasedSourceGenerator(IType type, - boolean createInAStaticMethod, String[] localTypesNames, + int line, boolean createInAStaticMethod, String[] localTypesNames, String[] localVariables, String codeSnippet, String sourceLevel) { fRightTypeFound = false; fType = type; + fLine = line; fLocalVariableTypeNames = localTypesNames; fLocalVariableNames = localVariables; fCodeSnippet = codeSnippet; @@ -243,8 +256,9 @@ public class SourceBasedSourceGenerator extends ASTVisitor { // add type parameters as required if (isSourceLevelGreaterOrEqual(1, 5)) { - if (!fTypeParameters.isEmpty()) { - Iterator<String> iterator = fTypeParameters.iterator(); + Collection<String> activeTypeParameters = (fMatchingTypeParameters != null ? fMatchingTypeParameters : fTypeParameterStack.peek()).values(); + if (!activeTypeParameters.isEmpty()) { + Iterator<String> iterator = activeTypeParameters.iterator(); buffer.append(Signature.C_GENERIC_START); while (iterator.hasNext()) { String name = iterator.next(); @@ -740,7 +754,7 @@ public class SourceBasedSourceGenerator extends ASTVisitor { if (type.isSimpleType()) { String name = getQualifiedIdentifier(((SimpleType) type).getName()); if (!isSourceLevelGreaterOrEqual(1, 5) - && fTypeParameters.contains(name)) { + && fTypeParameterStack.peek().containsKey(name)) { return "Object"; //$NON-NLS-1$ } return name; @@ -1008,6 +1022,13 @@ public class SourceBasedSourceGenerator extends ASTVisitor { } } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.dom.ASTVisitor#endVisit(org.eclipse.jdt.core.dom.MethodDeclaration) + */ + public void endVisit(MethodDeclaration node) { + fTypeParameterStack.pop(); + } + /** * @see ASTVisitor#endVisit(TypeDeclaration) */ @@ -1015,6 +1036,7 @@ public class SourceBasedSourceGenerator extends ASTVisitor { public void endVisit(TypeDeclaration node) { if (hasError()) { + fTypeParameterStack.pop(); return; } @@ -1027,6 +1049,7 @@ public class SourceBasedSourceGenerator extends ASTVisitor { if (!fEvaluateNextEndTypeDeclaration) { fEvaluateNextEndTypeDeclaration = true; + fTypeParameterStack.pop(); return; } @@ -1060,6 +1083,7 @@ public class SourceBasedSourceGenerator extends ASTVisitor { fLastTypeName = node.getName().getIdentifier(); } } + fTypeParameterStack.pop(); } /* @@ -1254,6 +1278,7 @@ public class SourceBasedSourceGenerator extends ASTVisitor { */ @Override public boolean visit(CompilationUnit node) { + fCompilationUnit = node; if (rightTypeFound()) { return false; } @@ -1532,18 +1557,35 @@ public class SourceBasedSourceGenerator extends ASTVisitor { */ @Override public boolean visit(MethodDeclaration node) { + String name = node.getName().toString(); + System.out.println(name); + int firstLine = fCompilationUnit.getLineNumber(node.getStartPosition()); + int lastLine = fCompilationUnit.getLineNumber(node.getStartPosition() + node.getLength()); + List<TypeParameter> typeParameters = node.typeParameters(); + pushTypeParameters(typeParameters); + if (isRightType(node.getParent()) && firstLine <= fLine && fLine <= lastLine) { + fMatchingTypeParameters = fTypeParameterStack.peek(); + } + if (rightTypeFound()) { + return false; + } + return true; + } + + private void pushTypeParameters(List<TypeParameter> typeParameters) { if (!typeParameters.isEmpty()) { + HashMap<String,String> newTypeParameters = new HashMap<String,String>(fTypeParameterStack.peek()); Iterator<TypeParameter> iterator = typeParameters.iterator(); while (iterator.hasNext()) { TypeParameter typeParameter = iterator.next(); - fTypeParameters.add(typeParameter.toString()); + String boundName = typeParameter.getName().getIdentifier(); + newTypeParameters.put(boundName, typeParameter.toString()); } + fTypeParameterStack.push(newTypeParameters); // Push the new "scope" + } else { + fTypeParameterStack.push(fTypeParameterStack.peek()); // Push the same } - if (rightTypeFound()) { - return false; - } - return true; } /** @@ -1925,13 +1967,7 @@ public class SourceBasedSourceGenerator extends ASTVisitor { @Override public boolean visit(TypeDeclaration node) { List<TypeParameter> typeParameters = node.typeParameters(); - if (!typeParameters.isEmpty()) { - Iterator<TypeParameter> iterator = typeParameters.iterator(); - while (iterator.hasNext()) { - TypeParameter typeParameter = iterator.next(); - fTypeParameters.add(typeParameter.getName().getIdentifier()); - } - } + pushTypeParameters(typeParameters); if (rightTypeFound()) { fEvaluateNextEndTypeDeclaration = false; return false; |

