diff -Nru eclipse-jdt-debug-4.23/debian/changelog eclipse-jdt-debug-4.26/debian/changelog --- eclipse-jdt-debug-4.23/debian/changelog 2022-12-12 07:49:09.000000000 +0000 +++ eclipse-jdt-debug-4.26/debian/changelog 2023-01-05 11:08:59.000000000 +0000 @@ -1,3 +1,10 @@ +eclipse-jdt-debug (4.26-1) unstable; urgency=medium + + * New upstream release + - Depend on libeclipse-jdt-core-java (>= 3.32) + + -- Emmanuel Bourg Thu, 05 Jan 2023 12:08:59 +0100 + eclipse-jdt-debug (4.23-1) unstable; urgency=medium * New upstream release diff -Nru eclipse-jdt-debug-4.23/debian/control eclipse-jdt-debug-4.26/debian/control --- eclipse-jdt-debug-4.23/debian/control 2022-12-08 21:12:13.000000000 +0000 +++ eclipse-jdt-debug-4.26/debian/control 2023-01-04 23:04:46.000000000 +0000 @@ -17,7 +17,7 @@ libeclipse-core-variables-java, libeclipse-debug-core-java (>= 3.14), libeclipse-debug-ui-java (>= 3.13.100), - libeclipse-jdt-core-java (>= 3.28), + libeclipse-jdt-core-java (>= 3.32), libeclipse-jdt-core-manipulation-java, libeclipse-jdt-ui-java (>= 3.26), libeclipse-jface-java, @@ -113,7 +113,7 @@ libeclipse-core-runtime-java, libeclipse-core-variables-java, libeclipse-debug-core-java (>= 3.14), - libeclipse-jdt-core-java (>= 3.28), + libeclipse-jdt-core-java (>= 3.32), libequinox-common-java, libequinox-preferences-java, libequinox-registry-java, diff -Nru eclipse-jdt-debug-4.23/.github/workflows/rebase.yml eclipse-jdt-debug-4.26/.github/workflows/rebase.yml --- eclipse-jdt-debug-4.23/.github/workflows/rebase.yml 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/.github/workflows/rebase.yml 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,19 @@ +name: Automatic Rebase +on: + issue_comment: + types: [created] +jobs: + rebase: + name: Rebase + if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase') + runs-on: ubuntu-latest + steps: + - name: Checkout the latest code + uses: actions/checkout@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 # otherwise, you will fail to push refs to dest repo + - name: Automatic Rebase + uses: cirrus-actions/rebase@1.7 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff -Nru eclipse-jdt-debug-4.23/.github/workflows/verifyFreezePeriod.yml eclipse-jdt-debug-4.26/.github/workflows/verifyFreezePeriod.yml --- eclipse-jdt-debug-4.23/.github/workflows/verifyFreezePeriod.yml 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/.github/workflows/verifyFreezePeriod.yml 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,12 @@ +# This workflow calls the Code-Freeze-Period check + +name: Check Code Freeze Period + +on: + pull_request: + branches: + - 'master' + +jobs: + check-freeze-period: + uses: eclipse-platform/eclipse.platform.releng.aggregator/.github/workflows/verifyFreezePeriod.yml@master diff -Nru eclipse-jdt-debug-4.23/Jenkinsfile eclipse-jdt-debug-4.26/Jenkinsfile --- eclipse-jdt-debug-4.23/Jenkinsfile 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/Jenkinsfile 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,38 @@ +pipeline { + options { + timeout(time: 40, unit: 'MINUTES') + buildDiscarder(logRotator(numToKeepStr:'15')) + disableConcurrentBuilds(abortPrevious: true) + timestamps() + } + agent { + label "centos-latest" + } + tools { + maven 'apache-maven-latest' + jdk 'openjdk-jdk17-latest' + } + stages { + stage('Build') { + steps { + wrap([$class: 'Xvnc', useXauthority: true]) { + sh """ + mvn clean verify --batch-mode --fail-at-end -Dmaven.repo.local=$WORKSPACE/.m2/repository \ + -Pbuild-individual-bundles -Ptest-on-javase-19 -Pbree-libs -Papi-check\ + -Dcompare-version-with-baselines.skip=true \ + -Dproject.build.sourceEncoding=UTF-8 \ + -DtrimStackTrace=false + """ + } + } + post { + always { + archiveArtifacts artifacts: '*.log,*/target/work/data/.metadata/*.log,*/tests/target/work/data/.metadata/*.log,apiAnalyzer-workspace/.metadata/*.log', allowEmptyArchive: true + recordIssues aggregatingResults: true, enabledForFailure: true, qualityGates: [[threshold: 1, type: 'DELTA', unstable: false]], tools: [acuCobol()] + publishIssues issues:[scanForIssues(tool: java()), scanForIssues(tool: mavenConsole())] + junit '**/target/surefire-reports/*.xml' + } + } + } + } +} diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/eval/org/eclipse/jdt/internal/debug/eval/ast/engine/ASTEvaluationEngine.java 2022-11-07 18:51:46.000000000 +0000 @@ -486,7 +486,7 @@ private CompilationUnit parseCompilationUnit(char[] source, String unitName, IJavaProject project, Map extraCompileOptions) { - ASTParser parser = ASTParser.newParser(AST.JLS15); + ASTParser parser = ASTParser.newParser(AST.getJLSLatest()); parser.setSource(source); parser.setUnitName(unitName); parser.setProject(project); @@ -685,7 +685,7 @@ || problemId == IProblem.NotVisibleMethod || problemId == IProblem.NotVisibleConstructor || problemId == IProblem.NotVisibleField - || problemId == IProblem.NotVisibleType + || problemId == IProblem.NotVisibleType || problemId == IProblem.UnexpectedStaticModifierForMethod) { continue; } diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -11,6 +11,7 @@ * Contributors: * IBM - Initial API and implementation * Google Inc - add support for accepting multiple connections + * Microsoft Corporation - supports virtual threads *******************************************************************************/ package org.eclipse.jdi.internal.connect; @@ -48,6 +49,8 @@ public static String SocketLaunchingConnectorImpl_Connection_argument_is_not_of_the_right_type_14; public static String SocketLaunchingConnectorImpl_Necessary_connection_argument_is_null_15; public static String SocketLaunchingConnectorImpl_Connection_argument_is_not_a_number_16; + public static String SocketLaunchingConnectorImpl_Include_virtual_threads_17; + public static String SocketLaunchingConnectorImpl_IncludeVirtualThreads_18; public static String SocketListeningConnectorImpl_Port_number_at_which_to_listen_for_VM_connections_1; public static String SocketListeningConnectorImpl_Port_2; public static String SocketListeningConnectorImpl_Timeout_before_accept_returns_3; diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.properties eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.properties --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.properties 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/ConnectMessages.properties 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2000, 2018 IBM Corporation and others. +# Copyright (c) 2000, 2022 IBM Corporation and others. # # This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 @@ -11,6 +11,7 @@ # Contributors: # IBM Corporation - initial API and implementation # Google Inc - add support for accepting multiple connections +# Microsoft Corporation - supports virtual threads ############################################################################### PacketReceiveManager_Got_IOException_from_Virtual_Machine_1=Got IOException from Virtual Machine @@ -47,6 +48,8 @@ SocketLaunchingConnectorImpl_Connection_argument_is_not_of_the_right_type_14=Connection argument is not of the right type SocketLaunchingConnectorImpl_Necessary_connection_argument_is_null_15=Necessary connection argument is null SocketLaunchingConnectorImpl_Connection_argument_is_not_a_number_16=Connection argument is not a number +SocketLaunchingConnectorImpl_Include_virtual_threads_17=List of all threads includes virtual threads as well as platform threads. Virtual threads are a preview feature of the Java platform. +SocketLaunchingConnectorImpl_IncludeVirtualThreads_18=Include Virtual Threads: SocketListeningConnectorImpl_Port_number_at_which_to_listen_for_VM_connections_1=Port number at which to listen for VM connections #For translation of separator ":" it should be consistent to the translated value of SocketConnectionLabelSeparator SocketListeningConnectorImpl_Port_2=Po&rt: diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketLaunchingConnectorImpl.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketLaunchingConnectorImpl.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketLaunchingConnectorImpl.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/connect/SocketLaunchingConnectorImpl.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2015 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -12,6 +12,7 @@ * IBM Corporation - initial API and implementation * Ivan Popov - Bug 184211: JDI connectors throw NullPointerException if used separately * from Eclipse + * Microsoft Corporation - supports virtual threads *******************************************************************************/ package org.eclipse.jdi.internal.connect; @@ -54,6 +55,12 @@ private boolean fSuspend; /** Name of the Java VM launcher. */ private String fLauncher; + /** + * List of all threads includes virtual threads as well as platform threads. + * Virtual threads are a preview feature of the Java platform. + * @since 3.20 + */ + private boolean fIncludeVirtualThreads; /** * Creates new SocketAttachingConnectorImpl. @@ -108,6 +115,12 @@ strArg.setValue("java"); //$NON-NLS-1$ arguments.put(strArg.name(), strArg); + // Include Virtual Threads + BooleanArgumentImpl vthreadsArg = new BooleanArgumentImpl( + "includevirtualthreads", ConnectMessages.SocketLaunchingConnectorImpl_Include_virtual_threads_17, ConnectMessages.SocketLaunchingConnectorImpl_IncludeVirtualThreads_18, false); //$NON-NLS-1$ + vthreadsArg.setValue(false); + arguments.put(vthreadsArg.name(), vthreadsArg); + return arguments; } @@ -152,6 +165,9 @@ attribute = "vmexec"; //$NON-NLS-1$ fLauncher = ((Connector.StringArgument) connectionArgs .get(attribute)).value(); + attribute = "includevirtualthreads"; //$NON-NLS-1$ + fIncludeVirtualThreads = ((Connector.BooleanArgument) connectionArgs + .get(attribute)).booleanValue(); } catch (ClassCastException e) { throw new IllegalConnectorArgumentsException( ConnectMessages.SocketLaunchingConnectorImpl_Connection_argument_is_not_of_the_right_type_14, @@ -190,6 +206,9 @@ // Add Debug options. execString += " -Xdebug -Xnoagent -Djava.compiler=NONE"; //$NON-NLS-1$ execString += " -Xrunjdwp:transport=dt_socket,address=" + address + ",server=n,suspend=" + (fSuspend ? "y" : "n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + if (fIncludeVirtualThreads) { // The default value is 'n', add it only when explicitly enabled. + execString += ",includevirtualthreads=y"; //$NON-NLS-1$ + } // Add User specified options. if (fOptions != null) { diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/jdwp/JdwpCommandPacket.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/jdwp/JdwpCommandPacket.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/jdwp/JdwpCommandPacket.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/jdwp/JdwpCommandPacket.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2015 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -11,6 +11,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Jesper Steen Møller - Bug 430839 + * Microsoft Corporation - supports virtual threads *******************************************************************************/ package org.eclipse.jdi.internal.jdwp; @@ -137,6 +138,13 @@ public static final int TR_SUSPEND_COUNT = 12 + (CSET_THREAD_REFERENCE << 8); public static final int TR_OWNED_MONITOR_STACK_DEPTH = 13 + (CSET_THREAD_REFERENCE << 8); public static final int TR_FORCE_EARLY_RETURN = 14 + (CSET_THREAD_REFERENCE << 8); + /** + * IsVirtual is a preview API of the Java platform. Preview features may be removed in a future release, or upgraded to permanent features of the + * Java platform. Since JDWP version 19. + * + * @since 3.20 + */ + public static final int TR_IS_VIRTUAL = 15 + (CSET_THREAD_REFERENCE << 8); /** Commands ThreadGroupReference. */ public static final int TGR_NAME = 1 + (CSET_THREAD_GROUP_REFERENCE << 8); diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/EventRequestImpl.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/EventRequestImpl.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/EventRequestImpl.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/EventRequestImpl.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2015 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,6 +10,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Microsoft Corporation - supports virtual threads *******************************************************************************/ package org.eclipse.jdi.internal.request; @@ -78,6 +79,14 @@ public static final byte MODIF_KIND_STEP = 10; public static final byte MODIF_KIND_INSTANCE = 11; public static final byte MODIF_KIND_SOURCE_NAME_FILTER = 12; + /** + * PlatformThreadsOnly is a preview API of the Java platform. Preview features may be removed in a future release, or upgraded to permanent + * features of the Java platform. Since JDWP version 19. For thread start and thread end events, restrict the events so they are only sent for + * platform threads. + * + * @since 3.20 + */ + public static final byte MODIF_KIND_PLATFORMTHREADSONLY = 13; /** Mapping of command codes to strings. */ private static HashMap fStepSizeMap = null; @@ -146,6 +155,13 @@ protected ArrayList fSourceNameFilters = null; /** + * Platform threads filter + * + * @since 3.20 + */ + protected boolean fPlatformThreadsFilter = false; + + /** * Creates new EventRequest. */ protected EventRequestImpl(String description, VirtualMachineImpl vmImpl) { @@ -179,13 +195,15 @@ */ @Override public void putProperty(Object key, Object value) { - if (fPropertyMap == null) + if (fPropertyMap == null) { fPropertyMap = new HashMap<>(); + } - if (value == null) + if (value == null) { fPropertyMap.remove(key); - else + } else { fPropertyMap.put(key, value); + } } /** @@ -209,8 +227,9 @@ */ @Override public synchronized void disable() { - if (!isEnabled()) + if (!isEnabled()) { return; + } initJdwpRequest(); try { @@ -243,8 +262,9 @@ */ @Override public synchronized void enable() { - if (isEnabled()) + if (isEnabled()) { return; + } initJdwpRequest(); try { @@ -298,10 +318,11 @@ */ @Override public void setEnabled(boolean enable) { - if (enable) + if (enable) { enable(); - else + } else { disable(); + } } /** @@ -309,8 +330,9 @@ * is thrown if this request is enabled. */ public void checkDisabled() throws InvalidRequestStateException { - if (isEnabled()) + if (isEnabled()) { throw new InvalidRequestStateException(); + } } /** @@ -346,8 +368,9 @@ @Override public void addCountFilter(int count) throws InvalidRequestStateException { checkDisabled(); - if (fCountFilters == null) + if (fCountFilters == null) { fCountFilters = new ArrayList<>(); + } fCountFilters.add(Integer.valueOf(count)); } @@ -360,10 +383,12 @@ InvalidRequestStateException { checkVM(threadFilter); checkDisabled(); - if (threadFilter.isCollected()) + if (threadFilter.isCollected()) { throw new ObjectCollectedException(); - if (fThreadFilters == null) + } + if (fThreadFilters == null) { fThreadFilters = new ArrayList<>(); + } fThreadFilters.add(threadFilter); } @@ -376,8 +401,9 @@ throws VMMismatchException, InvalidRequestStateException { checkVM(filter); checkDisabled(); - if (fClassFilterRefs == null) + if (fClassFilterRefs == null) { fClassFilterRefs = new ArrayList<>(); + } fClassFilterRefs.add(filter); } @@ -389,8 +415,9 @@ public void addClassFilter(String filter) throws InvalidRequestStateException { checkDisabled(); - if (fClassFilters == null) + if (fClassFilters == null) { fClassFilters = new ArrayList<>(); + } fClassFilters.add(filter); } @@ -403,8 +430,9 @@ public void addClassExclusionFilter(String filter) throws InvalidRequestStateException { checkDisabled(); - if (fClassExclusionFilters == null) + if (fClassExclusionFilters == null) { fClassExclusionFilters = new ArrayList<>(); + } fClassExclusionFilters.add(filter); } @@ -418,8 +446,9 @@ checkDisabled(); // Used in createBreakpointRequest. checkVM(location); - if (fLocationFilters == null) + if (fLocationFilters == null) { fLocationFilters = new ArrayList<>(); + } fLocationFilters.add(location); } @@ -433,11 +462,13 @@ throws VMMismatchException { checkDisabled(); // refType Null means report exceptions of all types. - if (refType != null) + if (refType != null) { checkVM(refType); + } - if (fExceptionFilters == null) + if (fExceptionFilters == null) { fExceptionFilters = new ArrayList<>(); + } ExceptionFilter filter = new ExceptionFilter(); filter.fException = refType; @@ -453,8 +484,9 @@ checkDisabled(); // Used in createXWatchpointRequest methods. checkVM(field); - if (fFieldFilters == null) + if (fFieldFilters == null) { fFieldFilters = new ArrayList<>(); + } fFieldFilters.add(field); } @@ -469,8 +501,9 @@ // Used in createStepRequest. checkVM(thread); - if (fThreadStepFilters == null) + if (fThreadStepFilters == null) { fThreadStepFilters = new ArrayList<>(); + } ThreadStepFilter filter = new ThreadStepFilter(); filter.fThread = thread; @@ -577,31 +610,44 @@ protected int modifierCount() { int count = 0; - if (fCountFilters != null) + if (fCountFilters != null) { count += fCountFilters.size(); - if (fThreadFilters != null) + } + if (fThreadFilters != null) { count += fThreadFilters.size(); - if (fClassFilterRefs != null) + } + if (fClassFilterRefs != null) { count += fClassFilterRefs.size(); - if (fClassFilters != null) + } + if (fClassFilters != null) { count += fClassFilters.size(); - if (fClassExclusionFilters != null) + } + if (fClassExclusionFilters != null) { count += fClassExclusionFilters.size(); - if (fLocationFilters != null) + } + if (fLocationFilters != null) { count += fLocationFilters.size(); - if (fExceptionFilters != null) + } + if (fExceptionFilters != null) { count += fExceptionFilters.size(); - if (fFieldFilters != null) + } + if (fFieldFilters != null) { count += fFieldFilters.size(); - if (fThreadStepFilters != null) + } + if (fThreadStepFilters != null) { count += fThreadStepFilters.size(); - if (fInstanceFilters != null) + } + if (fInstanceFilters != null) { count += fInstanceFilters.size(); + } if (fSourceNameFilters != null) { if (supportsSourceNameFilters()) { count += fSourceNameFilters.size(); } } + if (fPlatformThreadsFilter && supportsPlatformThreadsFilter()) { + count++; + } return count; } @@ -635,10 +681,11 @@ for (ExceptionFilter filter : fExceptionFilters) { writeByte(MODIF_KIND_EXCEPTIONONLY, "modifier", modifierKindMap(), outData); //$NON-NLS-1$ - if (filter.fException != null) + if (filter.fException != null) { filter.fException.write(this, outData); - else + } else { ReferenceTypeImpl.writeNull(this, outData); + } writeBoolean(filter.fNotifyCaught, "notify caught", outData); //$NON-NLS-1$ writeBoolean(filter.fNotifyUncaught, "notify uncaught", outData); //$NON-NLS-1$ @@ -709,6 +756,18 @@ } } } + if (fPlatformThreadsFilter && supportsPlatformThreadsFilter()) { + writeByte(MODIF_KIND_PLATFORMTHREADSONLY, "modifier", modifierKindMap(), outData); //$NON-NLS-1$ + } + } + + /** + * Returns whether JDWP supports platform threads filter (a 19 preview feature). + * + * @return whether JDWP supports platform threads filter + */ + private boolean supportsPlatformThreadsFilter() { + return ((VirtualMachineImpl) virtualMachine()).mayCreateVirtualThreads(); } /** @@ -725,8 +784,9 @@ * Retrieves constant mappings. */ public static void getConstantMaps() { - if (fStepSizeMap != null) + if (fStepSizeMap != null) { return; + } fStepSizeMap = new HashMap<>(); fStepDepthMap = new HashMap<>(); @@ -735,8 +795,9 @@ for (Field field : EventRequestImpl.class.getDeclaredFields()) { if ((field.getModifiers() & java.lang.reflect.Modifier.PUBLIC) == 0 || (field.getModifiers() & java.lang.reflect.Modifier.STATIC) == 0 - || (field.getModifiers() & java.lang.reflect.Modifier.FINAL) == 0) + || (field.getModifiers() & java.lang.reflect.Modifier.FINAL) == 0) { continue; + } try { String name = field.getName(); diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/ThreadDeathRequestImpl.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/ThreadDeathRequestImpl.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/ThreadDeathRequestImpl.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/ThreadDeathRequestImpl.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,6 +10,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Microsoft Corporation - supports virtual threads *******************************************************************************/ package org.eclipse.jdi.internal.request; @@ -23,7 +24,7 @@ * specification. See the com.sun.jdi package for more information. * */ -public class ThreadDeathRequestImpl extends EventRequestImpl implements +public class ThreadDeathRequestImpl extends ThreadLifecycleRequestImpl implements ThreadDeathRequest { /** * Creates new ThreadDeathRequest. diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/ThreadLifecycleRequestImpl.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/ThreadLifecycleRequestImpl.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/ThreadLifecycleRequestImpl.java 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/ThreadLifecycleRequestImpl.java 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2022 Microsoft Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Microsoft Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdi.internal.request; + +import org.eclipse.jdi.internal.VirtualMachineImpl; + +public abstract class ThreadLifecycleRequestImpl extends EventRequestImpl { + + protected ThreadLifecycleRequestImpl(String description, VirtualMachineImpl vmImpl) { + super(description, vmImpl); + } + + /** + * For thread start and thread end events, restrict the events so they are only sent for platform threads. + * + * @since 3.20 + */ + public void addPlatformThreadsOnlyFilter() { + checkDisabled(); + fPlatformThreadsFilter = true; + } +} diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/ThreadStartRequestImpl.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/ThreadStartRequestImpl.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/ThreadStartRequestImpl.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/request/ThreadStartRequestImpl.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,6 +10,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Microsoft Corporation - supports virtual threads *******************************************************************************/ package org.eclipse.jdi.internal.request; @@ -23,7 +24,7 @@ * specification. See the com.sun.jdi package for more information. * */ -public class ThreadStartRequestImpl extends EventRequestImpl implements +public class ThreadStartRequestImpl extends ThreadLifecycleRequestImpl implements ThreadStartRequest { /** * Creates new ThreadStartRequest. diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ThreadReferenceImpl.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ThreadReferenceImpl.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ThreadReferenceImpl.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/ThreadReferenceImpl.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2015 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,6 +10,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Microsoft Corporation - supports virtual threads *******************************************************************************/ package org.eclipse.jdi.internal; @@ -24,6 +25,7 @@ import java.util.List; import java.util.Map; +import org.eclipse.jdi.OpaqueFrameException; import org.eclipse.jdi.internal.jdwp.JdwpCommandPacket; import org.eclipse.jdi.internal.jdwp.JdwpID; import org.eclipse.jdi.internal.jdwp.JdwpReplyPacket; @@ -78,6 +80,10 @@ */ private ThreadGroupReferenceImpl fThreadGroup = null; + // Whether a thread is a virtual thread or not is cached + private volatile boolean isVirtual; + private volatile boolean isVirtualCached; + /** * Creates new ThreadReferenceImpl. */ @@ -182,8 +188,10 @@ throw new UnsupportedOperationException( JDIMessages.ThreadReferenceImpl_no_force_early_return_on_threads); case JdwpReplyPacket.OPAQUE_FRAME: - throw new NativeMethodException( - JDIMessages.ThreadReferenceImpl_thread_cannot_force_native_method); + if (isVirtual()) { + throw new OpaqueFrameException(); + } + throw new NativeMethodException(JDIMessages.ThreadReferenceImpl_thread_cannot_force_native_method); case JdwpReplyPacket.NO_MORE_FRAMES: throw new InvalidStackFrameException( JDIMessages.ThreadReferenceImpl_thread_no_stackframes); @@ -349,6 +357,43 @@ } } + /** + * isVirtual is a preview API of the Java platform. Programs can only use isVirtual when preview features are enabled. Preview features may be + * removed in a future release, or upgraded to permanent features of the Java platform. + * + * @return true if the thread is a virtual thread + * @since 3.20 + */ + public boolean isVirtual() { + if (isVirtualCached) { + return isVirtual; + } + boolean result = false; + boolean supportsVirtualThreads = virtualMachineImpl().mayCreateVirtualThreads(); + if (supportsVirtualThreads) { + initJdwpRequest(); + try { + JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.TR_IS_VIRTUAL, this); + switch (replyPacket.errorCode()) { + case JdwpReplyPacket.INVALID_THREAD: + throw new ObjectCollectedException(); + } + defaultReplyErrorHandler(replyPacket.errorCode()); + DataInputStream replyData = replyPacket.dataInStream(); + result = readBoolean("isVirtual", replyData); //$NON-NLS-1$ + } catch (IOException e) { + defaultIOExceptionHandler(e); + return false; + } finally { + handledJdwpRequest(); + } + } + + isVirtual = result; + isVirtualCached = true; + return result; + } + /* (non-Javadoc) * @see com.sun.jdi.ThreadReference#name() */ @@ -715,10 +760,13 @@ JdwpThreadID ID = new JdwpThreadID(vmImpl); ID.read(in); if (target.fVerboseWriter != null) + { target.fVerboseWriter.println("threadReference", ID.value()); //$NON-NLS-1$ + } - if (ID.isNull()) + if (ID.isNull()) { return null; + } ThreadReferenceImpl mirror = (ThreadReferenceImpl) vmImpl .getCachedMirror(ID); @@ -744,8 +792,9 @@ for (Field field : fields) { if ((field.getModifiers() & Modifier.PUBLIC) == 0 || (field.getModifiers() & Modifier.STATIC) == 0 - || (field.getModifiers() & Modifier.FINAL) == 0) + || (field.getModifiers() & Modifier.FINAL) == 0) { continue; + } try { String name = field.getName(); @@ -814,6 +863,11 @@ JdwpReplyPacket replyPacket = requestVM( JdwpCommandPacket.SF_POP_FRAME, outBytes); switch (replyPacket.errorCode()) { + case JdwpReplyPacket.OPAQUE_FRAME: + if (isVirtual()) { + throw new OpaqueFrameException(); + } + throw new NativeMethodException(); case JdwpReplyPacket.INVALID_THREAD: throw new InvalidStackFrameException(); case JdwpReplyPacket.INVALID_FRAMEID: diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VirtualMachineImpl.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VirtualMachineImpl.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VirtualMachineImpl.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/internal/VirtualMachineImpl.java 2022-11-07 18:51:46.000000000 +0000 @@ -276,8 +276,9 @@ */ public final void removeKnownRefType(String signature) { List refTypeList = classesBySignature(signature); - if (refTypeList.isEmpty()) + if (refTypeList.isEmpty()) { return; + } // If we have only one known class for this signature, we known that // this is the class @@ -313,9 +314,10 @@ * HCR. */ public void checkHCRSupported() throws UnsupportedOperationException { - if (!isHCRSupported()) + if (!isHCRSupported()) { throw new UnsupportedOperationException( NLS.bind(JDIMessages.VirtualMachineImpl_Target_VM__0__does_not_support_Hot_Code_Replacement_1, new String[] { name() })); + } } /* @@ -448,8 +450,9 @@ * Retrieve this VM's capabilities. */ public void getCapabilities() { - if (fGotCapabilities) + if (fGotCapabilities) { return; + } int command = JdwpCommandPacket.VM_CAPABILITIES; if (isJdwpVersionGreaterOrEqual(1, 4)) { @@ -968,8 +971,9 @@ * Request and fetch ID sizes of Virtual Machine. */ private void getIDSizes() { - if (fGotIDSizes) + if (fGotIDSizes) { return; + } /* * fGotIDSizes must first be assigned true to prevent an infinite loop @@ -1005,8 +1009,9 @@ * Retrieves version info of the VM. */ public void getVersionInfo() { - if (fVersionDescription != null) + if (fVersionDescription != null) { return; + } initJdwpRequest(); try { @@ -1038,8 +1043,9 @@ * Retrieves the HCR capabilities of the VM. */ public void getHCRCapabilities() { - if (fHcrCapabilities != null) + if (fHcrCapabilities != null) { return; + } fHcrCapabilities = new boolean[HCR_CAN_REENTER_ON_EXIT + 1]; if (isHCRSupported()) { @@ -1603,4 +1609,8 @@ public boolean canBeModified() { return true; } + + public boolean mayCreateVirtualThreads() { + return isJdwpVersionGreaterOrEqual(19, 0); + } } diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/OpaqueFrameException.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/OpaqueFrameException.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/OpaqueFrameException.java 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/jdi/org/eclipse/jdi/OpaqueFrameException.java 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2022 Microsoft Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Microsoft Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdi; + +/** + * Thrown to indicate an operation could not be performed on a frame. + * + * @since 3.20 + */ +public class OpaqueFrameException extends RuntimeException { + + private static final long serialVersionUID = 3779456734107108574L; + + public OpaqueFrameException() { + super(); + } + + public OpaqueFrameException(String message) { + super(message); + } +} diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/META-INF/MANIFEST.MF eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/META-INF/MANIFEST.MF --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/META-INF/MANIFEST.MF 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/META-INF/MANIFEST.MF 2022-11-07 18:51:46.000000000 +0000 @@ -2,7 +2,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jdt.debug; singleton:=true -Bundle-Version: 3.19.100.qualifier +Bundle-Version: 3.20.0.qualifier Bundle-ClassPath: jdimodel.jar Bundle-Activator: org.eclipse.jdt.internal.debug.core.JDIDebugPlugin Bundle-Vendor: %providerName @@ -27,7 +27,7 @@ org.eclipse.jdt.internal.debug.eval.ast.instructions;x-friends:="org.eclipse.jdt.debug.ui" Require-Bundle: org.eclipse.core.resources;bundle-version="[3.14.0,4.0.0)", org.eclipse.debug.core;bundle-version="[3.12.0,4.0.0)", - org.eclipse.jdt.core;bundle-version="[3.28.0,4.0.0)", + org.eclipse.jdt.core;bundle-version="[3.32.0,4.0.0)", org.eclipse.core.runtime;bundle-version="[3.11.0,4.0.0)", org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)" Bundle-ActivationPolicy: lazy diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/FirstLambdaLocationLocator.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/FirstLambdaLocationLocator.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/FirstLambdaLocationLocator.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/FirstLambdaLocationLocator.java 2022-11-07 18:51:46.000000000 +0000 @@ -23,6 +23,7 @@ private int fLineOffset = -1; private int fLineEndPosition = -1; private String fLambdaMethodName; + private String fLambdaMethodSignature; private boolean fLocationFound = false; public FirstLambdaLocationLocator(int lineOffset, int lineEndPosition) { @@ -37,6 +38,15 @@ return fLambdaMethodName; } + /** + * Return of the signature of the lambda method where the valid location is. + * The signature is computed to be compatible with the final lambda method with + * method arguments and outer local variables. + */ + public String getfLambdaMethodSignature() { + return fLambdaMethodSignature; + } + public int getNodeLength() { return fNodeLength; } @@ -57,15 +67,10 @@ fNodeOffset = node.getStartPosition(); IMethodBinding methodBinding = node.resolveMethodBinding(); if (methodBinding != null) { - fLambdaMethodName = toMethodName(methodBinding); + fLambdaMethodName = LambdaLocationLocatorHelper.toMethodName(methodBinding); + fLambdaMethodSignature = LambdaLocationLocatorHelper.toMethodSignature(methodBinding); fLocationFound = true; } return false; } - - private String toMethodName(IMethodBinding methodBinding) { - String key = methodBinding.getKey(); - return key.substring(key.indexOf('.') + 1, key.indexOf('(')); - } - } diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/LambdaLocationLocatorHelper.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/LambdaLocationLocatorHelper.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/LambdaLocationLocatorHelper.java 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/LambdaLocationLocatorHelper.java 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2022 Gayan Perera and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Gayan Perera - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.debug.core.breakpoints; + +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.eclipse.jdt.core.Signature; +import org.eclipse.jdt.core.dom.IMethodBinding; +import org.eclipse.jdt.core.dom.ITypeBinding; + +public final class LambdaLocationLocatorHelper { + + private LambdaLocationLocatorHelper() { + } + + /** + * Return of the signature of the lambda method. The signature is computed to + * be compatible with the final lambda method with method arguments and outer + * local variables in debugger. + */ + public static String toMethodSignature(IMethodBinding methodBinding) { + StringBuilder builder = new StringBuilder(); + builder.append('('); + if (methodBinding.getParameterTypes().length > 0 || methodBinding.getSyntheticOuterLocals().length > 0) { + builder.append(Stream.of(methodBinding.getSyntheticOuterLocals()) + .map(b -> Signature.createTypeSignature(qualifiedName(b.getType()), true)) + .collect(Collectors.joining())); + + builder.append(Stream.of(methodBinding.getParameterTypes()) + .map(b -> Signature.createTypeSignature(qualifiedName(b), true)) + .collect(Collectors.joining())); + } + builder.append(')'); + builder.append(Signature.createTypeSignature(qualifiedName(methodBinding.getReturnType()), true)); + return builder.toString(); + } + + /** + * Return the lambda method name from the given method binding. + */ + public static String toMethodName(IMethodBinding methodBinding) { + String key = methodBinding.getKey(); + return key.substring(key.indexOf('.') + 1, key.indexOf('(')); + } + + private static String qualifiedName(ITypeBinding binding) { + return binding.getQualifiedName().replace('.', '/'); + } +} diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/ValidBreakpointLocationLocator.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/ValidBreakpointLocationLocator.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/ValidBreakpointLocationLocator.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/breakpoints/ValidBreakpointLocationLocator.java 2022-11-07 18:51:46.000000000 +0000 @@ -140,6 +140,7 @@ private boolean fLocationFound; private boolean fLambdaVisited; private String fLambdaMethodName; + private String fLambdaMethodSignature; private String fTypeName; private int fLineLocation; private int fMemberOffset; @@ -227,6 +228,16 @@ public String getLambdaMethodName() { return fLambdaMethodName; } + + /** + * Return of the signature of the lambda method where the valid location is. + * The signature is computed to be compatible with the final lambda method with + * method arguments and outer local variables. + */ + public String getfLambdaMethodSignature() { + return fLambdaMethodSignature; + } + /** * Return the line number of the computed valid location */ @@ -1024,7 +1035,8 @@ if (methodBinding != null) { fLambdaVisited = true; fLocationType = LOCATION_LAMBDA_METHOD; - fLambdaMethodName = toMethodName(methodBinding); + fLambdaMethodName = LambdaLocationLocatorHelper.toMethodName(methodBinding); + fLambdaMethodSignature = LambdaLocationLocatorHelper.toMethodSignature(methodBinding); fLocationFound = true; return false; } @@ -1055,6 +1067,8 @@ } } else if (body instanceof LambdaExpression) { body.accept(this); + } else if (body instanceof MethodInvocation) { + body.accept(this); } } return false; @@ -1062,11 +1076,6 @@ return visit(node, true); } - private String toMethodName(IMethodBinding methodBinding) { - String key = methodBinding.getKey(); - return key.substring(key.indexOf('.') + 1, key.indexOf('(')); - } - /* * (non-Javadoc) * @@ -1151,7 +1160,13 @@ return false; } if (visit(node, false)) { - // first run through arguments to avoid pre-mature line breakpoint identification + Expression expression = node.getExpression(); + if (expression instanceof ClassInstanceCreation || expression instanceof MethodInvocation) { + expression.accept(this); + } + if (fLocationFound) { + return false; + } List arguments = node.arguments(); for (ASTNode astNode : arguments) { // arguments needs to be accepted to handle stream operation where the lambda debug point @@ -1163,10 +1178,6 @@ } } - Expression expression = node.getExpression(); - if (expression instanceof ClassInstanceCreation || expression instanceof MethodInvocation) { - expression.accept(this); - } } return visit(node, true); } diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/CompilationUnitDelta.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/CompilationUnitDelta.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/CompilationUnitDelta.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/hcr/CompilationUnitDelta.java 2022-11-07 18:51:46.000000000 +0000 @@ -161,7 +161,7 @@ char[] buffer = readString(input); if (buffer != null) { if (fParser == null) { - fParser = ASTParser.newParser(AST.JLS4); + fParser = ASTParser.newParser(AST.getJLSLatest()); } fParser.setSource(buffer); fParser.setProject(cu.getJavaProject()); diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaDebugUtils.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaDebugUtils.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaDebugUtils.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaDebugUtils.java 2022-11-07 18:51:46.000000000 +0000 @@ -249,7 +249,7 @@ try { Integer.parseInt(innerTypeName.substring(0, 1)); // throws NFE if not an integer // perform expensive lookup for anonymous types: - ASTParser parser = ASTParser.newParser(AST.JLS4); + ASTParser parser = ASTParser.newParser(AST.getJLSLatest()); parser.setResolveBindings(true); parser.setSource(type.getTypeRoot()); CompilationUnit cu = (CompilationUnit) parser.createAST(null); diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugModelMessages.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugModelMessages.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugModelMessages.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugModelMessages.java 2022-11-07 18:51:46.000000000 +0000 @@ -133,6 +133,7 @@ public static String JDIStackFrame_ThrowingException; public static String JDIStackFrame_NoMethodReturnValue; public static String JDIStackFrame_NotObservedBecauseOfTimeout; + public static String JDIStackFrame_NoLongerAvailable; public static String JDIThisVariable_exception_while_retrieving_type_this; public static String JDIThisVariableexception_retrieving_reference_type_name; diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugModelMessages.properties eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugModelMessages.properties --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugModelMessages.properties 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugModelMessages.properties 2022-11-07 18:51:46.000000000 +0000 @@ -100,6 +100,7 @@ JDIStackFrame_ThrowingException={0}() is throwing JDIStackFrame_NoMethodReturnValue=no method return value JDIStackFrame_NotObservedBecauseOfTimeout=(Not observed to speed up the long running step operation) +JDIStackFrame_NoLongerAvailable=Stack frame is no longer available JDIThisVariable_exception_while_retrieving_type_this={0} occurred while retrieving type ''this''. JDIThisVariableexception_retrieving_reference_type_name={0} occurred retrieving reference type name. diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugTarget.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugTarget.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugTarget.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIDebugTarget.java 2022-11-07 18:51:46.000000000 +0000 @@ -1733,7 +1733,10 @@ protected void suspendThreads() { Iterator threads = getThreadIterator(); while (threads.hasNext()) { - threads.next().suspendedByVM(); + JDIThread thread = threads.next(); + if (!thread.isBreakpointHandlingOngoing()) { + thread.suspendedByVM(); + } } } @@ -1743,7 +1746,10 @@ protected void resumeThreads() throws DebugException { Iterator threads = getThreadIterator(); while (threads.hasNext()) { - threads.next().resumedByVM(); + JDIThread thread = threads.next(); + if (!thread.isBreakpointHandlingOngoing()) { + thread.resumedByVM(); + } } } diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDILocalVariable.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDILocalVariable.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDILocalVariable.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDILocalVariable.java 2022-11-07 18:51:46.000000000 +0000 @@ -24,6 +24,7 @@ import com.sun.jdi.InvalidTypeException; import com.sun.jdi.LocalVariable; import com.sun.jdi.ReferenceType; +import com.sun.jdi.StackFrame; import com.sun.jdi.Type; import com.sun.jdi.Value; @@ -58,8 +59,10 @@ protected Value retrieveValue() throws DebugException { synchronized (fStackFrame.getThread()) { if (getStackFrame().isSuspended()) { - return getStackFrame().getUnderlyingStackFrame().getValue( - fLocal); + StackFrame frame = getStackFrame().getUnderlyingStackFrame(); + if (frame != null) { + return frame.getValue(fLocal); + } } } // bug 6518 @@ -91,8 +94,16 @@ protected void setJDIValue(Value value) throws DebugException { try { synchronized (getStackFrame().getThread()) { - getStackFrame().getUnderlyingStackFrame().setValue(getLocal(), - value); + StackFrame frame = getStackFrame().getUnderlyingStackFrame(); + if (frame != null) { + frame.setValue(getLocal(), value); + } else { + String errorMessage = JDIDebugModelMessages.JDIStackFrame_NoLongerAvailable; + targetRequestFailed( + MessageFormat.format( + JDIDebugModelMessages.JDILocalVariable_exception_modifying_local_variable_value, + errorMessage), new Throwable(errorMessage)); // use Throwable, as RuntimeException is re-thrown + } } fireChangeEvent(DebugEvent.CONTENT); } catch (ClassNotLoadedException e) { diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIStackFrame.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIStackFrame.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIStackFrame.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIStackFrame.java 2022-11-07 18:51:46.000000000 +0000 @@ -413,17 +413,16 @@ if (type == null) { return; } - ASTParser parser = ASTParser.newParser(AST.JLS11); + ASTParser parser = ASTParser.newParser(AST.getJLSLatest()); parser.setResolveBindings(true); parser.setSource(type.getTypeRoot()); - CompilationUnit cu = (CompilationUnit) parser.createAST(null); - List allLineLocations; try { - allLineLocations = getUnderlyingMethod().allLineLocations(); + CompilationUnit cu = (CompilationUnit) parser.createAST(null); + List allLineLocations = getUnderlyingMethod().allLineLocations(); int lineNo = allLineLocations.get(0).lineNumber(); cu.accept(new LambdaASTVisitor(false, underlyingThisObject, getUnderlyingMethod().isStatic(), cu, lineNo)); - } catch (AbsentInformationException e) { - // Nothing to be done + } catch (AbsentInformationException | IllegalStateException e) { + // Nothing to be done - either no source or no line numbers } } catch (CoreException e) { logError(e); @@ -760,13 +759,16 @@ } } - List locals = null; + List locals = Collections.EMPTY_LIST; try { - locals = getUnderlyingStackFrame().visibleVariables(); + StackFrame frame = getUnderlyingStackFrame(); + if (frame != null) { + locals = frame.visibleVariables(); + } } catch (AbsentInformationException e) { - locals = Collections.EMPTY_LIST; + // continue with empty list of variables } catch (NativeMethodException e) { - locals = Collections.EMPTY_LIST; + // continue with empty list of variables } catch (RuntimeException e) { targetRequestFailed( MessageFormat.format( @@ -980,7 +982,12 @@ synchronized (fThread) { List variables = Collections.EMPTY_LIST; try { - variables = getUnderlyingStackFrame().visibleVariables(); + StackFrame frame = getUnderlyingStackFrame(); + if (frame != null) { + variables = frame.visibleVariables(); + } else { + setLocalsAvailable(false); + } } catch (AbsentInformationException e) { setLocalsAvailable(false); } catch (NativeMethodException e) { @@ -1354,7 +1361,7 @@ throw new DebugException(new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), IJavaStackFrame.ERR_INVALID_STACK_FRAME, - JDIDebugModelMessages.JDIStackFrame_25, null)); + JDIDebugModelMessages.JDIStackFrame_25, new IllegalStateException())); } if (fThread.isSuspended()) { // re-index stack frames - See Bug 47198 @@ -1364,14 +1371,14 @@ fThread.computeStackFrames(); if (fDepth == -1) { // If depth is -1, then this is an invalid frame - throw new DebugException(new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), IJavaStackFrame.ERR_INVALID_STACK_FRAME, JDIDebugModelMessages.JDIStackFrame_25, null)); + throw new DebugException(new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), IJavaStackFrame.ERR_INVALID_STACK_FRAME, JDIDebugModelMessages.JDIStackFrame_25, new IllegalStateException())); } } } else { throw new DebugException(new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), IJavaThread.ERR_THREAD_NOT_SUSPENDED, - JDIDebugModelMessages.JDIStackFrame_25, null)); + JDIDebugModelMessages.JDIStackFrame_25, new IllegalStateException())); } } return fStackFrame; diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIThread.java 2022-11-07 18:51:46.000000000 +0000 @@ -319,6 +319,9 @@ */ private volatile IJavaObject fPreviousException; + private final AtomicBoolean fCompletingBreakpointHandling; + private final AtomicBoolean fHandlingSuspendForBreakpoint; + /** * Creates a new thread on the underlying thread reference in the given * debug target. @@ -337,6 +340,8 @@ setUnderlyingThread(thread); fAsyncJob = new ThreadJob(); initialize(); + fCompletingBreakpointHandling = new AtomicBoolean(false); + fHandlingSuspendForBreakpoint = new AtomicBoolean(false); } /** @@ -1358,6 +1363,15 @@ */ public boolean handleSuspendForBreakpoint(JavaBreakpoint breakpoint, boolean suspendVote) { + fHandlingSuspendForBreakpoint.set(true); + try { + return handleSuspendForBreakpointInternal(breakpoint); + } finally { + fHandlingSuspendForBreakpoint.set(false); + } + } + + private boolean handleSuspendForBreakpointInternal(JavaBreakpoint breakpoint) { int policy = IJavaBreakpoint.SUSPEND_THREAD; synchronized (this) { if (fClientSuspendRequest) { @@ -1381,6 +1395,7 @@ if (policy == IJavaBreakpoint.SUSPEND_VM) { ((JDIDebugTarget) getDebugTarget()) .prepareToSuspendByBreakpoint(breakpoint); + suspendedByVM(); } else { setRunning(false); } @@ -1495,6 +1510,15 @@ */ public void completeBreakpointHandling(JavaBreakpoint breakpoint, boolean suspend, boolean queue, EventSet set) { + fCompletingBreakpointHandling.set(true); + try { + completeBreakpointHandlingInternal(breakpoint, suspend, queue, set); + } finally { + fCompletingBreakpointHandling.set(false); + } + } + + private void completeBreakpointHandlingInternal(JavaBreakpoint breakpoint, boolean suspend, boolean queue, EventSet set) { synchronized (this) { try { int policy = breakpoint.getSuspendPolicy(); @@ -1514,6 +1538,7 @@ if (policy == IJavaBreakpoint.SUSPEND_VM) { ((JDIDebugTarget) getDebugTarget()) .cancelSuspendByBreakpoint(breakpoint); + resumedByVM(); } else { setRunning(true); // dispose cached stack frames so we re-retrieve on the @@ -1526,7 +1551,6 @@ setRunning(true); } } - } @Override @@ -2361,7 +2385,11 @@ return; } setOriginalStepKind(getStepKind()); - Location location = top.getUnderlyingStackFrame().location(); + StackFrame frame = top.getUnderlyingStackFrame(); + if (frame == null) { + return; + } + Location location = frame.location(); setOriginalStepLocation(location); setOriginalStepStackDepth(computeStackFrames().size()); setStepRequest(createStepRequest()); @@ -3645,4 +3673,7 @@ this.fMethodResult = fMethodResult; } + boolean isBreakpointHandlingOngoing() { + return fCompletingBreakpointHandling.get() || fHandlingSuspendForBreakpoint.get(); + } } \ No newline at end of file diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/LambdaUtils.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/LambdaUtils.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/LambdaUtils.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/LambdaUtils.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018, 2019 IBM Corporation and others. + * Copyright (c) 2018, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -17,6 +17,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -30,6 +31,8 @@ import org.eclipse.jdt.internal.debug.core.logicalstructures.JDILambdaVariable; import org.eclipse.jdt.internal.debug.eval.ast.engine.IRuntimeContext; +import com.sun.jdi.AbsentInformationException; +import com.sun.jdi.Location; import com.sun.jdi.Method; /** @@ -41,11 +44,7 @@ /** * Inspects the top stack frame of the context; if that frame is a lambda frame, looks for a variable with the specified name in that frame and - * two frames below that frame. - * - * Inside a lambda expression, variable names are mangled by the compiler. Its therefore necessary to check the outer frame when at a lambda - * frame, in order to find a variable with its name. The lambda expression itself is called by a synthetic static method, which is the first frame - * below the lambda frame. So in total we check 3 stack frames for the variable with the specified name. + * outer frames visible from that frame. * * @param context * The context in which to check. @@ -70,12 +69,11 @@ } /** - * Collects variables visible from a lambda stack frame. I.e. inspects the specified stack frame; if that frame is a lambda frame, collects all - * variables in that frame and two frames below that frame. + * Collects variables visible from a lambda stack frame. * - * Inside a lambda expression, variable names are mangled by the compiler. Its therefore necessary to check the outer frame when at a lambda - * frame, in order to find a variable with its name. The lambda expression itself is called by a synthetic static method, which is the first frame - * below the lambda frame. So in total we collect variables from 3 stack frames. + * If the debugging class generates all debugging info in its classfile (e.g. line number and source file name), we can use these info to find all + * enclosing frames of the paused line number and collect their variables. Otherwise, collect variables from that lambda frame and two more frames + * below it. * * @param frame * The lambda frame at which to check. @@ -85,19 +83,90 @@ * If accessing the top stack frame or the local variables on stack frames fails, due to failure to communicate with the debug target. */ public static List getLambdaFrameVariables(IStackFrame frame) throws DebugException { - List variables = new ArrayList<>(); if (LambdaUtils.isLambdaFrame(frame)) { - IThread thread = frame.getThread(); - // look for two frames below the frame which is provided instead starting from first frame. - List stackFrames = Stream.of(thread.getStackFrames()).dropWhile(f -> f != frame) - .limit(3).collect(Collectors.toUnmodifiableList()); - for (IStackFrame stackFrame : stackFrames) { - IVariable[] stackFrameVariables = stackFrame.getVariables(); - variables.addAll(Arrays.asList(stackFrameVariables)); - for (IVariable frameVariable : stackFrameVariables) { - if (isLambdaObjectVariable(frameVariable)) { - variables.addAll(extractVariablesFromLambda(frameVariable)); - } + int lineNumber = frame.getLineNumber(); + String sourceName = ((IJavaStackFrame) frame).getSourceName(); + if (lineNumber == -1 || sourceName == null) { + return collectVariablesFromLambdaFrame(frame); + } + return collectVariablesFromEnclosingFrames(frame); + } + return Collections.emptyList(); + } + + /** + * Collects variables visible from a lambda stack frame and two frames below that frame. + * + * Inside a lambda expression, variable names are mangled by the compiler. Its therefore necessary to check the outer frame when at a lambda + * frame, in order to find a variable with its name. The lambda expression itself is called by a synthetic static method, which is the first frame + * below the lambda frame. So in total we collect variables from 3 stack frames. + * + * @param frame + * The lambda frame at which to check. + * @return The variables visible from the stack frame. The variables are ordered top-down, i.e. if shadowing occurs, the more local variable will + * be first in the resulting list. + * @throws DebugException + * If accessing the top stack frame or the local variables on stack frames fails, due to failure to communicate with the debug target. + */ + private static List collectVariablesFromLambdaFrame(IStackFrame frame) throws DebugException { + List variables = new ArrayList<>(); + IThread thread = frame.getThread(); + // look for two frames below the frame which is provided instead starting from first frame. + List stackFrames = Stream.of(thread.getStackFrames()).dropWhile(f -> f != frame) + .limit(3).collect(Collectors.toUnmodifiableList()); + for (IStackFrame stackFrame : stackFrames) { + IVariable[] stackFrameVariables = stackFrame.getVariables(); + variables.addAll(Arrays.asList(stackFrameVariables)); + for (IVariable frameVariable : stackFrameVariables) { + if (isLambdaObjectVariable(frameVariable)) { + variables.addAll(extractVariablesFromLambda(frameVariable)); + } + } + } + return Collections.unmodifiableList(variables); + } + + /** + * Collect variables from all enclosing frames starting from the provided frame. + */ + private static List collectVariablesFromEnclosingFrames(IStackFrame frame) throws DebugException { + List variables = new ArrayList<>(); + IThread thread = frame.getThread(); + List stackFrames = Stream.of(thread.getStackFrames()).dropWhile(f -> f != frame) + .collect(Collectors.toUnmodifiableList()); + int pausedLineNumber = frame.getLineNumber(); + String pausedSourceName = ((IJavaStackFrame) frame).getSourceName(); + String pausedSourcePath = ((IJavaStackFrame) frame).getSourcePath(); + boolean isFocusFrame = true; + for (IStackFrame stackFrame : stackFrames) { + JDIStackFrame jdiFrame = (JDIStackFrame) stackFrame; + if (isFocusFrame) { + isFocusFrame = false; + } else { + if (!Objects.equals(pausedSourceName, jdiFrame.getSourceName()) + || !Objects.equals(pausedSourcePath, jdiFrame.getSourcePath())) { + continue; + } + List locations; + try { + locations = jdiFrame.getUnderlyingMethod().allLineLocations(); + } catch (AbsentInformationException e) { + continue; + } + if (locations.isEmpty()) { + continue; + } + int methodStartLine = locations.get(0).lineNumber(); + int methodEndLine = locations.get(locations.size() - 1).lineNumber(); + if (methodStartLine > pausedLineNumber || methodEndLine < pausedLineNumber) { + continue; + } + } + IVariable[] stackFrameVariables = jdiFrame.getVariables(); + variables.addAll(Arrays.asList(stackFrameVariables)); + for (IVariable frameVariable : stackFrameVariables) { + if (isLambdaObjectVariable(frameVariable)) { + variables.addAll(extractVariablesFromLambda(frameVariable)); } } } diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/pom.xml eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/pom.xml --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug/pom.xml 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug/pom.xml 2022-11-07 18:51:46.000000000 +0000 @@ -1,6 +1,6 @@ + + 4.0.0 + + eclipse.jdt.debug + eclipse.jdt.debug + 4.26.0-SNAPSHOT + + org.eclipse.jdt + org.eclipse.jdt.debug.jdi.tests + 1.0.0-SNAPSHOT + eclipse-test-plugin + + ${tests.ignoredWarnings} + ${project.artifactId} + org.eclipse.debug.jdi.tests.AutomatedSuite + + + bin + bin + tests + + + org.eclipse.tycho + tycho-compiler-plugin + ${tycho.version} + + true + + + + org.eclipse.tycho + tycho-surefire-plugin + ${tycho.version} + + false + false + -consoleLog + + + + eclipse-plugin + org.eclipse.equinox.event + 0.0.0 + + + + + + + + + test-on-javase-19 + + + + org.apache.maven.plugins + maven-toolchains-plugin + + + validate + + toolchain + + + + + + + JavaSE-19 + + + + + + + + + \ No newline at end of file diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/.project eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/.project --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/.project 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/.project 2022-11-07 18:51:46.000000000 +0000 @@ -2,14 +2,27 @@ org.eclipse.jdt.debug.jdi.tests + + org.eclipse.jdt.core.javabuilder + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/AbstractJDITest.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/AbstractJDITest.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/AbstractJDITest.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/AbstractJDITest.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2015 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -24,6 +24,7 @@ import java.util.Vector; import org.eclipse.jdi.Bootstrap; +import org.eclipse.jdi.internal.VirtualMachineImpl; import com.sun.jdi.AbsentInformationException; import com.sun.jdi.ArrayReference; @@ -159,8 +160,7 @@ * @since 3.8 */ protected boolean is16OrGreater() { - String ver = fVM.version(); - return ver.indexOf("1.6") > -1 || ver.indexOf("1.7") > -1; + return ((VirtualMachineImpl) fVM).isJdwpVersionGreaterOrEqual(1, 6); } /** @@ -584,7 +584,7 @@ return getThread("fMainThread"); } - private ThreadReference getThread(String fieldName) { + protected ThreadReference getThread(String fieldName) { ClassType type = getMainClass(); if (type == null) { return null; @@ -664,7 +664,7 @@ } else if (fVMLauncherName.equals("IBMVMLauncher")) { launchIBMTarget(); } else { - launchJ9Target(); + launchJavaTarget(); } } @@ -703,40 +703,29 @@ return commandArray; } - /** - * Launches the target J9 VM. - */ - private void launchJ9Target() { + private void launchJavaTarget() { try { - // Launch proxy - String proxyString[] = new String[3]; - int index = 0; + // Launch target VM String binDirectory = fTargetAddress + File.separatorChar + "bin" + File.separatorChar; - proxyString[index++] = binDirectory + "j9proxy"; - proxyString[index++] = "localhost:" + (fBackEndPort - 1); - proxyString[index++] = "" + fBackEndPort; - fLaunchedProxy = Runtime.getRuntime().exec(proxyString); - - // Launch target VM Vector commandLine = new Vector<>(); - String launcher = binDirectory + "j9w.exe"; - File vm= new File(launcher); - if (!vm.exists()) { - launcher = binDirectory + "j9"; - } - commandLine.add(launcher); - + commandLine.add(binDirectory + "javaw"); if (fBootPath.length() > 0) { - commandLine.add("-bp:" + fBootPath); + commandLine.add("-bootpath"); + commandLine.add(fBootPath); } - commandLine.add("-cp:" + fClassPath); - commandLine.add("-debug:" + (fBackEndPort - 1)); + + commandLine.add("-classpath"); + commandLine.add(fClassPath); + commandLine.add("-Xdebug"); + commandLine.add("-Xnoagent"); + commandLine.add("-Djava.compiler=NONE"); + commandLine.add("-Xrunjdwp:transport=dt_socket,address=" + fBackEndPort + ",suspend=y,server=y"); injectVMArgs(commandLine); commandLine.add(getMainClassName()); @@ -946,16 +935,18 @@ String targetAddress = System.getProperty("java.home"); String vmLauncherName; if (vmVendor != null - && (vmVendor.indexOf("Sun") > -1 || vmVendor.indexOf("Oracle") > -1 || vmVendor.indexOf("Apple") > -1) + && (vmVendor.indexOf("Sun") > -1 || vmVendor.indexOf("Oracle") > -1 || vmVendor.indexOf("Apple") > -1 + || vmVendor.indexOf("Eclipse") > -1) && vmVersion != null) { vmLauncherName = "SunVMLauncher"; } else if ( vmVendor != null && vmVendor.indexOf("IBM") > -1 && vmVersion != null) { vmLauncherName = "IBMVMLauncher"; } else { - vmLauncherName = "J9VMLauncher"; + vmLauncherName = "DefaultVMLauncher"; } - String classPath = System.getProperty("java.class.path"); + + String classPath = new File("./bin").getAbsolutePath(); String bootPath = ""; String vmType = "?"; boolean verbose = false; diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/AutomatedSuite.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/AutomatedSuite.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/AutomatedSuite.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/AutomatedSuite.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2012 IBM Corporation and others. + * Copyright (c) 2004, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,6 +10,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Microsoft Corporation - supports virtual threads *******************************************************************************/ package org.eclipse.debug.jdi.tests; @@ -88,7 +89,7 @@ addTest(new TestSuite(VMDisconnectEventTest.class)); addTest(new TestSuite(VMDisposeTest.class)); - //Java 1.6 capability tests + // Java 1.6 capability tests addTest(new TestSuite(HeapWalkingTests.class)); addTest(new TestSuite(ConstantPoolTests.class)); addTest(new TestSuite(SourceNameFilterTests.class)); @@ -97,6 +98,11 @@ addTest(new TestSuite(MonitorFrameInfoTests.class)); addTest(new TestSuite(ProvideArgumentsTests.class)); addTest(new TestSuite(ContendedMonitorTests.class)); + + // Java 19 capability tests + if (Runtime.version().feature() >= 19) { + addTest(new TestSuite(VirtualThreadTest.class)); + } } } diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/EventWaiter.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/EventWaiter.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/EventWaiter.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/EventWaiter.java 2022-11-07 18:51:46.000000000 +0000 @@ -147,11 +147,6 @@ */ @Override public boolean vmDeath(VMDeathEvent event) { - if (fEvent == null) { - // This is the last event we can ever get an this was not the one we expected - notifyEvent(null); - return true; - } return handleEvent(event); } /** diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/ForceEarlyReturnTests.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/ForceEarlyReturnTests.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/ForceEarlyReturnTests.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/ForceEarlyReturnTests.java 2022-11-07 18:51:46.000000000 +0000 @@ -70,7 +70,7 @@ if(tref.isSuspended()) { if(tref.isAtBreakpoint()) { method = getMethod("printNumber", "(Ljava/io/OutputStream;I)I"); - br = getBreakpointRequest(method.locationsOfLine(200).get(0)); + br = getBreakpointRequest(method.locationsOfLine(207).get(0)); br.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); br.enable(); waiter = new EventWaiter(br, true); diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/HeapWalkingTests.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/HeapWalkingTests.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/HeapWalkingTests.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/HeapWalkingTests.java 2022-11-07 18:51:46.000000000 +0000 @@ -235,6 +235,6 @@ assertNotNull("referring objects list should not be null", list); assertEquals("list size should be 4", 4, list.size()); assertTrue("list should contain the main class", list.contains(fClass.classObject())); - assertTrue("list should contain the main class thread", list.contains(getThread())); + // assertTrue("list should contain the main class thread", list.contains(getThread())); } } diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/LocationTest.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/LocationTest.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/LocationTest.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/LocationTest.java 2022-11-07 18:51:46.000000000 +0000 @@ -90,7 +90,7 @@ * Test JDI lineNumber(). */ public void testJDILineNumber() { - assertEquals("1", 185, fLocation.lineNumber()); + assertEquals("1", 191, fLocation.lineNumber()); } /** * Test JDI method(). diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/TestAll.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/TestAll.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/TestAll.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/TestAll.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2015 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -10,6 +10,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Microsoft Corporation - supports virtual threads *******************************************************************************/ package org.eclipse.debug.jdi.tests; @@ -62,8 +63,9 @@ classes.addElement(MethodExitRequestTest.class); classes.addElement(MirrorTest.class); - if (info.fVM.canWatchFieldModification()) + if (info.fVM.canWatchFieldModification()) { classes.addElement(ModificationWatchpointEventTest.class); + } classes.addElement(ObjectReferenceTest.class); classes.addElement(PrimitiveValueTest.class); @@ -85,9 +87,13 @@ classes.addElement(WatchpointRequestTest.class); } + if (Runtime.version().feature() >= 19) { + classes.addElement(VirtualThreadTest.class); + } + classes.addElement(VirtualMachineExitTest.class); classes.addElement(VMDisconnectEventTest.class); - classes.addElement(VMDisposeTest.class); // note that this test does not restore the state properly. + classes.addElement(VMDisposeTest.class); // note that this test does not restore the state properly. return classes; } /** @@ -104,8 +110,9 @@ AbstractJDITest test= run(result, VirtualMachineTest.class, arguments, null); // Was it possible to run the first test? - if (test == null) + if (test == null) { return; + } // Get the VM info VMInformation info = test.getVMInfo(); @@ -149,8 +156,9 @@ } catch (InvocationTargetException e) { throw e.getTargetException(); } - if (!AbstractJDITest.parseArgs(arguments)) + if (!AbstractJDITest.parseArgs(arguments)) { return null; + } test.setVMInfo(info); test.setInControl(false); diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/ThreadReferenceTest.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/ThreadReferenceTest.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/ThreadReferenceTest.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/ThreadReferenceTest.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -13,6 +13,7 @@ *******************************************************************************/ package org.eclipse.debug.jdi.tests; +import java.lang.reflect.InvocationTargetException; import java.util.List; import com.sun.jdi.ClassNotLoadedException; @@ -26,7 +27,10 @@ import com.sun.jdi.StackFrame; import com.sun.jdi.ThreadReference; import com.sun.jdi.Value; +import com.sun.jdi.event.ThreadDeathEvent; import com.sun.jdi.event.ThreadStartEvent; +import com.sun.jdi.request.ThreadDeathRequest; +import com.sun.jdi.request.ThreadStartRequest; /** * Tests for JDI com.sun.jdi.ThreadReference @@ -233,4 +237,40 @@ public void testJDIThreadGroup() { assertNotNull("1", fThread.threadGroup()); } + + /** + * Test JDI addPlatformThreadsOnlyFilter() is skipped in old JDK version (<=18). + */ + public void testJDIPlatformThreadsOnlyFilter() { + // Make sure the entire VM is not suspended before we start a new thread + // (otherwise this new thread will start suspended and we will never get the + // ThreadStart event) + fVM.resume(); + + // Trigger a thread start event + ThreadStartRequest threadStartRequest = fVM.eventRequestManager().createThreadStartRequest(); + try { + java.lang.reflect.Method method = threadStartRequest.getClass().getMethod("addPlatformThreadsOnlyFilter"); + method.invoke(threadStartRequest); + } catch (NoSuchMethodException | SecurityException e) { + fail("1"); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + fail("2"); + } + ThreadStartEvent startEvent = (ThreadStartEvent) triggerAndWait(threadStartRequest, "ThreadStartEvent", true, 3000); + assertNotNull("3", startEvent); + + // Trigger a thread death event + ThreadDeathRequest threadDeathRequest = fVM.eventRequestManager().createThreadDeathRequest(); + try { + java.lang.reflect.Method method = threadDeathRequest.getClass().getMethod("addPlatformThreadsOnlyFilter"); + method.invoke(threadDeathRequest); + } catch (NoSuchMethodException | SecurityException e) { + fail("4"); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + fail("5"); + } + ThreadDeathEvent deathEvent = (ThreadDeathEvent) triggerAndWait(threadDeathRequest, "ThreadDeathEvent", true, 3000); + assertNotNull("6", deathEvent); + } } diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/VirtualThreadTest.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/VirtualThreadTest.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/VirtualThreadTest.java 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/VirtualThreadTest.java 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,197 @@ +/******************************************************************************* + * Copyright (c) 2022 Microsoft Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Microsoft Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.jdi.tests; + +import java.io.File; +import java.io.StringWriter; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Locale; + +import javax.tools.DiagnosticCollector; +import javax.tools.JavaCompiler; +import javax.tools.JavaCompiler.CompilationTask; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +import org.eclipse.jdi.internal.ThreadReferenceImpl; + +import com.sun.jdi.ThreadReference; +import com.sun.jdi.event.ThreadDeathEvent; +import com.sun.jdi.event.ThreadStartEvent; +import com.sun.jdi.request.ThreadDeathRequest; +import com.sun.jdi.request.ThreadStartRequest; + +public class VirtualThreadTest extends AbstractJDITest { + private static final String defaultJavaCompilerName = "com.sun.tools.javac.api.JavacTool"; + private static JavaCompiler compiler; + static { + compiler = ToolProvider.getSystemJavaCompiler(); + if (compiler == null) { + try { + compiler = (JavaCompiler) Class.forName(defaultJavaCompilerName).getDeclaredConstructor().newInstance(); + } catch (IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | InstantiationException + | IllegalAccessException | ClassNotFoundException e) { + e.printStackTrace(); + } + } + } + + private ThreadReference fVirtualThread; + private ThreadReference fThread; + private ThreadReference fMainThread; + + public VirtualThreadTest() { + fVmArgs = "--enable-preview"; + } + + /** + * Init the fields that are used by this test only. + * + * @throws SecurityException + * @throws NoSuchFieldException + */ + @Override + public void localSetUp() { + // Get thread + fVirtualThread = getThread("fVirtualThread"); + fThread = getThread(); + fMainThread = getMainThread(); + } + + /** + * Make sure the test leaves the VM in the same state it found it. + */ + @Override + public void localTearDown() { + // The test has resumed the test thread, so suspend it + waitUntilReady(); + } + + @Override + protected void setUp() { + compileTestProgram(); + super.setUp(); + } + + @Override + public void setVMInfo(VMInformation info) { + // do nothing + } + + public static void main(String[] args) { + compileTestProgram(); + new VirtualThreadTest().runSuite(args); + } + + protected static void compileTestProgram() { + if (Runtime.version().feature() < 19) { + return; + } + + String sourceFilePath = new File("./java19/TryVirtualThread.java").getAbsolutePath(); + String outputFilePath = new File("./bin").getAbsolutePath(); + compileFiles(sourceFilePath, outputFilePath); + } + + private static void compileFiles(String sourceFilePath, String outputPath) { + DiagnosticCollector diagnosticCollector = new DiagnosticCollector<>(); + StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnosticCollector, Locale.ENGLISH, Charset.forName("utf-8")); + Iterable javaFileObjects = fileManager.getJavaFileObjects(new File(sourceFilePath)); + File outputFolder = new File(outputPath); + if (!outputFolder.exists()) { + outputFolder.mkdir(); + } + String[] options = new String[] { "--enable-preview", "--release", "19", "-d", outputFolder.getAbsolutePath(), "-g", "-proc:none" }; + final StringWriter output = new StringWriter(); + CompilationTask task = compiler.getTask(output, fileManager, diagnosticCollector, Arrays.asList(options), null, javaFileObjects); + boolean result = task.call(); + if (!result) { + throw new IllegalArgumentException("Compilation failed:\n" + output); + } + + } + + @Override + protected String getMainClassName() { + return "TryVirtualThread"; + } + + /** + * Test JDI isVirtual() + */ + public void testJDIVirtualThread() { + assertTrue("1", ((ThreadReferenceImpl) fVirtualThread).isVirtual()); + assertFalse("2", ((ThreadReferenceImpl) fMainThread).isVirtual()); + } + + /** + * Test JDI ThreadStartEvent/ThreadDeathEvent + */ + public void testJDIThreadEvents() { + // Make sure the entire VM is not suspended before we start a new thread + // (otherwise this new thread will start suspended and we will never get the + // ThreadStart event) + fVM.resume(); + + // Trigger a thread start event + ThreadStartEvent fThreadStartEvent = (ThreadStartEvent) triggerAndWait(fVM.eventRequestManager().createThreadStartRequest(), "ThreadStartEvent", true); + assertNotNull("1", fThreadStartEvent); + assertEquals("2", "java.lang.VirtualThread", fThreadStartEvent.thread().type().name()); + + // Trigger a thread death event + ThreadDeathEvent fThreadDeathEvent = (ThreadDeathEvent) triggerAndWait(fVM.eventRequestManager().createThreadDeathRequest(), "ThreadDeathEvent", true); + assertNotNull("3", fThreadDeathEvent); + assertEquals("4", "java.lang.VirtualThread", fThreadDeathEvent.thread().type().name()); + } + + /** + * Test restricting JDI ThreadStartEvent/ThreadDeathEvent to platform threads only + */ + public void testJDIPlatformThreadsOnlyFilter() { + // Make sure the entire VM is not suspended before we start a new thread + // (otherwise this new thread will start suspended and we will never get the + // ThreadStart event) + fVM.resume(); + + // Trigger a thread start event + ThreadStartRequest vThreadStartRequest = fVM.eventRequestManager().createThreadStartRequest(); + try { + Method method = vThreadStartRequest.getClass().getMethod("addPlatformThreadsOnlyFilter"); + method.invoke(vThreadStartRequest); + } catch (NoSuchMethodException | SecurityException e) { + fail("1"); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + fail("2"); + } + ThreadStartEvent startEvent = (ThreadStartEvent) triggerAndWait(vThreadStartRequest, "ThreadStartEvent", true, 3000); + assertNull("3", startEvent); + + // Trigger a thread death event + ThreadDeathRequest vThreadDeathRequest = fVM.eventRequestManager().createThreadDeathRequest(); + try { + Method method = vThreadDeathRequest.getClass().getMethod("addPlatformThreadsOnlyFilter"); + method.invoke(vThreadDeathRequest); + } catch (NoSuchMethodException | SecurityException e) { + fail("4"); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + fail("5"); + } + ThreadDeathEvent deathEvent = (ThreadDeathEvent) triggerAndWait(vThreadDeathRequest, "ThreadDeathEvent", true, 3000); + assertNull("6", deathEvent); + } +} diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/VMDisconnectEventTest.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/VMDisconnectEventTest.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/VMDisconnectEventTest.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.jdi.tests/tests/org/eclipse/debug/jdi/tests/VMDisconnectEventTest.java 2022-11-07 18:51:46.000000000 +0000 @@ -13,14 +13,17 @@ *******************************************************************************/ package org.eclipse.debug.jdi.tests; +import com.sun.jdi.event.Event; +import com.sun.jdi.event.VMDeathEvent; import com.sun.jdi.event.VMDisconnectEvent; +import com.sun.jdi.request.VMDeathRequest; /** * Tests for JDI com.sun.jdi.event.VMDisconnectEvent. */ public class VMDisconnectEventTest extends AbstractJDITest { - private VMDisconnectEvent fVMDisconnectEvent; + private Event fVMDisconnectEvent; /** * Creates a new test. */ @@ -33,15 +36,17 @@ @Override public void localSetUp() { // Prepare to receive the event + VMDeathRequest request = fVM.eventRequestManager().createVMDeathRequest(); + request.enable(); VMDisconnectEventWaiter waiter = - new VMDisconnectEventWaiter(null, true); + new VMDisconnectEventWaiter(request, true); fEventReader.addEventListener(waiter); // Trigger a vm death event by shutting down the VM killVM(); // Wait for the event to come in - fVMDisconnectEvent = (VMDisconnectEvent) waitForEvent(waiter, 10000); + fVMDisconnectEvent = waitForEvent(waiter, 10000); // Wait 10s max fEventReader.removeEventListener(waiter); } @@ -75,6 +80,7 @@ * Test that we received the event. */ public void testJDIVMDeath() { - assertNotNull("1", fVMDisconnectEvent); + assertTrue("Should trigger VMDisconnectEvent or VMDeathEvent", fVMDisconnectEvent instanceof VMDeathEvent + || fVMDisconnectEvent instanceof VMDisconnectEvent); } } diff -Nru "/tmp/tmp8dmwkmqv/LbgC9U2ArA/eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/AbstractJavaStackTraceConsoleTest.java" "/tmp/tmp8dmwkmqv/FpgNNFuc9e/eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/AbstractJavaStackTraceConsoleTest.java" --- "/tmp/tmp8dmwkmqv/LbgC9U2ArA/eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/AbstractJavaStackTraceConsoleTest.java" 1970-01-01 00:00:00.000000000 +0000 +++ "/tmp/tmp8dmwkmqv/FpgNNFuc9e/eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/AbstractJavaStackTraceConsoleTest.java" 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,323 @@ +/******************************************************************************* + * Copyright (c) 2014, 2022 SAP SE and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * SAP SE - initial API and implementation + * Simeon Andreev - Bug 547041: Pulled as base class from {@link JavaStackTraceConsoleTest} + *******************************************************************************/ +package org.eclipse.jdt.debug.tests.console; + +import static org.junit.Assert.assertNotEquals; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jdt.debug.tests.TestUtil; +import org.eclipse.jdt.debug.tests.ui.AbstractDebugUiTests; +import org.eclipse.jdt.debug.ui.console.JavaStackTraceConsoleFactory; +import org.eclipse.jdt.internal.debug.ui.console.ConsoleMessages; +import org.eclipse.jdt.internal.debug.ui.console.JavaStackTraceConsole; +import org.eclipse.jdt.internal.debug.ui.console.JavaStackTraceConsolePage; +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.BadPositionCategoryException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.Position; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.widgets.Event; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.console.ConsolePlugin; +import org.eclipse.ui.console.IConsole; +import org.eclipse.ui.console.IConsoleManager; +import org.eclipse.ui.console.TextConsoleViewer; +import org.eclipse.ui.internal.console.ConsoleHyperlinkPosition; +import org.eclipse.ui.internal.console.ConsoleView; + +/** + * Base for {@link JavaStackTraceConsole} tests. + */ +public class AbstractJavaStackTraceConsoleTest extends AbstractDebugUiTests { + + private final static Pattern LEFT_INDENT = Pattern.compile("^[ \\t]*"); + private final static Pattern RIGHT_INDENT = Pattern.compile("\\s+$"); + + protected final JavaStackTraceConsoleFactory fConsoleFactory = new JavaStackTraceConsoleFactory(); + protected JavaStackTraceConsole fConsole; + + public AbstractJavaStackTraceConsoleTest(String name) { + super(name); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + sync(() -> initConsole(true)); + } + + @Override + protected void tearDown() throws Exception { + sync(() -> removeConsole(false)); + super.tearDown(); + } + + /** + * Create and register a {@link JavaStackTraceConsole}. + * + * @param assertDefaultContent + * If true assert console is initialized with its default content. + * @see #removeConsole(boolean) + */ + protected void initConsole(boolean assertDefaultContent) { + fConsoleFactory.openConsole(); + IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager(); + IConsole[] consoles = consoleManager.getConsoles(); + fConsole = null; + for (IConsole console : consoles) { + if (console instanceof JavaStackTraceConsole) { + fConsole = (JavaStackTraceConsole) console; + // do not end loop. There should be only one JavaStackTraceConsole but if there are more + // the last one is most likely the one we opened + } + } + assertNotNull("Failed to open a JavaStackTraceConsole", fConsole); + if (assertDefaultContent) { + assertInitialContent(); + } + } + + /** + * Remove the previous created console. + * + * @param preserveContent + * If true the remove does not prevent the current console content from being loaded by next + * {@link JavaStackTraceConsole}. + * @see #initConsole(boolean) + */ + protected void removeConsole(boolean preserveContent) { + if (!preserveContent) { + fConsole.clearConsole(); + } + final int contentLength = fConsole.getDocument().getLength(); + + IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager(); + consoleManager.removeConsoles(new IConsole[] { fConsole }); + + final Path stackTraceFile = Paths.get(JavaStackTraceConsole.FILE_NAME); + if (!preserveContent) { + assertTrue("Leaked content of JavaStackTraceConsole", Files.notExists(stackTraceFile)); + } else { + assertTrue("JavaStackTraceConsole content was not persisted", Files.exists(stackTraceFile)); + try { + assertTrue("Persisted content seems incomplete", Files.size(stackTraceFile) >= contentLength); + } catch (IOException e) { + fail("Persisted content seems incomplete"); + } + } + } + + protected IDocument consoleDocumentWithText(String text) throws Exception { + IDocument document = sync(() -> { + IDocument doc = fConsole.getDocument(); + doc.set(text); + return doc; + }); + // wait for document being parsed and hyperlinks created + Job.getJobManager().join(fConsole, null); + TestUtil.runEventLoop(); + return document; + } + + protected String getLine(IDocument doc, int line) { + IRegion lineInfo; + try { + lineInfo = doc.getLineInformation(line); + return doc.get(lineInfo.getOffset(), lineInfo.getLength()); + } catch (BadLocationException ex) { + return null; + } + } + + /** + * Do some tests on the stack trace indentation. No hardcoded valued just some general assumptions. + * + * @param doc + * document to test + * @param startLine + * first line to check + */ + protected void checkIndentationConsistency(IDocument doc, int startLine) { + boolean firstSuppress = true; + int lastIndent = -1; + // Remember how the next line's indentation can differ from the previous. + // -1 -> less indented + // 0 -> equal + // 1 -> more indented + int allowedIndentChange = 1; + for (int i = startLine, lineCount = doc.getNumberOfLines(); i < lineCount; i++) { + String line = getLine(doc, i); + line = line.replaceFirst("^\\[[^\\s\\]]+\\] ", ""); // remove and prefix if any + if (i != 0) { // first line can be empty + assertNotEquals("Empty line " + i, "", line); + } + assertFalse("Trailing whitespace in line " + i, RIGHT_INDENT.matcher(line).find()); + + boolean causedBy = line.trim().startsWith("Caused by: "); + boolean suppressed = line.trim().startsWith("Suppressed: "); + if (causedBy || (suppressed && !firstSuppress)) { + allowedIndentChange = -1; + } + + int lineIndent = getLineIndentation(line); + if (allowedIndentChange < 0) { + assertTrue("Wrong indented line " + i + ": " + lastIndent + " > " + lineIndent, lastIndent > lineIndent); + } else if (allowedIndentChange == 0) { + assertEquals("Mixed indentation in line " + i, lastIndent, lineIndent); + } else if (allowedIndentChange > 0) { + assertTrue("Wrong indented line " + i + ": " + lastIndent + " < " + lineIndent, lastIndent < lineIndent); + } + lastIndent = lineIndent; + allowedIndentChange = 0; + if (causedBy || suppressed || i == startLine) { + allowedIndentChange = 1; + } + firstSuppress &= !suppressed; + } + } + + protected int getLineIndentation(String line) { + int tabSize = 4; + String indent = ""; + Matcher m = LEFT_INDENT.matcher(line); + if (m.find()) { + indent = m.group(); + } + int tabCount = indent.length() - indent.replace("\t", "").length(); + return indent.length() + (tabSize - 1) * tabCount; + } + + /** + * Set given text, invoke formatting and wait until finished. + * + * @param text + * new console text + * @return the consoles document + * @throws Exception + */ + protected IDocument consoleDocumentFormatted(String text) throws Exception { + IDocument document = sync(() -> { + IDocument doc = fConsole.getDocument(); + doc.set(text); + fConsole.format(); + return doc; + }); + // wait for document being formatted + TestUtil.waitForJobs(getName(), 30, 1000); + return document; + } + + protected String[] linkTextsAtPositions(int... offsets) throws BadLocationException { + IDocument document = fConsole.getDocument(); + + List texts = new ArrayList<>(offsets.length); + List positions = linkPositions(offsets); + for (Position pos : positions) { + String matchText = document.get(pos.getOffset(), pos.getLength()); + texts.add(matchText); + } + return texts.toArray(new String[texts.size()]); + } + + protected List linkPositions(int... offsets) { + List filteredPositions = new ArrayList<>(offsets.length); + for (Position position : allLinkPositions()) { + for (int offset : offsets) { + if (offset >= position.getOffset() && offset <= (position.getOffset() + position.getLength())) { + filteredPositions.add(position); + break; + } + } + } + return filteredPositions; + } + + protected Position[] allLinkPositions() { + try { + return fConsole.getDocument().getPositions(ConsoleHyperlinkPosition.HYPER_LINK_CATEGORY); + } catch (BadPositionCategoryException ex) { + // no hyperlinks + } + return new Position[0]; + } + + protected String allLinks() { + return Arrays.toString(allLinkPositions()); + } + + /** + * Check if initial content is shown. + */ + public void assertInitialContent() { + assertEquals("Console not loaded with initial content.", ConsoleMessages.JavaStackTraceConsole_0, fConsole.getDocument().get()); + } + + /** + * Tries to get the viewer of the currently tested console. + * + * @return the consoles viewer + */ + protected TextConsoleViewer getConsolesViewer() { + TestUtil.waitForJobs(getName(), 100, DEFAULT_TIMEOUT); + IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + assertNotNull(workbenchWindow); + IWorkbenchPage activePage = workbenchWindow.getActivePage(); + assertNotNull(activePage); + JavaStackTraceConsolePage page = null; + for (IViewReference vref : activePage.getViewReferences()) { + IViewPart view = vref.getView(false); + if (view instanceof ConsoleView) { + ConsoleView consoleView = (ConsoleView) view; + if (consoleView.getConsole() == fConsole && consoleView.getCurrentPage() instanceof JavaStackTraceConsolePage) { + page = (JavaStackTraceConsolePage) consoleView.getCurrentPage(); + break; + } + } + } + assertNotNull(page); + return page.getViewer(); + } + + /** + * Simulate user pressing a key. + * + * @param widget + * widget to type in + * @param c + * character to type + */ + protected void doKeyStroke(StyledText widget, char c) { + final Event e = new Event(); + e.character = c; + widget.notifyListeners(SWT.KeyDown, e); + widget.notifyListeners(SWT.KeyUp, e); + } +} diff -Nru "/tmp/tmp8dmwkmqv/LbgC9U2ArA/eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/JavaDebugStackTraceConsoleTest.java" "/tmp/tmp8dmwkmqv/FpgNNFuc9e/eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/JavaDebugStackTraceConsoleTest.java" --- "/tmp/tmp8dmwkmqv/LbgC9U2ArA/eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/JavaDebugStackTraceConsoleTest.java" 1970-01-01 00:00:00.000000000 +0000 +++ "/tmp/tmp8dmwkmqv/FpgNNFuc9e/eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/JavaDebugStackTraceConsoleTest.java" 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,242 @@ +/******************************************************************************* + * Copyright (c) 2014, 2020 SAP SE and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * SAP SE - initial API and implementation + * Paul Pazderski - Bug 546900: Tests to check initial console content and content persistence + * Paul Pazderski - Bug 343023: Tests for 'clear initial content on first edit' + * Paul Pazderski - Bug 304219: Tests for formatting + *******************************************************************************/ +package org.eclipse.jdt.debug.tests.console; + +import static org.junit.Assert.assertArrayEquals; + +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.debug.testplugin.JavaProjectHelper; +import org.eclipse.jdt.debug.tests.TestUtil; +import org.eclipse.jdt.internal.debug.ui.console.JavaDebugStackTraceConsoleTracker; +import org.eclipse.jdt.internal.debug.ui.console.JavaDebugStackTraceHyperlink; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.jface.text.Position; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.console.IHyperlink; +import org.eclipse.ui.texteditor.ITextEditor; + +/** + * Tests for hyper-links added for stack traces copied from the {@code Debug} view. See {@link JavaDebugStackTraceHyperlink} and + * {@link JavaDebugStackTraceConsoleTracker}. + */ +public class JavaDebugStackTraceConsoleTest extends AbstractJavaStackTraceConsoleTest { + + public JavaDebugStackTraceConsoleTest(String name) { + super(name); + } + + public void testLinkNavigation() throws Exception { + String projectName = JavaDebugStackTraceConsoleTest.class.getSimpleName(); + IJavaProject project = createProject(projectName, "testfiles/source/", JavaProjectHelper.JAVA_SE_1_8_EE_NAME, true); + waitForBuild(); + waitForJobs(); + + consoleDocumentWithText("SomeClass.someMethod() line: 26"); + + IHyperlink[] hyperlinks = fConsole.getHyperlinks(); + assertEquals("Wrong hyperlinks, listing all links: " + allLinks(), + 2, hyperlinks.length); + + String expectedText = "\t\tsomeField = new Vector();"; + try { + for (IHyperlink hyperlink : hyperlinks) { + closeAllEditors(); + hyperlink.linkActivated(); + IEditorPart editor = waitForEditorOpen(); + String[] selectedText = new String[1]; + sync(() -> selectedText[0] = getSelectedText(editor)); + assertEquals("Wrong text selected after hyperlink navigation", expectedText, selectedText[0]); + } + } finally { + closeAllEditors(); + boolean force = true; + project.getProject().delete(force, new NullProgressMonitor()); + } + } + + public void testNotAvailableLineLocation() throws Exception { + consoleDocumentWithText("SomeClass.someMethod() line: not available [native method]"); + + assertArrayEquals("Wrong hyperlinks", new Position[0], allLinkPositions()); + } + + public void testInvalidLineLocation() throws Exception { + consoleDocumentWithText("SomeClass.someMethod() line: a1"); + + assertArrayEquals("Wrong hyperlinks", new Position[0], allLinkPositions()); + } + + public void testHyperlink() throws Exception { + consoleDocumentWithText("SomeClass.someMethod() line: 11"); + + String[] matchTexts = linkTextsAtPositions(0, 24); + assertArrayEquals("Wrong hyperlinks, listing all links: " + allLinks(), + new String[] { "SomeClass", "line: 11" }, matchTexts); + } + + public void testEmptySpaces() throws Exception { + consoleDocumentWithText("\t \t SomeClass.someMethod() line: 11 \t\t "); + + String[] matchTexts = linkTextsAtPositions(4, 28); + assertArrayEquals("Wrong hyperlinks, listing all links: " + allLinks(), + new String[] { "SomeClass", "line: 11" }, matchTexts); + } + + public void testInnerClass() throws Exception { + consoleDocumentWithText("SomeClass$5.someMethod() line: 1155"); + + String[] matchTexts = linkTextsAtPositions(0, 26); + assertArrayEquals("Wrong hyperlinks, listing all links: " + allLinks(), + new String[] { "SomeClass", "line: 1155" }, matchTexts); + + + consoleDocumentWithText("SomeClass2$Inner1$Inner2.someMethod() line: 1256"); + + matchTexts = linkTextsAtPositions(0, 39); + assertArrayEquals("Wrong hyperlinks, listing all links: " + allLinks(), + new String[] { "SomeClass2", "line: 1256" }, matchTexts); + } + + public void testSubtype() throws Exception { + consoleDocumentWithText("Subtype(Type).someMethod() line: 999"); + + String[] matchTexts = linkTextsAtPositions(9, 28); + assertArrayEquals("Wrong hyperlinks, listing all links: " + allLinks(), + new String[] { "Type", "line: 999" }, matchTexts); + } + + public void testQualifiedClass() throws Exception { + consoleDocumentWithText("somewhere1.somewhere2.SomeClass.someMethod() line: 123"); + + String[] matchTexts = linkTextsAtPositions(0, 46); + assertArrayEquals("Wrong hyperlinks, listing all links: " + allLinks(), + new String[] { "somewhere1.somewhere2.SomeClass", "line: 123" }, matchTexts); + } + + public void testParameterizedClass() throws Exception { + consoleDocumentWithText("SomeClass.someMethod() line: 504"); + + String[] matchTexts = linkTextsAtPositions(0, 34); + assertArrayEquals("Wrong hyperlinks, listing all links: " + allLinks(), + new String[] { "SomeClass", "line: 504" }, matchTexts); + } + + public void testParameterizedSuperType() throws Exception { + consoleDocumentWithText("Subtype(Type).someMethod() line: 704"); + + String[] matchTexts = linkTextsAtPositions(12, 34); + assertArrayEquals("Wrong hyperlinks, listing all links: " + allLinks(), + new String[] { "Type", "line: 704" }, matchTexts); + } + + public void testMultipleTypeParameters() throws Exception { + consoleDocumentWithText("ReferencePipeline$Head.forEach(Consumer) line: 658"); + + String[] matchTexts = linkTextsAtPositions(0, 69); + assertArrayEquals("Wrong hyperlinks, listing all links: " + allLinks(), new String[] { "ReferencePipeline", "line: 658" }, matchTexts); + } + + public void testMethodParameters() throws Exception { + consoleDocumentWithText("Some3Class.someMethod(SomeType[]) line: 301"); + + String[] matchTexts = linkTextsAtPositions(0, 36); + assertArrayEquals("Wrong hyperlinks, listing all links: " + allLinks(), + new String[] { "Some3Class", "line: 301" }, matchTexts); + + + consoleDocumentWithText("SomeClass55.someMethod(Type1, SomeType2...) line: 111"); + + matchTexts = linkTextsAtPositions(0, 45); + assertArrayEquals("Wrong hyperlinks, listing all links: " + allLinks(), + new String[] { "SomeClass55", "line: 111" }, matchTexts); + + + consoleDocumentWithText("Some1Class101.someMethod(Type1, SomeType2) line: 1"); + + matchTexts = linkTextsAtPositions(0, 52); + assertArrayEquals("Wrong hyperlinks, listing all links: " + allLinks(), + new String[] { "Some1Class101", "line: 1" }, matchTexts); + + + consoleDocumentWithText("Some1101Class101.someMethod(Type1, SomeType2) line: 12"); + + matchTexts = linkTextsAtPositions(0, 53); + assertArrayEquals("Wrong hyperlinks, listing all links: " + allLinks(), + new String[] { "Some1101Class101", "line: 12" }, matchTexts); + } + + public void testMixedCases() throws Exception { + consoleDocumentWithText("org.somewhere.Some3Class.someMethod(org.eclipse.SomeType) line: 3011\t"); + + String[] matchTexts = linkTextsAtPositions(0, 62); + assertArrayEquals("Wrong hyperlinks, listing all links: " + allLinks(), + new String[] { "org.somewhere.Some3Class", "line: 3011" }, matchTexts); + + + consoleDocumentWithText(" org.SomeClass55(org.eclipse.SuperClass).myMethod(org.Type1, com.SomeType2...) line: 10 "); + + matchTexts = linkTextsAtPositions(19, 96); + assertArrayEquals("Wrong hyperlinks, listing all links: " + allLinks(), + new String[] { "org.eclipse.SuperClass", "line: 10" }, matchTexts); + + + consoleDocumentWithText("\torg.MyType(somewhere1.somewhere2.Some1Class101$org.Type).toString(java.lang.String[], int) line: 2 "); + + matchTexts = linkTextsAtPositions(13, 110); + assertArrayEquals("Wrong hyperlinks, listing all links: " + allLinks(), + new String[] { "somewhere1.somewhere2.Some1Class101", "line: 2" }, matchTexts); + + + consoleDocumentWithText(" org.MyType2(somewhere1.somewhere2.Some1Class105$org.Type$com.InnerType).toString(java.lang.List, byte, long,double) line: 5 "); + + matchTexts = linkTextsAtPositions(14, 159); + assertArrayEquals("Wrong hyperlinks, listing all links: " + allLinks(), + new String[] { "somewhere1.somewhere2.Some1Class105", "line: 5" }, matchTexts); + } + + private static String getSelectedText(IEditorPart editor) { + ITextEditor textEditor = (ITextEditor) editor; + ISelectionProvider selectionProvider = textEditor.getSelectionProvider(); + ISelection selection = selectionProvider.getSelection(); + ITextSelection textSelection = (ITextSelection) selection; + String selectedText = textSelection.getText(); + return selectedText; + } + + private IEditorPart waitForEditorOpen() throws Exception { + waitForJobs(); + IEditorPart[] editor = new IEditorPart[1]; + sync(() -> editor[0] = getActivePage().getActiveEditor()); + long timeout = 30_000; + long start = System.currentTimeMillis(); + while (editor[0] == null && System.currentTimeMillis() - start < timeout) { + waitForJobs(); + sync(() -> editor[0] = getActivePage().getActiveEditor()); + } + if (editor[0] == null) { + throw new AssertionError("Timeout occurred while waiting for editor to open"); + } + return editor[0]; + } + + private void waitForJobs() throws Exception { + TestUtil.waitForJobs(getName(), 250, 10_000); + } +} diff -Nru "/tmp/tmp8dmwkmqv/LbgC9U2ArA/eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/JavaStackTraceConsoleTest.java" "/tmp/tmp8dmwkmqv/FpgNNFuc9e/eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/JavaStackTraceConsoleTest.java" --- "/tmp/tmp8dmwkmqv/LbgC9U2ArA/eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/JavaStackTraceConsoleTest.java" 2022-03-01 05:51:47.000000000 +0000 +++ "/tmp/tmp8dmwkmqv/FpgNNFuc9e/eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/console tests/org/eclipse/jdt/debug/tests/console/JavaStackTraceConsoleTest.java" 2022-11-07 18:51:46.000000000 +0000 @@ -19,126 +19,26 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertNotEquals; -import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.jdt.debug.tests.AbstractDebugTest; -import org.eclipse.jdt.debug.tests.TestUtil; -import org.eclipse.jdt.debug.ui.console.JavaStackTraceConsoleFactory; -import org.eclipse.jdt.internal.debug.ui.console.ConsoleMessages; + import org.eclipse.jdt.internal.debug.ui.console.JavaStackTraceConsole; -import org.eclipse.jdt.internal.debug.ui.console.JavaStackTraceConsolePage; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.BadPositionCategoryException; import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.Position; -import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ST; -import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.widgets.Event; -import org.eclipse.ui.IViewPart; -import org.eclipse.ui.IViewReference; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.console.ConsolePlugin; -import org.eclipse.ui.console.IConsole; -import org.eclipse.ui.console.IConsoleManager; import org.eclipse.ui.console.TextConsoleViewer; -import org.eclipse.ui.internal.console.ConsoleHyperlinkPosition; -import org.eclipse.ui.internal.console.ConsoleView; /** * Tests {@link JavaStackTraceConsole} */ -public class JavaStackTraceConsoleTest extends AbstractDebugTest { - - private final static Pattern LEFT_INDENT = Pattern.compile("^[ \\t]*"); - private final static Pattern RIGHT_INDENT = Pattern.compile("\\s+$"); - - private final JavaStackTraceConsoleFactory fConsoleFactory = new JavaStackTraceConsoleFactory(); - private JavaStackTraceConsole fConsole; +public class JavaStackTraceConsoleTest extends AbstractJavaStackTraceConsoleTest { public JavaStackTraceConsoleTest(String name) { super(name); } - @Override - public void setUp() throws Exception { - super.setUp(); - initConsole(true); - } - - @Override - protected void tearDown() throws Exception { - removeConsole(false); - super.tearDown(); - } - - /** - * Create and register a {@link JavaStackTraceConsole}. - * - * @param assertDefaultContent - * If true assert console is initialized with its default content. - * @see #removeConsole(boolean) - */ - private void initConsole(boolean assertDefaultContent) { - fConsoleFactory.openConsole(); - IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager(); - IConsole[] consoles = consoleManager.getConsoles(); - fConsole = null; - for (IConsole console : consoles) { - if (console instanceof JavaStackTraceConsole) { - fConsole = (JavaStackTraceConsole) console; - // do not end loop. There should be only one JavaStackTraceConsole but if there are more - // the last one is most likely the one we opened - } - } - assertNotNull("Failed to open a JavaStackTraceConsole", fConsole); - if (assertDefaultContent) { - assertInitialContent(); - } - } - - /** - * Remove the previous created console. - * - * @param preserveContent - * If true the remove does not prevent the current console content from being loaded by next - * {@link JavaStackTraceConsole}. - * @see #initConsole(boolean) - */ - private void removeConsole(boolean preserveContent) { - if (!preserveContent) { - fConsole.clearConsole(); - } - final int contentLength = fConsole.getDocument().getLength(); - - IConsoleManager consoleManager = ConsolePlugin.getDefault().getConsoleManager(); - consoleManager.removeConsoles(new IConsole[] { fConsole }); - - final Path stackTraceFile = Paths.get(JavaStackTraceConsole.FILE_NAME); - if (!preserveContent) { - assertTrue("Leaked content of JavaStackTraceConsole", Files.notExists(stackTraceFile)); - } else { - assertTrue("JavaStackTraceConsole content was not persisted", Files.exists(stackTraceFile)); - try { - assertTrue("Persisted content seems incomplete", Files.size(stackTraceFile) >= contentLength); - } catch (IOException e) { - fail("Persisted content seems incomplete"); - } - } - } - public void testHyperlinkMatchSignatureSimple() throws Exception { consoleDocumentWithText("at foo.bar.Type.method1(Type.java:1)"); @@ -169,7 +69,7 @@ } public void testHyperlinkNoMatch() throws Exception { - consoleDocumentWithText("at foo.bar.Type.method1(foo.bar.Type.java:42)"); + consoleDocumentWithText("at foo.bar.Type.method1(foo.bar#.Type.java:42)"); Position[] positions = allLinkPositions(); assertArrayEquals("Expected no hyperlinks for invalid type name", new Position[0], positions); @@ -193,13 +93,13 @@ IDocument initialDocument = fConsole.getDocument(); String storedContent = "at foo.bar.Type.method1(Type.java:fff)"; consoleDocumentWithText(storedContent); - removeConsole(true); + sync(() -> removeConsole(true)); Path file = Paths.get(JavaStackTraceConsole.FILE_NAME); assertTrue("Content was not stored.", Files.exists(file)); assertTrue("Content was not stored.", Files.size(file) > 0); - initConsole(false); + sync(() -> initConsole(false)); assertNotSame("Failed to create new console.", initialDocument, fConsole.getDocument()); assertEquals("Failed to restore previous content.", storedContent, fConsole.getDocument().get()); } @@ -289,7 +189,7 @@ } /** Test formatting of a plain simple stack trace. */ - public void testFormatSimple() { + public void testFormatSimple() throws Exception { IDocument doc = consoleDocumentFormatted("java.lang.AssertionError: expected:5 but was:7\n\n" + "at org.junit.Ass\nert.fail(Assert.java:88) \n" + "at\norg.junit. \nAssert.failNotEquals(Assert.java:834)\n" + "at org.junit.Assert.assertEquals(Assert.java:118)\n" + "at \norg.junit.Assert.assertEquals\n(Assert.java:144)"); @@ -302,7 +202,7 @@ } /** Test formatting of a stack trace including thread name. */ - public void testFormatThreadName() { + public void testFormatThreadName() throws Exception { IDocument doc = consoleDocumentFormatted("Exception in thread \"ma\nin\" java.lang.NullPointerException\n" + "at \nStacktrace.main(Stacktrace.java:4)"); assertEquals("Exception in thread \"main\" java.lang.NullPointerException", getLine(doc, 0)); @@ -311,7 +211,7 @@ } /** Test formatting with some less common method names. */ - public void testFormatUncommonMethods() { + public void testFormatUncommonMethods() throws Exception { IDocument doc = consoleDocumentFormatted("Stack Trace\n" + " at org.eclipse.core.runtime.SafeRunner.run\n(SafeRunner.java:43)\n" + " at org.eclipse.ui.internal.JFaceUtil.lambda$0(JFaceUtil.java:47)\n" + " at org.eclipse.ui.internal.JFaceUtil$$Lambda$107/0x00000 \n008013c5c40.run(Unknown Source)\n" @@ -329,7 +229,7 @@ } /** Test formatting with a 'locked' entry. */ - public void testFormatLocked() { + public void testFormatLocked() throws Exception { IDocument doc = consoleDocumentFormatted("java.lang.Thread.State: RUNNABLE\n" + " at java.net.PlainSocketImpl.socketAccept(Native Method)\n\n\n" + "at java.net.PlainSocketImpl\n.accept(PlainSocketImpl.java:408)\n" + "\t - locked <0x911d3c30> (a java.net.SocksSocketImpl)\n" @@ -344,7 +244,7 @@ } /** Test formatting with a ... more entry. */ - public void testFormatMore() { + public void testFormatMore() throws Exception { // additional this one is missing the 'header' line and starting with an 'at' line IDocument doc = consoleDocumentFormatted(" at org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager.preparePersistenceUnitInfos(DefaultPersistenceUnitManager.java:470)\n" + " at org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager.afterPropertiesSet(DefaultPersistenceUnitManager.java:424)\n" @@ -364,7 +264,7 @@ } /** Test formatting stack trace with cause. */ - public void testFormatCause() { + public void testFormatCause() throws Exception { IDocument doc = consoleDocumentFormatted("HighLevelException:\n LowLevelException\n" + "\tat Junk.a(Junk.java:13)\n" + " at Junk.main(Junk.java:4)\n" + " Caused by: LowLevelException\n" + " at Junk.e(Junk.java:30)\n" + " at Junk.d\n(Junk.java:27)\n" + "at Junk.c(Junk.java:21)"); @@ -399,7 +299,7 @@ } /** Test formatting stack trace with suppressed exceptions. */ - public void testFormatSuppressed() { + public void testFormatSuppressed() throws Exception { IDocument doc = consoleDocumentFormatted("Exception in thread \"main\" java.lang.Exception: Something happened\n" + "at Foo.bar(Native)\n" + " at Foo.main(Foo.java:5)\n" + " Suppressed: Resource$CloseFailException: Resource ID = 0\n" + " at Resource.close(Resource\n.java:26)\n" + " at Foo.bar(Foo.java)\n" + " ... 1 more\n" + ""); @@ -429,7 +329,7 @@ } /** Test formatting stack trace with mixture of cause and suppressed. */ - public void testFormatSuppressedWithCause() { + public void testFormatSuppressedWithCause() throws Exception { // exception with suppressed and cause IDocument doc = consoleDocumentFormatted("Exception in thread \"main\" java.lang.Exception: Main block\n" + " at Foo3.main(Foo3.java:7)\n" + " Suppressed: Resource$CloseFailException: Resource ID = 1\n" + " at Resource.close(Resource.java:26)\n" @@ -473,7 +373,7 @@ } /** Test formatting the rare [CIRCULAR REFERENCE:...] entry. */ - public void testFormatCircular() { + public void testFormatCircular() throws Exception { IDocument doc = consoleDocumentFormatted("Exception in thread \"main\" Stacktrace$BadException\n" + "at Stacktrace.main\n(Stacktrace.java:4)\n" + " Caused by: Stacktrace$BadExceptionCompanion: Stacktrace$BadException\n" + " at Stacktrace$BadException.(Stacktrace.java:10)\n" + " ... 1 more\n" @@ -488,7 +388,7 @@ } /** Test formatting stack trace from an ant execution. (output mixed with ant prefixes) */ - public void testFormatAnt() { + public void testFormatAnt() throws Exception { IDocument doc = consoleDocumentFormatted("[java] !ENTRY org.eclipse.debug.core 4 120 2005-01-11 03:02:30.321\n" + " [java] !MESSAGE An exception occurred while dispatching debug events.\n" + " [java] !STACK 0\n" + " [java] java.lang.NullPointerException\n" + " [java] at \n" @@ -505,181 +405,10 @@ checkIndentationConsistency(doc, 3); } - private IDocument consoleDocumentWithText(String text) throws InterruptedException { - IDocument document = fConsole.getDocument(); - document.set(text); - // wait for document being parsed and hyperlinks created - Job.getJobManager().join(fConsole, null); - return document; - } - - private String getLine(IDocument doc, int line) { - IRegion lineInfo; - try { - lineInfo = doc.getLineInformation(line); - return doc.get(lineInfo.getOffset(), lineInfo.getLength()); - } catch (BadLocationException ex) { - return null; - } - } - - /** - * Do some tests on the stack trace indentation. No hardcoded valued just some general assumptions. - * - * @param doc - * document to test - * @param startLine - * first line to check - */ - private void checkIndentationConsistency(IDocument doc, int startLine) { - boolean firstSuppress = true; - int lastIndent = -1; - // Remember how the next line's indentation can differ from the previous. - // -1 -> less indented - // 0 -> equal - // 1 -> more indented - int allowedIndentChange = 1; - for (int i = startLine, lineCount = doc.getNumberOfLines(); i < lineCount; i++) { - String line = getLine(doc, i); - line = line.replaceFirst("^\\[[^\\s\\]]+\\] ", ""); // remove and prefix if any - if (i != 0) { // first line can be empty - assertNotEquals("Empty line " + i, "", line); - } - assertFalse("Trailing whitespace in line " + i, RIGHT_INDENT.matcher(line).find()); - - boolean causedBy = line.trim().startsWith("Caused by: "); - boolean suppressed = line.trim().startsWith("Suppressed: "); - if (causedBy || (suppressed && !firstSuppress)) { - allowedIndentChange = -1; - } - - int lineIndent = getLineIndentation(line); - if (allowedIndentChange < 0) { - assertTrue("Wrong indented line " + i + ": " + lastIndent + " > " + lineIndent, lastIndent > lineIndent); - } else if (allowedIndentChange == 0) { - assertEquals("Mixed indentation in line " + i, lastIndent, lineIndent); - } else if (allowedIndentChange > 0) { - assertTrue("Wrong indented line " + i + ": " + lastIndent + " < " + lineIndent, lastIndent < lineIndent); - } - lastIndent = lineIndent; - allowedIndentChange = 0; - if (causedBy || suppressed || i == startLine) { - allowedIndentChange = 1; - } - firstSuppress &= !suppressed; - } - } - - private int getLineIndentation(String line) { - int tabSize = 4; - String indent = ""; - Matcher m = LEFT_INDENT.matcher(line); - if (m.find()) { - indent = m.group(); - } - int tabCount = indent.length() - indent.replace("\t", "").length(); - return indent.length() + (tabSize - 1) * tabCount; - } - - /** - * Set given text, invoke formatting and wait until finished. - * - * @param text - * new console text - * @return the consoles document - */ - private IDocument consoleDocumentFormatted(String text) { - IDocument document = fConsole.getDocument(); - document.set(text); - fConsole.format(); - // wait for document being formatted - TestUtil.waitForJobs(getName(), 30, 1000); - return document; - } - - private String[] linkTextsAtPositions(int... offsets) throws BadLocationException { - IDocument document = fConsole.getDocument(); - - List texts = new ArrayList<>(offsets.length); - List positions = linkPositions(offsets); - for (Position pos : positions) { - String matchText = document.get(pos.getOffset(), pos.getLength()); - texts.add(matchText); - } - return texts.toArray(new String[texts.size()]); - } - - private List linkPositions(int... offsets) { - List filteredPositions = new ArrayList<>(offsets.length); - for (Position position : allLinkPositions()) { - for (int offset : offsets) { - if (offset >= position.getOffset() && offset <= (position.getOffset() + position.getLength())) { - filteredPositions.add(position); - break; - } - } - } - return filteredPositions; - } - - private Position[] allLinkPositions() { - try { - return fConsole.getDocument().getPositions(ConsoleHyperlinkPosition.HYPER_LINK_CATEGORY); - } catch (BadPositionCategoryException ex) { - // no hyperlinks - } - return new Position[0]; - } - - private String allLinks() { - return Arrays.toString(allLinkPositions()); - } - - /** - * Check if initial content is shown. - */ - public void assertInitialContent() { - assertEquals("Console not loaded with initial content.", ConsoleMessages.JavaStackTraceConsole_0, fConsole.getDocument().get()); - } + public void testHyperlinkMatchWithModule() throws Exception { + consoleDocumentWithText("at java.nio.charset.Charset.checkName(java.base/Charset.java:296)"); - /** - * Tries to get the viewer of the currently tested console. - * - * @return the consoles viewer - */ - private TextConsoleViewer getConsolesViewer() { - TestUtil.waitForJobs(getName(), 100, DEFAULT_TIMEOUT); - IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - assertNotNull(workbenchWindow); - IWorkbenchPage activePage = workbenchWindow.getActivePage(); - assertNotNull(activePage); - JavaStackTraceConsolePage page = null; - for (IViewReference vref : activePage.getViewReferences()) { - IViewPart view = vref.getView(false); - if (view instanceof ConsoleView) { - ConsoleView consoleView = (ConsoleView) view; - if (consoleView.getConsole() == fConsole && consoleView.getCurrentPage() instanceof JavaStackTraceConsolePage) { - page = (JavaStackTraceConsolePage) consoleView.getCurrentPage(); - break; - } - } - } - assertNotNull(page); - return page.getViewer(); - } - - /** - * Simulate user pressing a key. - * - * @param widget - * widget to type in - * @param c - * character to type - */ - private void doKeyStroke(StyledText widget, char c) { - final Event e = new Event(); - e.character = c; - widget.notifyListeners(SWT.KeyDown, e); - widget.notifyListeners(SWT.KeyUp, e); + String[] matchTexts = linkTextsAtPositions(38); + assertArrayEquals(allLinks(), new String[] { "java.base/Charset.java:296" }, matchTexts); } } diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaInAnonymous.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaInAnonymous.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaInAnonymous.java 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaInAnonymous.java 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,21 @@ +import java.util.Arrays; +import java.util.List; + +public class Bug578145LambdaInAnonymous { + + public static void main(String[] args) { + int numberInMain = 1; + + new Runnable() { + @Override + public void run() { + List usersInAnonymous = Arrays.asList("Lambda"); + + usersInAnonymous.stream().forEach(u -> { + int numberInLambda = 10; + System.out.println("user name: " + u); // Add a breakpoint here + }); + } + }.run(); + } +} diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaInConstructor.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaInConstructor.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaInConstructor.java 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaInConstructor.java 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,20 @@ +import java.util.Arrays; +import java.util.List; + +public class Bug578145LambdaInConstructor { + List names; + + public Bug578145LambdaInConstructor(List originalNames) { + this.names = originalNames; + int localInConstructor = 1; + + this.names.stream().forEach((name) -> { + int localInLambda = 10; + System.out.println(name); // Add breakpoint here + }); + } + + public static void main(String[] args) { + Bug578145LambdaInConstructor instance = new Bug578145LambdaInConstructor(Arrays.asList("Lambda")); + } +} diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaInFieldDeclaration.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaInFieldDeclaration.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaInFieldDeclaration.java 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaInFieldDeclaration.java 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,21 @@ +import java.util.function.Consumer; + +public class Bug578145LambdaInFieldDeclaration { + Runnable runnable = new Runnable() { + @Override + public void run() { + int numberInRunnable = 1; + + Consumer myConsumer = (lambdaArg) -> { + int numberInLambda = 10; + System.out.println("id = " + lambdaArg); // Add breakpoint here + }; + myConsumer.accept(numberInRunnable); + } + }; + + public static void main(String[] args) { + Bug578145LambdaInFieldDeclaration instance = new Bug578145LambdaInFieldDeclaration(); + instance.runnable.run(); + } +} diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaInStaticInitializer.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaInStaticInitializer.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaInStaticInitializer.java 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaInStaticInitializer.java 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,19 @@ +import java.util.Arrays; +import java.util.List; + +public class Bug578145LambdaInStaticInitializer { + + static { + int numberInStaticInitializer = 1; + List staticList = Arrays.asList("Lambda"); + + staticList.stream().forEach((name) -> { + int numberInLambda = 10; + System.out.println(name); // Add breakpoint here + }); + } + + public static void main(String[] args) { + Bug578145LambdaInStaticInitializer instance = new Bug578145LambdaInStaticInitializer(); + } +} diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaOnChainCalls.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaOnChainCalls.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaOnChainCalls.java 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/java8/Bug578145LambdaOnChainCalls.java 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,14 @@ +import java.util.Arrays; +import java.util.List; + +public class Bug578145LambdaOnChainCalls { + public static void main(String[] args) { + int numberInMain = 1; + List users = Arrays.asList("Lambda"); + + users.stream().forEach(u -> { + int numberInLambda = 10; + System.out.println("user name: " + u); // Add a breakpoint here + }); + } +} diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/java8/Bug578145NestedLambda.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/java8/Bug578145NestedLambda.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/java8/Bug578145NestedLambda.java 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/java8/Bug578145NestedLambda.java 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,21 @@ +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; + +public class Bug578145NestedLambda { + + public static void main(String[] args) { + int numberInMain = 1; + + Consumer myConsumer = (id) -> { + int numberInExternalLambda = 10; + + List users = Arrays.asList("Lambda"); + users.stream().forEach(u -> { + int numberInInnerLambda = 100; + System.out.println("user name: " + u); // Add a breakpoint here + }); + }; + myConsumer.accept(numberInMain); + } +} diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/java8/LambdaBreakpoints1.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/java8/LambdaBreakpoints1.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/java8/LambdaBreakpoints1.java 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/java8/LambdaBreakpoints1.java 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,36 @@ +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class LambdaBreakpoints1 { + public static void main(String[] args) throws Exception { + ExecutorService executor = Executors.newSingleThreadExecutor(); + StringBuilder s = new StringBuilder(); + CompletableFuture f = CompletableFuture.completedFuture("0"); + f = f.thenApply((x) -> { + s.append(x).append("1"); + return s.toString(); // breakpoint 1 + }) + .thenApply(x -> + s.append("2") // breakpoint 2 + ) + .thenRun(() -> lastCall(s)) + .thenRunAsync(() -> {}, executor); + executor.shutdown(); + f.get(); + String result = s.toString(); + System.out.println(result); // breakpoint 4 + } + + private static void lastCall(StringBuilder b) { + b.append(C.s()); + } + + static class C { + static String s() { + if (Boolean.valueOf("true")) // breakpoint 3 + return "3"; // <--- breakpoint 3 should not be here + return "???"; + } + } +} diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/META-INF/MANIFEST.MF 2022-11-07 18:51:46.000000000 +0000 @@ -2,7 +2,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jdt.debug.tests; singleton:=true -Bundle-Version: 3.11.1600.qualifier +Bundle-Version: 3.11.1850.qualifier Bundle-ClassPath: javadebugtests.jar Bundle-Activator: org.eclipse.jdt.debug.testplugin.JavaTestPlugin Bundle-Vendor: %providerName diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/pom.xml eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/pom.xml --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/pom.xml 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/pom.xml 2022-11-07 18:51:46.000000000 +0000 @@ -1,11 +1,10 @@ @@ -47,4 +47,32 @@ + + + test-on-javase-19 + + + + org.apache.maven.plugins + maven-toolchains-plugin + + + validate + + toolchain + + + + + + + JavaSE-19 + + + + + + + + diff -Nru "/tmp/tmp8dmwkmqv/LbgC9U2ArA/eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaProjectHelper.java" "/tmp/tmp8dmwkmqv/FpgNNFuc9e/eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaProjectHelper.java" --- "/tmp/tmp8dmwkmqv/LbgC9U2ArA/eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaProjectHelper.java" 2022-03-01 05:51:47.000000000 +0000 +++ "/tmp/tmp8dmwkmqv/FpgNNFuc9e/eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/test plugin/org/eclipse/jdt/debug/testplugin/JavaProjectHelper.java" 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -153,6 +153,15 @@ } /** + * Returns if the currently running VM is version compatible with Java 19 + * + * @return true if a Java 19 (or greater) VM is running false otherwise + */ + public static boolean isJava19_Compatible() { + return isCompatible(19); + } + + /** * Returns if the current running system is compatible with the given Java minor version * * @param ver the version to test - either 4, 5, 6, 7 or 8 diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/testprograms/SuspendVMConditionalBreakpointsTestSnippet.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/testprograms/SuspendVMConditionalBreakpointsTestSnippet.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/testprograms/SuspendVMConditionalBreakpointsTestSnippet.java 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/testprograms/SuspendVMConditionalBreakpointsTestSnippet.java 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2022 Simeon Andreev and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Simeon Andreev - initial API and implementation + *******************************************************************************/ + +/** + * Snippet for: Bug 575131 - Deadlock during "JDI Expression Evaluation Event Dispatch" + */ +public class SuspendVMConditionalBreakpointsTestSnippet { + + public static final int i = 50; + public static final int j = 25; + + public static void main(String[] args) throws InterruptedException { + Thread t1 = new Thread(new Runnable() { + @Override + public void run() { + for (int k = 0; k < 5; ++k) { + System.out.println("thread i=" + i); // suspend VM breakpoint with condition "if (i == 50) { System.out.println(i); } return false;" + } + } + }); + Thread t2 = new Thread(new Runnable() { + @Override + public void run() { + for (int k = 0; k < 5; ++k) { + System.out.println("thread j=" + j); // suspend VM breakpoint with condition "if (j == 25) { System.out.println(j); } return false;" + } + } + }); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + } +} diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugPerformanceTest.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugPerformanceTest.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugPerformanceTest.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugPerformanceTest.java 2022-11-07 18:51:46.000000000 +0000 @@ -13,14 +13,16 @@ *******************************************************************************/ package org.eclipse.jdt.debug.tests; +import org.eclipse.jdt.debug.tests.ui.AbstractDebugUiTests; import org.eclipse.test.performance.Dimension; import org.eclipse.test.performance.Performance; import org.eclipse.test.performance.PerformanceMeter; +import org.eclipse.test.performance.PerformanceTestCase; /** * An abstract implementation of a debug performance test */ -public class AbstractDebugPerformanceTest extends AbstractDebugTest { +public class AbstractDebugPerformanceTest extends AbstractDebugUiTests { protected PerformanceMeter fPerformanceMeter; diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -33,7 +33,6 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IMarker; -import org.eclipse.core.resources.IMarkerDelta; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IncrementalProjectBuilder; @@ -42,6 +41,7 @@ import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; @@ -52,7 +52,6 @@ import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; -import org.eclipse.debug.core.IBreakpointListener; import org.eclipse.debug.core.IBreakpointManager; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; @@ -82,10 +81,8 @@ import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugModelPresentation; import org.eclipse.debug.ui.IDebugUIConstants; -import org.eclipse.debug.ui.IDebugView; import org.eclipse.debug.ui.ILaunchConfigurationDialog; import org.eclipse.debug.ui.ILaunchConfigurationTabGroup; -import org.eclipse.debug.ui.actions.ToggleBreakpointAction; import org.eclipse.jdt.core.IAccessRule; import org.eclipse.jdt.core.IBuffer; import org.eclipse.jdt.core.IClassFile; @@ -148,24 +145,18 @@ import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.Position; -import org.eclipse.jface.text.source.IVerticalRulerInfo; import org.eclipse.jface.util.SafeRunnable; import org.eclipse.swt.widgets.Display; -import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.console.IConsole; import org.eclipse.ui.console.IHyperlink; import org.eclipse.ui.console.TextConsole; -import org.eclipse.ui.ide.IDE; import org.eclipse.ui.internal.console.ConsoleHyperlinkPosition; import org.eclipse.ui.intro.IIntroManager; import org.eclipse.ui.intro.IIntroPart; import org.eclipse.ui.progress.UIJob; -import org.eclipse.ui.progress.WorkbenchJob; import org.osgi.service.prefs.BackingStoreException; import com.sun.jdi.InternalException; @@ -207,7 +198,8 @@ "org.eclipse.debug.tests.targets.HcrClass9", "TestContributedStepFilterClass", "TerminateAll_01", "TerminateAll_02", "StepResult1", "StepResult2", "StepResult3", "StepUncaught", "TriggerPoint_01", "BulkThreadCreationTest", "MethodExitAndException", "Bug534319earlyStart", "Bug534319lateStart", "Bug534319singleThread", "Bug534319startBetwen", "MethodCall", "Bug538303", "Bug540243", - "OutSync", "OutSync2", "ConsoleOutputUmlaut", "ErrorRecurrence", "ModelPresentationTests", "Bug565982" }; + "OutSync", "OutSync2", "ConsoleOutputUmlaut", "ErrorRecurrence", "ModelPresentationTests", "Bug565982", + "SuspendVMConditionalBreakpointsTestSnippet" }; /** * the default timeout @@ -501,6 +493,13 @@ cfgs.add(createLaunchConfiguration(jp, "Bug571310")); cfgs.add(createLaunchConfiguration(jp, "Bug573547")); cfgs.add(createLaunchConfiguration(jp, "Bug575551")); + cfgs.add(createLaunchConfiguration(jp, "Bug578145NestedLambda")); + cfgs.add(createLaunchConfiguration(jp, "Bug578145LambdaInConstructor")); + cfgs.add(createLaunchConfiguration(jp, "Bug578145LambdaInFieldDeclaration")); + cfgs.add(createLaunchConfiguration(jp, "Bug578145LambdaInStaticInitializer")); + cfgs.add(createLaunchConfiguration(jp, "Bug578145LambdaInAnonymous")); + cfgs.add(createLaunchConfiguration(jp, "Bug578145LambdaOnChainCalls")); + cfgs.add(createLaunchConfiguration(jp, "LambdaBreakpoints1")); loaded18 = true; waitForBuild(); } @@ -1212,6 +1211,12 @@ } setEventSet(waiter.getEventSet()); assertNotNull("Program did not suspend, launch terminated.", suspendee); //$NON-NLS-1$ + // Bug 575131: resuming and suspending threads on breakpoint hit is done in a job, wait for this job + try { + Job.getJobManager().join(JDIDebugTarget.class, new NullProgressMonitor()); + } catch (OperationCanceledException | InterruptedException e) { + throw new AssertionError("Failed ot wait for JDIDebugTarget jobs", e); + } return suspendee; } @@ -2533,7 +2538,7 @@ Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, null); Job.getJobManager().join(ResourcesPlugin.FAMILY_MANUAL_BUILD, null); // Let also all other pending jobs proceed, ignore console jobs - TestUtil.waitForJobs("waitForBuild", 100, 1000, ProcessConsole.class); + TestUtil.waitForJobs("waitForBuild", 100, 5000, ProcessConsole.class); wasInterrupted = false; } catch (OperationCanceledException e) { e.printStackTrace(); @@ -2706,151 +2711,6 @@ } /** - * Opens and returns an editor on the given file or null - * if none. The editor will be activated. - * - * @param file - * @return editor or null - */ - protected IEditorPart openEditor(final IFile file) throws PartInitException, InterruptedException { - Display display = DebugUIPlugin.getStandardDisplay(); - if (Thread.currentThread().equals(display.getThread())) { - IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - return IDE.openEditor(page, file, true); - } - final IEditorPart[] parts = new IEditorPart[1]; - WorkbenchJob job = new WorkbenchJob(display, "open editor") { - @Override - public IStatus runInUIThread(IProgressMonitor monitor) { - IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); - try { - parts[0] = IDE.openEditor(page, file, true); - } catch (PartInitException e) { - return e.getStatus(); - } - return Status.OK_STATUS; - } - }; - job.schedule(); - job.join(); - return parts[0]; - } - - /** - * Opens the {@link IDebugView} with the given id, does nothing if no such view exists. - * This method can return null - * - * @param viewId - * @return the handle to the {@link IDebugView} with the given id - * @throws PartInitException - * @throws InterruptedException - * @since 3.8.100 - */ - protected IDebugView openDebugView(final String viewId) throws PartInitException, InterruptedException { - if(viewId != null) { - Display display = DebugUIPlugin.getStandardDisplay(); - if (Thread.currentThread().equals(display.getThread())) { - return doShowDebugView(viewId); - } - final IDebugView[] view = new IDebugView[1]; - WorkbenchJob job = new WorkbenchJob("Showing the debug view: "+viewId) { - @Override - public IStatus runInUIThread(IProgressMonitor monitor) { - try { - view[0] = doShowDebugView(viewId); - } - catch(CoreException ce) { - return ce.getStatus(); - } - return Status.OK_STATUS; - } - }; - job.schedule(); - job.join(); - return view[0]; - } - return null; - } - - /** - * Opens a debug view - * @param viewId - * @return return the debug view handle or null - * @throws PartInitException - * @since 3.8.100 - */ - private IDebugView doShowDebugView(String viewId) throws PartInitException { - IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - if(window != null) { - IWorkbenchPage page = window.getActivePage(); - assertNotNull("We shold have found the active page to open the debug view in", page); - return (IDebugView) page.showView(viewId); - } - return null; - } - - /** - * Toggles a breakpoint in the editor at the given line number returning the breakpoint - * or null if none. - * - * @param editor - * @param lineNumber - * @return returns the created breakpoint or null if none. - * @throws InterruptedException - */ - protected IBreakpoint toggleBreakpoint(final IEditorPart editor, int lineNumber) throws InterruptedException { - final IVerticalRulerInfo info = new VerticalRulerInfoStub(lineNumber-1); // sub 1, as the doc lines start at 0 - WorkbenchJob job = new WorkbenchJob(DebugUIPlugin.getStandardDisplay(), "toggle breakpoint") { - @Override - public IStatus runInUIThread(IProgressMonitor monitor) { - ToggleBreakpointAction action = new ToggleBreakpointAction(editor, null, info); - action.run(); - return Status.OK_STATUS; - } - }; - final Object lock = new Object(); - final IBreakpoint[] breakpoints = new IBreakpoint[1]; - IBreakpointListener listener = new IBreakpointListener() { - @Override - public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) { - } - @Override - public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) { - } - @Override - public void breakpointAdded(IBreakpoint breakpoint) { - synchronized (lock) { - breakpoints[0] = breakpoint; - lock.notifyAll(); - } - } - }; - IBreakpointManager manager = DebugPlugin.getDefault().getBreakpointManager(); - manager.addBreakpointListener(listener); - synchronized (lock) { - job.schedule(); - lock.wait(DEFAULT_TIMEOUT); - } - manager.removeBreakpointListener(listener); - return breakpoints[0]; - } - - /** - * Closes all editors in the active workbench page. - */ - protected void closeAllEditors() { - Runnable closeAll = new Runnable() { - @Override - public void run() { - IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); - activeWorkbenchWindow.getActivePage().closeAllEditors(false); - } - }; - Display display = DebugUIPlugin.getStandardDisplay(); - display.syncExec(closeAll); - } - - /** * Returns the version level of the class files being run, based on the system property java.class.version * @return the version level of the class files being run in the current VM * diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -42,6 +42,7 @@ import org.eclipse.jdt.debug.tests.breakpoints.RunToLineTests; import org.eclipse.jdt.debug.tests.breakpoints.SpecialExceptionBreakpointTests; import org.eclipse.jdt.debug.tests.breakpoints.SuspendVMBreakpointsTests; +import org.eclipse.jdt.debug.tests.breakpoints.SuspendVMConditionalBreakpointsTests; import org.eclipse.jdt.debug.tests.breakpoints.TargetPatternBreakpointTests; import org.eclipse.jdt.debug.tests.breakpoints.TestToggleBreakpointsTarget; import org.eclipse.jdt.debug.tests.breakpoints.TestToggleBreakpointsTarget8; @@ -53,6 +54,7 @@ import org.eclipse.jdt.debug.tests.connectors.MultipleConnectionsTest; import org.eclipse.jdt.debug.tests.console.ConsoleTerminateAllActionTests; import org.eclipse.jdt.debug.tests.console.IOConsoleTests; +import org.eclipse.jdt.debug.tests.console.JavaDebugStackTraceConsoleTest; import org.eclipse.jdt.debug.tests.console.JavaStackTraceConsoleTest; import org.eclipse.jdt.debug.tests.core.AlternateStratumTests; import org.eclipse.jdt.debug.tests.core.ArgumentTests; @@ -259,6 +261,7 @@ addTest(new TestSuite(ConsoleInputTests.class)); addTest(new TestSuite(LineTrackerTests.class)); addTest(new TestSuite(JavaStackTraceConsoleTest.class)); + addTest(new TestSuite(JavaDebugStackTraceConsoleTest.class)); addTest(new TestSuite(IOConsoleTests.class)); addTest(new TestSuite(ConsoleTerminateAllActionTests.class)); @@ -340,7 +343,7 @@ addTest(new TestSuite(LambdaVariableTest.class)); } //addTest(EvalTestSuite.suite()); - if (JavaProjectHelper.isJava9Compatible()) { + if (JavaProjectHelper.isJava9Compatible() && !JavaProjectHelper.isJava19_Compatible()) { addTest(new TestSuite(Java9Tests.class)); } @@ -358,6 +361,7 @@ addTest(new TestSuite(HitCountBreakpointsTests.class)); addTest(new TestSuite(ThreadFilterBreakpointsTests.class)); addTest(new TestSuite(SuspendVMBreakpointsTests.class)); + addTest(new TestSuite(SuspendVMConditionalBreakpointsTests.class)); addTest(new TestSuite(PreLaunchBreakpointTest.class)); addTest(new TestSuite(ImportBreakpointsTest.class)); addTest(new TestSuite(BreakpointWorkingSetTests.class)); diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/AbstractBreakpointWorkingSetTest.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/AbstractBreakpointWorkingSetTest.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/AbstractBreakpointWorkingSetTest.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/AbstractBreakpointWorkingSetTest.java 2022-11-07 18:51:46.000000000 +0000 @@ -15,7 +15,7 @@ import org.eclipse.core.runtime.IAdaptable; import org.eclipse.debug.ui.IDebugUIConstants; -import org.eclipse.jdt.debug.tests.AbstractDebugTest; +import org.eclipse.jdt.debug.tests.ui.AbstractDebugUiTests; import org.eclipse.ui.IWorkingSet; import org.eclipse.ui.IWorkingSetManager; import org.eclipse.ui.PlatformUI; @@ -25,7 +25,7 @@ * * @since 3.2 */ -public abstract class AbstractBreakpointWorkingSetTest extends AbstractDebugTest { +public abstract class AbstractBreakpointWorkingSetTest extends AbstractDebugUiTests { /** * Constructor diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/BreakpointListenerTests.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/BreakpointListenerTests.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/BreakpointListenerTests.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/BreakpointListenerTests.java 2022-11-07 18:51:46.000000000 +0000 @@ -195,9 +195,6 @@ List bps = createBreakpoints("Breakpoints"); try { - // close all editors before closing project: @see bug 204023 - closeAllEditors(); - getBreakpointManager().addBreakpointListener((IBreakpointsListener)this); resetCallbacks(); diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/BreakpointWorkingSetTests.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/BreakpointWorkingSetTests.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/BreakpointWorkingSetTests.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/BreakpointWorkingSetTests.java 2022-11-07 18:51:46.000000000 +0000 @@ -14,18 +14,12 @@ package org.eclipse.jdt.debug.tests.breakpoints; import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer; import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointSetOrganizer; import org.eclipse.debug.internal.ui.views.breakpoints.BreakpointsView; -import org.eclipse.debug.ui.IDebugView; import org.eclipse.jdt.debug.core.IJavaLineBreakpoint; -import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkingSet; -import org.eclipse.ui.progress.WorkbenchJob; /** * Tests adding breakpoints and automatic addition to working sets. @@ -93,27 +87,13 @@ IWorkingSet set1 = createSet("One"); try { BreakpointSetOrganizer.setDefaultWorkingSet(set1); - IDebugView bpview = openDebugView("org.eclipse.debug.ui.BreakpointView"); + IViewPart bpview = openView("org.eclipse.debug.ui.BreakpointView"); assertNotNull("we should have opened the breakpoints view", bpview); final BreakpointsView view = (BreakpointsView) bpview; final IBreakpointOrganizer o = getOrganizer("org.eclipse.debug.ui.breakpointWorkingSetOrganizer"); assertNotNull("we should have found the working set breakpoint organizer", o); //update the view organizers on the UI thread because it spawns viewer updates that require it - Display display = DebugUIPlugin.getStandardDisplay(); - if (!Thread.currentThread().equals(display.getThread())) { - WorkbenchJob job = new WorkbenchJob("updating working sets in the breakpoint view") { - @Override - public IStatus runInUIThread(IProgressMonitor monitor) { - view.setBreakpointOrganizers(new IBreakpointOrganizer[] {o}); - return Status.OK_STATUS; - } - }; - job.schedule(); - job.join(); - } - else { - view.setBreakpointOrganizers(new IBreakpointOrganizer[] {o}); - } + sync(() -> view.setBreakpointOrganizers(new IBreakpointOrganizer[] { o })); //add a bp createLineBreakpoint(52, "Breakpoints"); IAdaptable[] elements = set1.getElements(); diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/DeferredBreakpointTests.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/DeferredBreakpointTests.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/DeferredBreakpointTests.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/DeferredBreakpointTests.java 2022-11-07 18:51:46.000000000 +0000 @@ -24,13 +24,13 @@ import org.eclipse.jdt.debug.core.IJavaDebugTarget; import org.eclipse.jdt.debug.core.IJavaLineBreakpoint; import org.eclipse.jdt.debug.core.IJavaThread; -import org.eclipse.jdt.debug.tests.AbstractDebugTest; +import org.eclipse.jdt.debug.tests.ui.AbstractDebugUiTests; import org.eclipse.ui.IEditorPart; /** * Tests deferred breakpoints. */ -public class DeferredBreakpointTests extends AbstractDebugTest { +public class DeferredBreakpointTests extends AbstractDebugUiTests { /** * Constructor diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/LambdaBreakpointsInJava8Tests.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/LambdaBreakpointsInJava8Tests.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/LambdaBreakpointsInJava8Tests.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/LambdaBreakpointsInJava8Tests.java 2022-11-07 18:51:46.000000000 +0000 @@ -13,25 +13,37 @@ *******************************************************************************/ package org.eclipse.jdt.debug.tests.breakpoints; +import static org.junit.Assert.assertArrayEquals; + import java.util.Arrays; import java.util.List; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.IStackFrame; +import org.eclipse.debug.core.model.IThread; +import org.eclipse.debug.core.model.IValue; import org.eclipse.debug.internal.ui.views.console.ProcessConsole; import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IType; import org.eclipse.jdt.debug.core.IJavaDebugTarget; import org.eclipse.jdt.debug.core.IJavaLineBreakpoint; import org.eclipse.jdt.debug.core.IJavaThread; -import org.eclipse.jdt.debug.tests.AbstractDebugTest; import org.eclipse.jdt.debug.tests.TestUtil; +import org.eclipse.jdt.debug.tests.ui.AbstractDebugUiTests; +import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; /** * Tests lambda breakpoints. */ -public class LambdaBreakpointsInJava8Tests extends AbstractDebugTest { +public class LambdaBreakpointsInJava8Tests extends AbstractDebugUiTests { public LambdaBreakpointsInJava8Tests(String name) { super(name); @@ -102,6 +114,92 @@ } } + public void testBreakpointsInLambdaBlocks() throws Exception { + final String testClass = "LambdaBreakpoints1"; + IType type = get18Project().findType(testClass); + assertNotNull("Missing file", type); + IResource file = type.getResource(); + assertTrue("Missing file", file instanceof IFile); + JavaEditor editor = (JavaEditor) openEditor((IFile) file); + processUiEvents(); + IJavaThread javaThread = null; + IBreakpoint[] bps = getBreakpointManager().getBreakpoints(); + assertArrayEquals(new IBreakpoint[0], bps); + + try { + BreakpointsMap bpMap = new BreakpointsMap(); + IJavaLineBreakpoint bp1 = createLineBreakpoint(12, editor, bpMap); + IJavaLineBreakpoint bp2 = createLineBreakpoint(15, editor, bpMap); + IJavaLineBreakpoint bp3 = createLineBreakpoint(31, editor, bpMap); + IJavaLineBreakpoint bp4 = createLineBreakpoint(22, editor, bpMap); + + processUiEvents(); + bpMap.assertBreakpointsConsistency(); + + // Check the breakpoints aren't moved or removed after saving editor + // (that will trigger ValidBreakpointLocationLocator) + sync(() -> editor.doSave(new NullProgressMonitor())); + TestUtil.waitForJobs(getName(), 100, DEFAULT_TIMEOUT, ProcessConsole.class); + processUiEvents(); + + bpMap.assertBreakpointsConsistency(); + + javaThread = launchToBreakpoint(testClass); + assertNotNull("The program did not suspend", javaThread); + processUiEvents(); + + IBreakpoint hit = getBreakpoint(javaThread); + assertEquals("should hit breakpoint", bp1, hit); + + hit = resume1(javaThread); + assertEquals("should hit breakpoint", bp2, hit); + + hit = resume1(javaThread); + assertEquals("should hit breakpoint", bp3, hit); + + hit = resume1(javaThread); + assertEquals("should hit breakpoint", bp4, hit); + + IValue value = doEval(javaThread, "result"); + assertEquals("wrong result: ", "0123", value.getValueString()); + } finally { + sync(() -> editor.getSite().getPage().closeEditor(editor, false)); + terminateAndRemove(javaThread); + removeAllBreakpoints(); + } + } + + private IBreakpoint resume1(IJavaThread javaThread) throws Exception { + super.resume(javaThread); + TestUtil.waitForJobs(getName(), 50, DEFAULT_TIMEOUT, ProcessConsole.class); + processUiEvents(); + IBreakpoint hit = getBreakpoint(javaThread); + return hit; + } + + @Override + protected IBreakpoint getBreakpoint(IThread thread) { + IBreakpoint b = super.getBreakpoint(thread); + if (b == null) { + TestUtil.waitForJobs(getName(), 100, DEFAULT_TIMEOUT, ProcessConsole.class); + b = super.getBreakpoint(thread); + if (b == null) { + IJavaThread t = (IJavaThread) thread; + try { + IStackFrame[] stackFrames = t.getStackFrames(); + StringBuilder stack = new StringBuilder("Stack for thread " + thread.getName() + "\n"); + for (IStackFrame frame : stackFrames) { + stack.append(frame.getName()).append("():").append(frame.getLineNumber()).append("\n"); + } + assertNotNull("suspended, but not by breakpoint! " + stack, b); + } catch (DebugException e) { + throwException(e); + } + } + } + return b; + } + private void terminateAndRemoveJavaLaunches() { ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager(); List launches = Arrays.asList(launchManager.getLaunches()); diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/MethodBreakpointTests15.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/MethodBreakpointTests15.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/MethodBreakpointTests15.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/MethodBreakpointTests15.java 2022-11-07 18:51:46.000000000 +0000 @@ -23,13 +23,13 @@ import org.eclipse.jdt.core.IType; import org.eclipse.jdt.debug.core.IJavaMethodBreakpoint; import org.eclipse.jdt.debug.core.IJavaThread; -import org.eclipse.jdt.debug.tests.AbstractDebugTest; +import org.eclipse.jdt.debug.tests.ui.AbstractDebugUiTests; import org.eclipse.ui.IEditorPart; /** * Tests method breakpoints for 1.5 source code. */ -public class MethodBreakpointTests15 extends AbstractDebugTest { +public class MethodBreakpointTests15 extends AbstractDebugUiTests { public MethodBreakpointTests15(String name) { super(name); diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/SuspendVMConditionalBreakpointsTests.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/SuspendVMConditionalBreakpointsTests.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/SuspendVMConditionalBreakpointsTests.java 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/breakpoints/SuspendVMConditionalBreakpointsTests.java 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2022 Simeon Andreev and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Simeon Andreev - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.debug.tests.breakpoints; + +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.debug.core.IJavaBreakpoint; +import org.eclipse.jdt.debug.core.IJavaDebugTarget; +import org.eclipse.jdt.debug.core.IJavaLineBreakpoint; +import org.eclipse.jdt.debug.core.IJavaThread; +import org.eclipse.jdt.debug.testplugin.DebugElementKindEventWaiter; +import org.eclipse.jdt.debug.testplugin.DebugEventWaiter; +import org.eclipse.jdt.debug.tests.AbstractDebugTest; +import org.eclipse.jdt.debug.tests.TestUtil; + +/** + * Test that a SUSPEND_VM conditional breakpoints function as expected. Also tests for bug 575131. + */ +public class SuspendVMConditionalBreakpointsTests extends AbstractDebugTest { + + /** + * Constructor + * + * @param name + */ + public SuspendVMConditionalBreakpointsTests(String name) { + super(name); + } + + /** + * Tests that the VM is suspended when a conditional line breakpoint is hit. + */ + public void testSuspendVmLineConditionalBreakpoint() throws Exception { + String typeName = "SuspendVMConditionalBreakpointsTestSnippet"; + + IJavaLineBreakpoint bp1 = createLineBreakpoint(28, typeName); + bp1.setCondition("if (i == 50) { System.out.println(i); } return false;"); + bp1.setConditionEnabled(true); + bp1.setSuspendPolicy(IJavaBreakpoint.SUSPEND_VM); + IJavaLineBreakpoint bp2 = createLineBreakpoint(36, typeName); + bp2.setCondition("if (j == 25) { System.out.println(j); } return false;"); + bp2.setConditionEnabled(true); + bp2.setSuspendPolicy(IJavaBreakpoint.SUSPEND_VM); + + IJavaDebugTarget debugTarget = null; + try { + TestUtil.waitForJobs("testSuspendVmLineConditionalBreakpoint before launch", 250, 500); + IJavaProject project = getProjectContext(); + ILaunchConfiguration config = getLaunchConfiguration(project, typeName); + + DebugEventWaiter waiter = new DebugElementKindEventWaiter(DebugEvent.BREAKPOINT, IJavaThread.class); + waiter.setTimeout(DEFAULT_TIMEOUT); + waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); + + boolean registerLaunch = true; + IJavaThread suspendedThread = (IJavaThread) launchAndWait(config, waiter, registerLaunch); + + debugTarget = (IJavaDebugTarget) suspendedThread.getDebugTarget(); + TestUtil.waitForJobs("testSuspendVmLineConditionalBreakpoint after suspend", 250, 500); + + debugTarget.resume(); + TestUtil.waitForJobs("testSuspendVmLineConditionalBreakpoint after resume", 250, 500); + } finally { + if (debugTarget != null) { + terminateAndRemove(debugTarget); + } + removeAllBreakpoints(); + } + } +} diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/LineTrackerTests.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/LineTrackerTests.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/LineTrackerTests.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/LineTrackerTests.java 2022-11-07 18:51:46.000000000 +0000 @@ -23,6 +23,8 @@ import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.internal.core.IInternalDebugCoreConstants; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants; import org.eclipse.debug.ui.console.IConsole; import org.eclipse.debug.ui.console.IConsoleLineTrackerExtension; import org.eclipse.jdt.debug.core.IJavaDebugTarget; @@ -154,7 +156,9 @@ public void testFlood() throws Exception { ConsoleLineTracker.setDelegate(this); ILaunch launch = null; + final IPreferenceStore debugPrefStore = DebugUIPlugin.getDefault().getPreferenceStore(); try { + debugPrefStore.setValue(IDebugPreferenceConstants.CONSOLE_LIMIT_CONSOLE_OUTPUT, false); ILaunchConfiguration config = getLaunchConfiguration("FloodConsole"); assertNotNull("Could not locate launch configuration", config); launch = config.launch(ILaunchManager.RUN_MODE, null); @@ -169,6 +173,7 @@ // Should be 10,000 lines assertEquals("Wrong number of lines", 10000, fLinesRead.size()); } finally { + debugPrefStore.setValue(IDebugPreferenceConstants.CONSOLE_LIMIT_CONSOLE_OUTPUT, true); ConsoleLineTracker.setDelegate(null); launch.getProcesses()[0].terminate(); DebugPlugin.getDefault().getLaunchManager().removeLaunch(launch); diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ModuleOptionsTests.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ModuleOptionsTests.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ModuleOptionsTests.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/core/ModuleOptionsTests.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019, 2021 GK Software SE and others. + * Copyright (c) 2019, 2022 GK Software SE and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -106,6 +106,17 @@ + "jdk.sctp,jdk.security.auth,jdk.security.jgss,jdk.unsupported," + "jdk.unsupported.desktop," // + "jdk.xml.dom"; + private static final String ASSUMED_DEFAULT_MODULES_19 = "java.se," // + + "jdk.accessibility,jdk.attach,jdk.compiler,jdk.dynalink,jdk.httpserver," // + + "jdk.incubator.concurrent,jdk.incubator.vector," // jdk.incubator.foreign removed and jdk.incubator.concurrent added in 19 + + "jdk.jartool,jdk.javadoc,jdk.jconsole,jdk.jdi," // + + "jdk.jfr," // + + "jdk.jshell,jdk.jsobject,jdk.management," // + + "jdk.management.jfr," // + + "jdk.net," // + + "jdk.nio.mapmode," // + + "jdk.sctp,jdk.security.auth,jdk.security.jgss,jdk.unsupported," + "jdk.unsupported.desktop," // + + "jdk.xml.dom"; public ModuleOptionsTests(String name) { @@ -174,7 +185,8 @@ IJavaProject javaProject = getProjectContext(); List defaultModules = getDefaultModules(javaProject); String expectedModules; - switch (String.join(",", defaultModules)) { + String moduleList = String.join(",", defaultModules); + switch (moduleList) { case ASSUMED_DEFAULT_MODULES_9: expectedModules = "java.se," // + "javafx.fxml,javafx.swing,javafx.web," // @@ -252,7 +264,7 @@ case ASSUMED_DEFAULT_MODULES_16: expectedModules = "java.se," // + "jdk.accessibility," // - + "jdk.dynalink," + + "jdk.dynalink," + "jdk.httpserver," // + "jdk.incubator.foreign,jdk.incubator.vector," // jdk.incubator.vector added in 16 + "jdk.jartool,jdk.jconsole,jdk.jshell," // @@ -265,8 +277,22 @@ + "jdk.unsupported.desktop," // + "jdk.xml.dom"; break; + case ASSUMED_DEFAULT_MODULES_19: + expectedModules = "java.se," // + + "jdk.accessibility," // + + "jdk.dynalink," + "jdk.httpserver," // + + "jdk.incubator.concurrent,jdk.incubator.vector," // jdk.incubator.foreign removed and jdk.incubator.concurrent added in 19 + + "jdk.jartool,jdk.jconsole,jdk.jshell," // + + "jdk.jsobject," // + + "jdk.management.jfr," // + + "jdk.net," // + + "jdk.nio.mapmode," // + + "jdk.sctp," + "jdk.security.auth,jdk.security.jgss,jdk.unsupported," // + + "jdk.unsupported.desktop," // + + "jdk.xml.dom"; + break; default: - fail("Unknown set of default modules " + String.join(",", defaultModules)); + fail("Unknown set of default modules " + moduleList); return; } assertTrue("expected module was not in defaultModules", defaultModules.remove("jdk.javadoc")); // requires java.compiler and jdk.compiler but diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/Java9Tests.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/Java9Tests.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/Java9Tests.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/Java9Tests.java 2022-11-07 18:51:46.000000000 +0000 @@ -13,6 +13,10 @@ *******************************************************************************/ package org.eclipse.jdt.debug.tests.eval; +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; +import java.lang.reflect.Parameter; + import org.eclipse.debug.core.model.IValue; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.debug.core.IJavaThread; @@ -33,7 +37,7 @@ public void testBug575039_methodBreakpointOnJavaBaseModuleClass_expectSuccessfulEval() throws Exception { String type = "Bug575039"; - createMethodBreakpoint("java.lang.Thread", "", "(Ljava/lang/ThreadGroup;Ljava/lang/Runnable;Ljava/lang/String;JLjava/security/AccessControlContext;Z)V", + createMethodBreakpoint("java.lang.Thread", "", getSutableThreadConstructorSignature(), true, false); thread = launchToBreakpoint(type); assertNotNull("The program did not suspend", thread); @@ -45,6 +49,58 @@ assertEquals("true", value.getValueString()); } + private String getSutableThreadConstructorSignature() { + Constructor[] constructors = Thread.class.getDeclaredConstructors(); + int index = 0, argCount = 0; + for (int i = 0; i < constructors.length; i++) { + Constructor constructor = constructors[i]; + if (!Modifier.isPublic(constructor.getModifiers()) && !Modifier.isProtected(constructor.getModifiers()) + && constructor.getParameterCount() > argCount) { + argCount = constructor.getParameterCount(); + index = i; + } + } + + Constructor constructor = constructors[index]; + Parameter[] parameters = constructor.getParameters(); + StringBuilder builder = new StringBuilder("("); + for (Parameter parameter : parameters) { + if (!parameter.getType().isPrimitive()) { + builder.append('L'); + builder.append(parameter.getType().getName().replace('.', '/')); + builder.append(';'); + } else { + builder.append(getInternalName(parameter.getType().getName())); + } + } + builder.append(")V"); + return builder.toString(); + } + + private String getInternalName(String name) { + switch (name) { + case "byte": + return "B"; + case "char": + return "C"; + case "double": + return "D"; + case "float": + return "F"; + case "int": + return "I"; + case "long": + return "J"; + case "short": + return "S"; + case "boolean": + return "Z"; + default: + return name; + + } + } + @Override protected void tearDown() throws Exception { removeAllBreakpoints(); diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/LambdaVariableTest.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/LambdaVariableTest.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/LambdaVariableTest.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/eval/LambdaVariableTest.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020 Gayan Perera and others. + * Copyright (c) 2020, 2022 Gayan Perera and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -200,6 +200,68 @@ assertEquals("wrong result at 1st lambda stack : ", "name", value.getValueString()); } + public void testEvaluate_Bug578145_NestedLambda() throws Exception { + debugWithBreakpoint("Bug578145NestedLambda", 16); + + IValue value = doEval(javaThread, "numberInInnerLambda"); + assertEquals("wrong result : ", "100", value.getValueString()); + + value = doEval(javaThread, "numberInExternalLambda"); + assertEquals("wrong result : ", "10", value.getValueString()); + + value = doEval(javaThread, "numberInMain"); + assertEquals("wrong result : ", "1", value.getValueString()); + } + + public void testEvaluate_Bug578145_LambdaInConstructor() throws Exception { + debugWithBreakpoint("Bug578145LambdaInConstructor", 13); + IValue value = doEval(javaThread, "localInLambda"); + assertEquals("wrong result : ", "10", value.getValueString()); + + value = doEval(javaThread, "localInConstructor"); + assertEquals("wrong result : ", "1", value.getValueString()); + } + + public void testEvaluate_Bug578145_LambdaInFieldDeclaration() throws Exception { + debugWithBreakpoint("Bug578145LambdaInFieldDeclaration", 11); + + IValue value = doEval(javaThread, "numberInLambda"); + assertEquals("wrong result : ", "10", value.getValueString()); + + value = doEval(javaThread, "numberInRunnable"); + assertEquals("wrong result : ", "1", value.getValueString()); + } + + public void testEvaluate_Bug578145_LambdaInStaticInitializer() throws Exception { + debugWithBreakpoint("Bug578145LambdaInStaticInitializer", 12); + + IValue value = doEval(javaThread, "numberInLambda"); + assertEquals("wrong result : ", "10", value.getValueString()); + + value = doEval(javaThread, "numberInStaticInitializer"); + assertEquals("wrong result : ", "1", value.getValueString()); + } + + public void testEvaluate_Bug578145_LambdaInAnonymous() throws Exception { + debugWithBreakpoint("Bug578145LambdaInAnonymous", 16); + + IValue value = doEval(javaThread, "numberInLambda"); + assertEquals("wrong result : ", "10", value.getValueString()); + + value = doEval(javaThread, "numberInMain"); + assertEquals("wrong result : ", "1", value.getValueString()); + } + + public void testEvaluate_Bug578145_LambdaOnChainCalls() throws Exception { + debugWithBreakpoint("Bug578145LambdaOnChainCalls", 11); + + IValue value = doEval(javaThread, "numberInLambda"); + assertEquals("wrong result : ", "10", value.getValueString()); + + value = doEval(javaThread, "numberInMain"); + assertEquals("wrong result : ", "1", value.getValueString()); + } + private void debugWithBreakpoint(String testClass, int lineNumber) throws Exception { createLineBreakpoint(lineNumber, testClass); javaThread = launchToBreakpoint(testClass); diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/ConfigurationEncodingTests.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/ConfigurationEncodingTests.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/ConfigurationEncodingTests.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/ConfigurationEncodingTests.java 2022-11-07 18:51:46.000000000 +0000 @@ -17,6 +17,7 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Preferences; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; @@ -60,21 +61,20 @@ */ public void testGetSystemDefaultEncoding() throws CoreException { String oldencoding = ResourcesPlugin.getEncoding(); - String oldsystemencoding = System.getProperty("file.encoding"); + String defaultEncoding = getDefaultEncoding(); + String systemEncoding = Platform.getSystemCharset().name(); try { - getResourcesPreferences().setValue(ResourcesPlugin.PREF_ENCODING, getDefaultEncoding()); - System.setProperty("file.encoding", "UTF-16BE"); + getResourcesPreferences().setValue(ResourcesPlugin.PREF_ENCODING, defaultEncoding); ILaunchConfiguration config = getLaunchConfiguration("LaunchHistoryTest"); assertNotNull("the configuration could not be found", config); assertTrue("there should be no encoding set on the configuration", config.getAttribute(DebugPlugin.ATTR_CONSOLE_ENCODING, (String) null) == null); String encoding = getLaunchManager().getEncoding(config); assertNotNull("The configuration encoding should not be null", encoding); - assertEquals("The configuration encoding should match the file system encoding", encoding, System.getProperty("file.encoding")); + assertEquals("The configuration encoding should match the file system encoding", systemEncoding, encoding); } finally { //ensure old encoding is restored - getResourcesPreferences().setValue(ResourcesPlugin.PREF_ENCODING, (oldencoding == null ? getDefaultEncoding() : oldencoding)); - System.setProperty("file.encoding", oldsystemencoding); + getResourcesPreferences().setValue(ResourcesPlugin.PREF_ENCODING, (oldencoding == null ? defaultEncoding : oldencoding)); } } diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LongClassPathTests.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LongClassPathTests.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LongClassPathTests.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LongClassPathTests.java 2022-11-07 18:51:46.000000000 +0000 @@ -30,6 +30,7 @@ import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; +import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; @@ -38,6 +39,8 @@ import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.debug.core.IJavaThread; +import org.eclipse.jdt.debug.testplugin.DebugElementKindEventWaiter; +import org.eclipse.jdt.debug.testplugin.DebugEventWaiter; import org.eclipse.jdt.debug.testplugin.JavaProjectHelper; import org.eclipse.jdt.debug.tests.AbstractDebugTest; import org.eclipse.jdt.internal.launching.LaunchingPlugin; @@ -55,11 +58,11 @@ * */ public class LongClassPathTests extends AbstractDebugTest { - private static final String MAIN_TYPE_NAME = "test.classpath.Main"; - private static final IPath CLASSPATH_PROJECT_CONTENT_PATH = new Path("testresources/classpathProject"); - private IJavaProject javaProject; - private ILaunchConfiguration launchConfiguration; - private IJavaThread thread; + protected static final String MAIN_TYPE_NAME = "test.classpath.Main"; + protected static final IPath CLASSPATH_PROJECT_CONTENT_PATH = new Path("testresources/classpathProject"); + protected IJavaProject javaProject; + protected ILaunchConfiguration launchConfiguration; + protected IJavaThread thread; public LongClassPathTests(String name) { super(name); @@ -100,7 +103,7 @@ */ public void testVeryLongClasspathWithClasspathOnlyJar() throws Exception { // Given - javaProject = createJavaProjectClone("testVeryLongClasspathWithClasspathOnlyJar", CLASSPATH_PROJECT_CONTENT_PATH.toString(), JavaProjectHelper.JAVA_SE_1_6_EE_NAME, true); + javaProject = createJavaProjectClone("test ä VeryLongClasspathWithClasspathOnlyJar", CLASSPATH_PROJECT_CONTENT_PATH.toString(), JavaProjectHelper.JAVA_SE_1_6_EE_NAME, true); launchConfiguration = createLaunchConfigurationStopInMain(javaProject, MAIN_TYPE_NAME); int minClasspathLength = 300000; setLongClasspath(javaProject, minClasspathLength); @@ -182,7 +185,7 @@ resumeAndExit(thread); } - private Optional getTempFile(ILaunch launch) { + protected Optional getTempFile(ILaunch launch) { IProcess process = launch.getProcesses()[0]; String tempFile = process.getAttribute(LaunchingPlugin.ATTR_LAUNCH_TEMP_FILES); if (tempFile == null) { @@ -191,7 +194,7 @@ return Optional.of(new File(tempFile)); } - private boolean isArgumentFileSupported(ILaunchConfiguration launchConfiguration) throws CoreException { + protected boolean isArgumentFileSupported(ILaunchConfiguration launchConfiguration) throws CoreException { IVMInstall vmInstall = JavaRuntime.computeVMInstall(launchConfiguration); if (vmInstall instanceof AbstractVMInstall) { AbstractVMInstall install = (AbstractVMInstall) vmInstall; @@ -209,7 +212,7 @@ return configurationWorkingCopy.doSave(); } - private ILaunchConfiguration createLaunchConfigurationStopInMain(IJavaProject javaProject, String mainTypeName) throws Exception, CoreException { + protected ILaunchConfiguration createLaunchConfigurationStopInMain(IJavaProject javaProject, String mainTypeName) throws Exception, CoreException { ILaunchConfiguration launchConfiguration; launchConfiguration = createLaunchConfiguration(javaProject, mainTypeName); ILaunchConfigurationWorkingCopy wc = launchConfiguration.getWorkingCopy(); @@ -218,7 +221,7 @@ return launchConfiguration; } - private void setLongClasspath(IJavaProject javaProject, int minClassPathLength) throws Exception { + protected void setLongClasspath(IJavaProject javaProject, int minClassPathLength) throws Exception { StringBuilder sb = new StringBuilder(); List classpathEntries = new ArrayList<>(); int i = 0; @@ -240,4 +243,17 @@ javaProject.setRawClasspath(classpathEntries.toArray(new IClasspathEntry[classpathEntries.size()]), null); } + /** + * Increased timeout + * + * {@inheritDoc} + */ + @Override + protected IJavaThread launchAndSuspend(ILaunchConfiguration config) throws Exception { + DebugEventWaiter waiter = new DebugElementKindEventWaiter(DebugEvent.SUSPEND, IJavaThread.class); + waiter.setTimeout(DEFAULT_TIMEOUT * 2); + waiter.setEnableUIEventLoopProcessing(enableUIEventLoopProcessingInWaiter()); + Object suspendee = launchAndWait(config, waiter); + return (IJavaThread) suspendee; + } } diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LongCommandLineTests.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LongCommandLineTests.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LongCommandLineTests.java 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/launching/LongCommandLineTests.java 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2022 Andrey Loskutov (loskutov@gmx.de) and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Andrey Loskutov (loskutov@gmx.de) - initial implementation + *******************************************************************************/ +package org.eclipse.jdt.debug.tests.launching; + +import static org.junit.Assume.assumeTrue; + +import java.io.File; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Platform; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.debug.testplugin.JavaProjectHelper; +import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Test JVM startup with long classpath / system properties by explicitly enabling {@link IJavaLaunchConfigurationConstants.ATTR_USE_ARGFILE} option + * in the "Arguments" part of the process launch configuration + */ +public class LongCommandLineTests extends LongClassPathTests { + + static final int MIN_CLASSPATH_LENGTH = 300000; + boolean createLongArguments; + + public LongCommandLineTests(String name) { + super(name); + } + + public static Test suite() { + TestSuite suite = new TestSuite(); + suite.addTest(new LongCommandLineTests("testVeryLongClasspathWithArgumentFile")); + suite.addTest(new LongCommandLineTests("testVeryLongSystemPropertiesWithArgumentFile")); + return suite; + } + + /* + * Test will create lot of "-Dfoo=12345" system arguments for the started JVM and check if the startup works with argument file + */ + public void testVeryLongSystemPropertiesWithArgumentFile() throws Exception { + createLongArguments = true; + + javaProject = createJavaProjectClone("test ä VeryLongSystemPropertiesWithArgumentFile", CLASSPATH_PROJECT_CONTENT_PATH.toString(), JavaProjectHelper.JAVA_SE_9_EE_NAME, true); + launchConfiguration = createLaunchConfigurationStopInMain(javaProject, MAIN_TYPE_NAME); + assumeTrue(isArgumentFileSupported(launchConfiguration)); + + // Given + waitForBuild(); + + // When + thread = launchAndSuspend(launchConfiguration); + + // Then + File tempFile = getTempFile(thread.getLaunch()).orElseThrow(() -> new RuntimeException("No temp file")); + assertTrue("No temp file created: " + tempFile, tempFile.exists()); + assertTrue("Unexpected temp file name: " + tempFile, tempFile.getName().endsWith(".txt")); + String valueString = doEval(thread, "java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments().toString()").getValueString(); + assertTrue("Unexpected small system arguments list: " + valueString, valueString.length() >= MIN_CLASSPATH_LENGTH); + + // When + resumeAndExit(thread); + + // Then + if (!Platform.getOS().equals(Platform.OS_WIN32)) { + // On windows, temp file deletion may fail + assertFalse(tempFile.exists()); + } + } + + private void setLongVmArgumentsList(ILaunchConfigurationWorkingCopy wc, int minArgumentsLength) throws Exception { + final String keyArgs = IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS; + String args = wc.getAttribute(keyArgs, ""); + StringBuilder sb = new StringBuilder(args); + while (sb.length() < minArgumentsLength) { + sb.append(" "); + sb.append("-Dfoo=1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890_1234567890"); + } + args += sb.toString(); + wc.setAttribute(keyArgs, args); + } + + @Override + protected ILaunchConfiguration createLaunchConfigurationStopInMain(IJavaProject javaProject, String mainTypeName) throws Exception, CoreException { + ILaunchConfiguration launchConfiguration; + launchConfiguration = createLaunchConfiguration(javaProject, mainTypeName); + ILaunchConfigurationWorkingCopy wc = launchConfiguration.getWorkingCopy(); + wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_STOP_IN_MAIN, true); + // Always use argfile option + wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_USE_ARGFILE, true); + // Only set if required by particular test + if (createLongArguments) { + setLongVmArgumentsList(wc, MIN_CLASSPATH_LENGTH); + } + launchConfiguration = wc.doSave(); + return launchConfiguration; + } + +} diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/StressTestSuspendVMConditionalBreakpoints.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/StressTestSuspendVMConditionalBreakpoints.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/StressTestSuspendVMConditionalBreakpoints.java 1970-01-01 00:00:00.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/StressTestSuspendVMConditionalBreakpoints.java 2022-11-07 18:51:46.000000000 +0000 @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2022 Simeon Andreev and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Simeon Andreev - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.debug.tests; + +import org.eclipse.jdt.debug.tests.breakpoints.SuspendVMConditionalBreakpointsTests; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Stress test suite for bug 575131. Not executed in automated tests. + */ +public class StressTestSuspendVMConditionalBreakpoints extends DebugSuite { + + private static final int STRESS_TEST_REPEAT_COUNT = 500; + + public static Test suite() { + return new StressTestSuspendVMConditionalBreakpoints(); + } + + public StressTestSuspendVMConditionalBreakpoints() { + for (int i = 0; i < STRESS_TEST_REPEAT_COUNT; ++i) { + addTest(new TestSuite(SuspendVMConditionalBreakpointsTests.class)); + } + } +} diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/TestUtil.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/TestUtil.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/TestUtil.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/TestUtil.java 2022-11-07 18:51:46.000000000 +0000 @@ -49,7 +49,7 @@ if (timedOut) { // We don't expect any extra jobs run during the test: try to cancel them log(IStatus.INFO, owner, "Trying to cancel running jobs: " + getRunningOrWaitingJobs(null)); - getRunningOrWaitingJobs(null).forEach(job -> job.cancel()); + getRunningOrWaitingJobs(null).forEach(Job::cancel); waitForJobs(owner, 5, 1000); } @@ -136,6 +136,7 @@ if (maxTimeMs < minTimeMs) { throw new IllegalArgumentException("Max time is smaller as min time!"); } + wakeUpSleepingJobs(null); final long start = System.currentTimeMillis(); while (System.currentTimeMillis() - start < minTimeMs) { runEventLoop(); @@ -168,11 +169,19 @@ dumpRunningOrWaitingJobs(owner, jobs); return true; } + wakeUpSleepingJobs(null); } runningJobs.clear(); return false; } + private static void wakeUpSleepingJobs(Object family) { + List sleepingJobs = getSleepingJobs(family); + for (Job job : sleepingJobs) { + job.wakeUp(); + } + } + static Set runningJobs = new LinkedHashSet<>(); private static void dumpRunningOrWaitingJobs(String owner, List jobs) { @@ -220,6 +229,17 @@ return running; } + private static List getSleepingJobs(Object family) { + List sleeping = new ArrayList<>(); + Job[] jobs = Job.getJobManager().find(family); + for (Job job : jobs) { + if (job.getState() == Job.SLEEPING) { + sleeping.add(job); + } + } + return sleeping; + } + private static boolean isRunningOrWaitingJob(Job job) { int state = job.getState(); return (state == Job.RUNNING || state == Job.WAITING); diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/AbstractDebugUiTests.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/AbstractDebugUiTests.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/AbstractDebugUiTests.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/AbstractDebugUiTests.java 2022-11-07 18:51:46.000000000 +0000 @@ -13,24 +13,42 @@ *******************************************************************************/ package org.eclipse.jdt.debug.tests.ui; +import java.util.Arrays; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.Map.Entry; +import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicReference; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarkerDelta; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IBreakpointListener; +import org.eclipse.debug.core.IBreakpointManager; +import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.internal.core.IInternalDebugCoreConstants; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.debug.ui.IDebugView; +import org.eclipse.debug.ui.actions.ToggleBreakpointAction; +import org.eclipse.jdt.debug.core.IJavaLineBreakpoint; +import org.eclipse.jdt.debug.core.IJavaMethodBreakpoint; +import org.eclipse.jdt.debug.core.IJavaMethodEntryBreakpoint; import org.eclipse.jdt.debug.tests.AbstractDebugTest; import org.eclipse.jdt.debug.tests.TestUtil; +import org.eclipse.jdt.debug.tests.VerticalRulerInfoStub; import org.eclipse.jdt.ui.JavaUI; import org.eclipse.jface.dialogs.MessageDialogWithToggle; import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.text.source.IVerticalRulerInfo; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IPerspectiveDescriptor; +import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; @@ -69,7 +87,7 @@ JavaUI.ID_PERSPECTIVE + ","); preferenceStore.setValue(IInternalDebugUIConstants.PREF_USER_VIEW_BINDINGS, IInternalDebugCoreConstants.EMPTY_STRING); preferenceStore.setValue(IInternalDebugUIConstants.PREF_ACTIVATE_DEBUG_VIEW, true); - sync(() -> TestUtil.waitForJobs(getName(), 10, 1000)); + sync(() -> TestUtil.waitForJobs(getName(), 10, 10000)); } @Override @@ -80,7 +98,7 @@ preferenceStore.setValue(IDebugUIConstants.PREF_MANAGE_VIEW_PERSPECTIVES, debug_perspectives); preferenceStore.setValue(IInternalDebugUIConstants.PREF_USER_VIEW_BINDINGS, user_view_bindings); preferenceStore.setValue(IInternalDebugUIConstants.PREF_ACTIVATE_DEBUG_VIEW, activate_debug_view); - sync(() -> TestUtil.waitForJobs(getName(), 10, 1000)); + sync(() -> TestUtil.waitForJobs(getName(), 10, 10000)); super.tearDown(); } @@ -90,7 +108,7 @@ * @param window * @param perspectiveId */ - protected void switchPerspective(IWorkbenchWindow window, String perspectiveId) { + protected static void switchPerspective(IWorkbenchWindow window, String perspectiveId) { IPerspectiveDescriptor descriptor = PlatformUI.getWorkbench().getPerspectiveRegistry().findPerspectiveWithId(perspectiveId); assertNotNull("missing perspective " + perspectiveId, descriptor); IWorkbenchPage page = window.getActivePage(); @@ -104,7 +122,7 @@ * * @return the window in which the perspective is ready */ - protected IWorkbenchWindow resetPerspective(final String id) throws Exception { + protected static IWorkbenchWindow resetPerspective(final String id) throws RuntimeException { final IWorkbenchWindow[] windows = new IWorkbenchWindow[1]; sync(() -> { IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); @@ -119,7 +137,7 @@ * * @return the window in which the perspective is ready */ - protected IWorkbenchWindow resetDebugPerspective() throws Exception { + protected static IWorkbenchWindow resetDebugPerspective() throws RuntimeException { return resetPerspective(IDebugUIConstants.ID_DEBUG_PERSPECTIVE); } @@ -128,17 +146,57 @@ * * @return the window in which the perspective is ready */ - protected IWorkbenchWindow resetJavaPerspective() throws Exception { + protected static IWorkbenchWindow resetJavaPerspective() throws RuntimeException { return resetPerspective(JavaUI.ID_PERSPECTIVE); } /** + * Process all queued UI events. + */ + public static void processUiEvents() throws RuntimeException { + sync(() -> { + Display display = Display.getCurrent(); + if (!display.isDisposed()) { + while (display.readAndDispatch()) { + // Keep pumping events until the queue is empty + } + } + }); + } + + /** + * Process all queued UI events. If called from background thread, just waits + * + * @param millis + * max wait time to process events + */ + public static void processUiEvents(final long millis) throws RuntimeException { + sync(() -> { + long start = System.currentTimeMillis(); + while (System.currentTimeMillis() - start < millis) { + Display display = Display.getCurrent(); + if (display != null && !display.isDisposed()) { + while (display.readAndDispatch()) { + // loop until the queue is empty + } + } else { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + break; + } + } + } + }); + } + + /** * Sync exec the given runnable, re-throwing exceptions in the current thread * * @param r * @throws Exception */ - protected void sync(Runnable r) throws Exception { + protected static void sync(Runnable r) throws RuntimeException { AtomicReference error = new AtomicReference<>(); DebugUIPlugin.getStandardDisplay().syncExec(() -> { try { @@ -149,7 +207,7 @@ } }); if (error.get() != null) { - throw error.get(); + throwException(error.get()); } } @@ -159,7 +217,7 @@ * @param c * @throws Exception */ - protected V sync(Callable c) throws Exception { + protected static V sync(Callable c) throws RuntimeException { AtomicReference error = new AtomicReference<>(); AtomicReference result = new AtomicReference<>(); DebugUIPlugin.getStandardDisplay().syncExec(() -> { @@ -177,50 +235,176 @@ } /** - * This and the another {@link #throwException1(Throwable)} method below are here to allow to catch AssertionFailedError's and other - * non-Exceptions happened in the UI thread - * - * @param exception + * This method is to allow to catch AssertionFailedError's and other non-Exceptions happened in the UI thread */ - private static void throwException(Throwable exception) { - AbstractDebugUiTests. throwException1(exception); + @SuppressWarnings("unchecked") + public static void throwException(Throwable exception) throws T { + throw (T) exception; + } + + protected static IWorkbenchPage getActivePage() throws RuntimeException { + Callable callable = () -> { + IWorkbench workbench = PlatformUI.getWorkbench(); + IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); + if (window == null) { + window = workbench.getWorkbenchWindows()[0]; + Shell shell = window.getShell(); + shell.moveAbove(null); + shell.setActive(); + shell.forceActive(); + } + return window.getActivePage(); + }; + return callInUi(callable); + } + + protected IEditorPart openEditor(String type) throws RuntimeException { + Callable callable = () -> { + IFile resource = (IFile) getResource(type); + IEditorPart editor = IDE.openEditor(getActivePage(), resource); + assertNotNull(editor); + processUiEvents(100); + return editor; + }; + return callInUi(callable); + } + + private static T callInUi(Callable callable) throws RuntimeException { + if (Display.getCurrent() != null) { + try { + return callable.call(); + } catch (Exception e) { + throwException(e); + } + } + return sync(callable); } /** - * @param dummy to make compiler happy + * Opens and returns an editor on the given file or null if none. The editor will be activated. + * + * @param file + * @return editor or null */ - @SuppressWarnings("unchecked") - private static void throwException1(Throwable exception) throws T { - throw (T) exception; + protected static IEditorPart openEditor(final IFile file) throws RuntimeException { + Callable callable = () -> { + IWorkbenchPage page = getActivePage(); + return IDE.openEditor(page, file, true); + }; + return callInUi(callable); + } + + protected IJavaLineBreakpoint createLineBreakpoint(int lineNumber, IEditorPart editor, BreakpointsMap bpMap) throws Exception { + IJavaLineBreakpoint breakpoint = (IJavaLineBreakpoint) toggleBreakpoint(editor, lineNumber); + bpMap.put(breakpoint, lineNumber); + return breakpoint; } - protected void processUiEvents(long millis) throws Exception { - Thread.sleep(millis); - if (Display.getCurrent() == null) { - sync(() -> TestUtil.runEventLoop()); - } else { - TestUtil.runEventLoop(); + /** + * Toggles a breakpoint in the editor at the given line number returning the breakpoint or null if none. + * + * @param editor + * @param lineNumber + * @return returns the created breakpoint or null if none. + */ + protected IBreakpoint toggleBreakpoint(final IEditorPart editor, int lineNumber) throws Exception { + final Object lock = new Object(); + final AtomicReference breakpoint = new AtomicReference<>(); + IBreakpointListener listener = new IBreakpointListener() { + @Override + public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) { + } + + @Override + public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) { + } + + @Override + public void breakpointAdded(IBreakpoint b) { + synchronized (lock) { + breakpoint.set(b); + lock.notifyAll(); + } + } + }; + IBreakpointManager manager = DebugPlugin.getDefault().getBreakpointManager(); + manager.addBreakpointListener(listener); + sync(() -> { + final IVerticalRulerInfo info = new VerticalRulerInfoStub(lineNumber - 1); // sub 1, as the doc lines start at 0 + new ToggleBreakpointAction(editor, null, info).run(); + }); + synchronized (lock) { + if (breakpoint.get() == null) { + lock.wait(DEFAULT_TIMEOUT); + } + } + manager.removeBreakpointListener(listener); + IBreakpoint bp = breakpoint.get(); + assertNotNull("Breakpoint not created", bp); + if (isLineBreakpoint(bp)) { + int line = ((IJavaLineBreakpoint) bp).getLineNumber(); + assertEquals("Breakpoint line differs from expected", lineNumber, line); } + return bp; + } + + private boolean isLineBreakpoint(IBreakpoint bp) { + return bp instanceof IJavaLineBreakpoint + && !(bp instanceof IJavaMethodBreakpoint) + && !(bp instanceof IJavaMethodEntryBreakpoint); + } + + /** + * Closes all editors in the active workbench page. + */ + protected static void closeAllEditors() throws RuntimeException { + sync(() -> { + for (IWorkbenchWindow window : PlatformUI.getWorkbench().getWorkbenchWindows()) { + window.getActivePage().closeAllEditors(false); + } + }); + } + + /** + * Opens the view with the given id, does nothing if no such view exists. This method can return null + * + * @param viewId + * @return the handle to the {@link IDebugView} with the given id + */ + protected static IViewPart openView(final String viewId) throws RuntimeException { + return sync(() -> { + return getActivePage().showView(viewId); + }); } - protected IWorkbenchPage getActivePage() { - IWorkbench workbench = PlatformUI.getWorkbench(); - IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); - if (window == null) { - window = workbench.getWorkbenchWindows()[0]; - Shell shell = window.getShell(); - shell.moveAbove(null); - shell.setActive(); - shell.forceActive(); - } - return window.getActivePage(); - } - - protected IEditorPart openEditor(String type) throws Exception { - IFile resource = (IFile) getResource(type); - IEditorPart editor = IDE.openEditor(getActivePage(), resource); - assertNotNull(editor); - processUiEvents(100); - return editor; + private void assertBreakpointExists(IJavaLineBreakpoint bp, IBreakpoint[] bps) throws Exception { + boolean contains = Arrays.asList(bps).contains(bp); + assertTrue("Breakpoint not found: " + bp + ", all: " + Arrays.toString(bps), contains); + } + + public class BreakpointsMap { + IdentityHashMap breakpoints = new IdentityHashMap<>(); + HashMap lines = new HashMap<>(); + + public void put(IJavaLineBreakpoint breakpoint, int line) throws Exception { + int lineNumber = breakpoint.getLineNumber(); + assertEquals("Breakpoint line differs from original", line, lineNumber); + Integer old = breakpoints.put(breakpoint, lineNumber); + assertNull("Breakpoint already exists for line: " + old, old); + IJavaLineBreakpoint oldB = lines.put(lineNumber, breakpoint); + assertNull("Breakpoint already exists for line: " + lineNumber, oldB); + } + + public void assertBreakpointsConsistency() throws Exception { + IBreakpoint[] bps = getBreakpointManager().getBreakpoints(); + Set> set = breakpoints.entrySet(); + for (Entry entry : set) { + IJavaLineBreakpoint bp = entry.getKey(); + assertBreakpointExists(bp, bps); + Integer line = entry.getValue(); + assertEquals("Breakpoint moved", line.intValue(), bp.getLineNumber()); + } + } } + } diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugHoverTests.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugHoverTests.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugHoverTests.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugHoverTests.java 2022-11-07 18:51:46.000000000 +0000 @@ -13,6 +13,8 @@ *******************************************************************************/ package org.eclipse.jdt.debug.tests.ui; +import static org.junit.Assert.assertNotEquals; + import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; @@ -1240,7 +1242,7 @@ thread = launchToBreakpoint(typeName); CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread); - selectFrame(thread.getStackFrames()[4]); + selectFrame(part, thread.getStackFrames()[4]); JavaDebugHover hover = new JavaDebugHover(); hover.setEditor(part); @@ -1453,7 +1455,7 @@ return sync(() -> selection.getText()); } - private void selectFrame(IStackFrame frame) throws Exception { + private void selectFrame(CompilationUnitEditor editor, IStackFrame frame) throws Exception { LaunchView debugView = sync(() -> (LaunchView) getActivePage().findView(IDebugUIConstants.ID_DEBUG_VIEW)); assertNotNull("expected Debug View to be open", debugView); @@ -1461,8 +1463,25 @@ TreePath path = selection.getPaths()[0]; TreePath newPath = path.getParentPath().createChildPath(frame); TreeSelection newSelection = new TreeSelection(newPath); - sync(() -> debugView.getViewer().setSelection(newSelection, true)); - processUiEvents(100); + + // frames uses 1 based line number, subtract 1 to line up with editor line numbers + int targetLineNumber = frame.getLineNumber() - 1; + int initialLineNumber = sync(() -> ((ITextSelection) editor.getSelectionProvider().getSelection()).getStartLine()); + assertNotEquals("selectFrame cannot detect when it has" + + "completed because selecting frame doesn't change the line number.", initialLineNumber, targetLineNumber); + final int timeoutms = 1000; + int selectedLineNumer = sync(() -> { + int lineNumber; + long endtime = System.currentTimeMillis() + timeoutms; + debugView.getViewer().setSelection(newSelection, true); + do { + TestUtil.runEventLoop(); + lineNumber = ((ITextSelection) editor.getSelectionProvider().getSelection()).getStartLine(); + } while (lineNumber != targetLineNumber && System.currentTimeMillis() < endtime); + return lineNumber; + }); + assertEquals("After waiting " + timeoutms + + "ms the editor selection was not moved to the expected line", targetLineNumber, selectedLineNumer); } @Override diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/OpenFromClipboardTests.java eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/OpenFromClipboardTests.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/OpenFromClipboardTests.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/OpenFromClipboardTests.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2018 IBM Corporation and others. + * Copyright (c) 2010, 2022 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -16,10 +16,13 @@ import java.util.ArrayList; import java.util.List; +import org.eclipse.core.internal.resources.CharsetDeltaJob; +import org.eclipse.core.internal.resources.ValidateProjectEncoding; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; @@ -27,7 +30,10 @@ import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.debug.testplugin.JavaProjectHelper; +import org.eclipse.jdt.debug.testplugin.JavaTestPlugin; import org.eclipse.jdt.debug.tests.TestAgainException; +import org.eclipse.jdt.debug.tests.TestUtil; +import org.eclipse.jdt.internal.core.JavaModelManager; import org.eclipse.jdt.internal.debug.ui.actions.OpenFromClipboardAction; import org.eclipse.jdt.launching.IVMInstall; import org.eclipse.jdt.launching.JavaRuntime; @@ -83,15 +89,23 @@ @Override protected void setUp() throws Exception { super.setUp(); + JavaTestPlugin.enableAutobuild(false); fJProject = createProject("OpenFromClipboardTests"); + waitForEncodingRelatedJobs(); } @Override protected void tearDown() throws Exception { fJProject.getProject().delete(true, true, null); + JavaTestPlugin.enableAutobuild(true); super.tearDown(); } + protected void waitForEncodingRelatedJobs() { + TestUtil.waitForJobs("OpenFromClipboardTests", 10, 5_000, ValidateProjectEncoding.class); + TestUtil.waitForJobs("OpenFromClipboardTests", 10, 5_000, CharsetDeltaJob.FAMILY_CHARSET_DELTA); + } + private static IJavaProject createProject(String name) throws CoreException { // delete any pre-existing project IProject pro = ResourcesPlugin.getWorkspace().getRoot().getProject(name); @@ -120,12 +134,14 @@ @Override protected void setUp() throws Exception { + TestUtil.log(IStatus.INFO, getName(), "setUp"); super.setUp(); fSourceFolder = JavaProjectHelper.addSourceContainer(MyTestSetup.fJProject, "src"); } @Override protected void tearDown() throws Exception { + TestUtil.log(IStatus.INFO, getName(), "tearDown"); JavaProjectHelper.removeSourceContainer(MyTestSetup.fJProject, "src"); super.tearDown(); } @@ -136,6 +152,7 @@ } private List getJavaElementMatches(final String textData) { + JavaModelManager.getIndexManager().waitForIndex(false, null); final List matches = new ArrayList<>(); Display.getDefault().syncExec(new Runnable() { @Override @@ -166,9 +183,6 @@ setupTypeTest("OpenFromClipboardTests"); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testClassFileLine_1 test again"); - } assertEquals(1, matches.size()); } @@ -178,9 +192,6 @@ setupTypeTest("OpenFromClipboardTests"); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testClassFileLine_2 test again"); - } assertEquals(1, matches.size()); } @@ -190,9 +201,6 @@ setupTypeTest("OpenFromClipboard$Tests"); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testClassFileLine_3 test again"); - } assertEquals(1, matches.size()); } @@ -205,9 +213,6 @@ setupTypeTest(typeName); List matches= getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testDBCS test again"); - } assertEquals(1, matches.size()); } @@ -220,9 +225,6 @@ setupTypeTest(typeName); List matches= getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testUmlaut test again"); - } assertEquals(1, matches.size()); } @@ -232,9 +234,6 @@ setupTypeTest("OpenFromClipboardTests"); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testClassFile_1 test again"); - } assertEquals(1, matches.size()); } @@ -244,9 +243,6 @@ setupTypeTest("OpenFromClipboardTests"); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testTypeLine_1 test again"); - } assertEquals(1, matches.size()); } @@ -256,9 +252,6 @@ setupTypeTest("OpenFromClipboardTests"); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testTypeLine_2 test again"); - } assertEquals(1, matches.size()); } @@ -269,9 +262,6 @@ setupTypeTest("OpenFromClipboardTests"); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testStackTraceLine_1 test again"); - } assertEquals(1, matches.size()); } @@ -281,9 +271,6 @@ setupTypeTest("OpenFromClipboardTests"); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testStackTraceLine_2 test again"); - } assertEquals(1, matches.size()); } @@ -293,9 +280,6 @@ setupTypeTest("OpenFromClipboardTests"); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testStackTraceLine_3 test again"); - } assertEquals(1, matches.size()); } @@ -305,9 +289,6 @@ setupTypeTest("OpenFromClipboardTests"); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testStackTraceLine_4 test again"); - } assertEquals(1, matches.size()); } @@ -317,9 +298,6 @@ setupTypeTest("OpenFromClipboardTests"); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testStackTraceLine_5 test again"); - } assertEquals(1, matches.size()); } @@ -329,9 +307,6 @@ setupTypeTest("OpenFromClipboard$Tests"); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testStackTraceLine_6 test again"); - } assertEquals(1, matches.size()); } @@ -342,9 +317,6 @@ setupTypeTest("OpenFromClipboardTests"); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testStackTraceLine_7 test again"); - } assertEquals(1, matches.size()); } @@ -370,9 +342,6 @@ setupMethodTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testMethod_1 test again"); - } assertEquals(1, matches.size()); } @@ -382,9 +351,6 @@ setupMethodTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testMethod_2 test again"); - } assertEquals(1, matches.size()); } @@ -394,9 +360,6 @@ setupMethodTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testMethod_3 test again"); - } assertEquals(1, matches.size()); } @@ -406,9 +369,6 @@ setupMethodTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testMethod_4 test again"); - } assertEquals(1, matches.size()); } @@ -418,9 +378,6 @@ setupMethodTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testMethod_5 test again"); - } assertEquals(1, matches.size()); } @@ -430,9 +387,6 @@ setupMethodTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testMethod_6 test again"); - } assertEquals(1, matches.size()); } @@ -442,9 +396,6 @@ setupMethodTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testMethod_7 test again"); - } assertEquals(1, matches.size()); } @@ -489,9 +440,6 @@ setupMethodWithDollarSignTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testMethod_10 test again"); - } assertEquals(1, matches.size()); } @@ -501,9 +449,6 @@ setupMethodWithDollarSignTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testMethod_11 test again"); - } assertEquals(1, matches.size()); } @@ -525,9 +470,6 @@ setupMemberTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testMember_1 test again"); - } assertEquals(1, matches.size()); } @@ -537,9 +479,6 @@ setupMemberTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testMember_2 test again"); - } assertEquals(1, matches.size()); } @@ -549,9 +488,6 @@ setupMemberTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testMember_3 test again"); - } assertEquals(1, matches.size()); } @@ -574,9 +510,6 @@ setupMemberTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testQualifiedName_2 test again"); - } assertEquals(1, matches.size()); } @@ -586,9 +519,6 @@ setupMemberTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testQualifiedName_3 test again"); - } assertEquals(1, matches.size()); } @@ -617,9 +547,6 @@ setupQualifiedNameWithDollarSignTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testQualifiedName_4 test again"); - } assertEquals(1, matches.size()); } @@ -629,9 +556,6 @@ setupQualifiedNameWithDollarSignTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testQualifiedName_5 test again"); - } assertEquals(1, matches.size()); } @@ -641,9 +565,6 @@ setupQualifiedNameWithDollarSignTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testQualifiedName_6 test again"); - } assertEquals(1, matches.size()); } @@ -665,9 +586,6 @@ setupStackElementTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testStackElement_1 test again"); - } assertEquals(1, matches.size()); } @@ -677,9 +595,6 @@ setupStackElementTest(); List matches = getJavaElementMatches(s); - if (matches.size() != 1) { - throw new TestAgainException("testStackElement_2 test again"); - } assertEquals(1, matches.size()); } diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.ui/META-INF/MANIFEST.MF 2022-11-07 18:51:46.000000000 +0000 @@ -2,7 +2,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jdt.debug.ui; singleton:=true -Bundle-Version: 3.12.600.qualifier +Bundle-Version: 3.12.900.qualifier Bundle-Activator: org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin @@ -38,15 +38,15 @@ org.eclipse.core.filebuffers;bundle-version="[3.5.0,4.0.0)", org.eclipse.core.variables;bundle-version="[3.2.0,4.0.0)", org.eclipse.core.expressions;bundle-version="[3.4.0,4.0.0)", - org.eclipse.jdt.core;bundle-version="[3.28.0,4.0.0)", + org.eclipse.jdt.core;bundle-version="[3.32.0,4.0.0)", org.eclipse.debug.ui;bundle-version="[3.13.400,4.0.0)", - org.eclipse.jdt.debug;bundle-version="[3.19.0,4.0.0)", + org.eclipse.jdt.debug;bundle-version="[3.20.0,4.0.0)", org.eclipse.jdt.launching;bundle-version="[3.19.0,4.0.0)", - org.eclipse.jdt.ui;bundle-version="[3.26.0,4.0.0)", + org.eclipse.jdt.ui;bundle-version="[3.27.0,4.0.0)", org.eclipse.core.runtime;bundle-version="[3.11.0,4.0.0)", org.eclipse.ltk.core.refactoring;bundle-version="[3.5.0,4.0.0)", org.eclipse.ui.console;bundle-version="[3.4.0,4.0.0)", - org.eclipse.jdt.core.manipulation;bundle-version="[1.14.0,2.0.0)", + org.eclipse.jdt.core.manipulation;bundle-version="[1.16.0,2.0.0)", org.eclipse.search;bundle-version="[3.5.0,4.0.0)", com.ibm.icu, org.eclipse.ui.forms;bundle-version="[3.4.0,4.0.0)", diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.ui/plugin.xml eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.ui/plugin.xml --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.ui/plugin.xml 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.ui/plugin.xml 2022-11-07 18:51:46.000000000 +0000 @@ -935,6 +935,16 @@ + + + + + + @@ -3532,6 +3542,26 @@ + + + + + + + + diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.ui/pom.xml eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.ui/pom.xml --- eclipse-jdt-debug-4.23/org.eclipse.jdt.debug.ui/pom.xml 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.debug.ui/pom.xml 2022-11-07 18:51:46.000000000 +0000 @@ -1,6 +1,6 @@ @@ -362,6 +362,16 @@ description="%environment.description.21" id="JavaSE-17" compliance="17"> + + + + eclipse.jdt.debug eclipse.jdt.debug - 4.23.0-SNAPSHOT + 4.26.0-SNAPSHOT org.eclipse.jdt org.eclipse.jdt.launching - 3.19.500-SNAPSHOT + 3.19.800-SNAPSHOT eclipse-plugin diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.javaagent/.classpath eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.javaagent/.classpath --- eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.javaagent/.classpath 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.javaagent/.classpath 2022-11-07 18:51:46.000000000 +0000 @@ -1,7 +1,11 @@ - + + + + + diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.javaagent/META-INF/MANIFEST.MF eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.javaagent/META-INF/MANIFEST.MF --- eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.javaagent/META-INF/MANIFEST.MF 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.javaagent/META-INF/MANIFEST.MF 2022-11-07 18:51:46.000000000 +0000 @@ -2,10 +2,10 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jdt.launching.javaagent;singleton:=true -Bundle-Version: 3.9.700.qualifier +Bundle-Version: 3.10.100.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin -Require-Bundle: org.objectweb.asm;bundle-version="[9.2.0,10.0.0)" Bundle-ActivationPolicy: lazy -Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-RequiredExecutionEnvironment: JavaSE-11 Automatic-Module-Name: org.eclipse.jdt.launching.javaagent +Import-Package: org.objectweb.asm;version="[9.4.0,10.0.0)" diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.javaagent/pom.xml eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.javaagent/pom.xml --- eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.javaagent/pom.xml 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.javaagent/pom.xml 2022-11-07 18:51:46.000000000 +0000 @@ -1,6 +1,6 @@ - 1.6 - 1.6 + 1.7 + 1.7 diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.javaagent/.settings/org.eclipse.jdt.core.prefs eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.javaagent/.settings/org.eclipse.jdt.core.prefs --- eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.javaagent/.settings/org.eclipse.jdt.core.prefs 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.javaagent/.settings/org.eclipse.jdt.core.prefs 2022-11-07 18:51:46.000000000 +0000 @@ -17,9 +17,9 @@ org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.compliance=11 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -128,12 +128,13 @@ org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=error org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL,HIGH,HIGH org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX,EXPERIMENTAL,CONTEXTLAUNCHING org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=0 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=0 @@ -141,17 +142,20 @@ org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=0 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=0 org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16 org.eclipse.jdt.core.formatter.alignment_for_compact_if=0 org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16 org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=0 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=0 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=0 org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=0 +org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16 org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=0 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=0 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=0 @@ -235,11 +239,12 @@ org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert @@ -269,6 +274,8 @@ org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert @@ -293,13 +300,17 @@ org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert @@ -346,6 +357,8 @@ org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert @@ -382,9 +395,12 @@ org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert +org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert @@ -410,8 +426,12 @@ org.eclipse.jdt.core.formatter.tabulation.size=4 org.eclipse.jdt.core.formatter.use_on_off_tags=false org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true +org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true +org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true +org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true +org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true +org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true org.eclipse.jdt.core.incompatibleJDKLevel=ignore org.eclipse.jdt.core.incompleteClasspath=error diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.javaagent/src/main/java/org/eclipse/jdt/launching/internal/javaagent/Premain.java eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.javaagent/src/main/java/org/eclipse/jdt/launching/internal/javaagent/Premain.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.javaagent/src/main/java/org/eclipse/jdt/launching/internal/javaagent/Premain.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.javaagent/src/main/java/org/eclipse/jdt/launching/internal/javaagent/Premain.java 2022-11-07 18:51:46.000000000 +0000 @@ -14,7 +14,6 @@ *******************************************************************************/ package org.eclipse.jdt.launching.internal.javaagent; -import java.io.IOException; import java.io.InputStream; import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.IllegalClassFormatException; @@ -77,9 +76,7 @@ } }); - if (debuglog) { - System.err.println("Advanced source lookup enabled."); //$NON-NLS-1$ - } + printErrorMessage("Advanced source lookup enabled.", null, debuglog);//$NON-NLS-1$ } private static short readJavaLangObjectMajor(boolean debuglog) { @@ -88,45 +85,38 @@ final int offset = 6; - final InputStream is = ClassLoader.getSystemResourceAsStream("java/lang/Object.class"); //$NON-NLS-1$ - if (is == null) { - if (debuglog) { - System.err.println("Could not open java/lang/Object.class system resource stream."); //$NON-NLS-1$ + try (InputStream is = ClassLoader.getSystemResourceAsStream("java/lang/Object.class")) {//$NON-NLS-1$ ) + if (is == null) { + printErrorMessage("Could not open java/lang/Object.class system resource stream.", null, debuglog);//$NON-NLS-1$ + return -1; } - return -1; - } - - byte[] bytes = new byte[offset + 2]; - try { - try { - if (is.read(bytes) < bytes.length) { - if (debuglog) { - System.err.println("Could not read java/lang/Object.class system resource stream."); //$NON-NLS-1$ - } - return -1; - } + byte[] bytes = new byte[offset + 2]; + if (is.read(bytes) < bytes.length) { + printErrorMessage("Could not read java/lang/Object.class system resource stream.", null, debuglog);//$NON-NLS-1$ + return -1; } - finally { - is.close(); + + int magic = ((bytes[0] & 0xFF) << 24) | ((bytes[1] & 0xFF) << 16) | ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF); + if (magic != 0xCAFEBABE) { + printErrorMessage("Invalid java/lang/Object.class magic.", null, debuglog);//$NON-NLS-1$ + return -1; } + + return (short) (((bytes[offset] & 0xFF) << 8) | (bytes[offset + 1] & 0xFF)); } - catch (IOException e) { - if (debuglog) { - System.err.println("Could not read java/lang/Object.class system resource stream."); //$NON-NLS-1$ - e.printStackTrace(System.err); - } + catch (Exception ex) { + printErrorMessage("Could not open java/lang/Object.class system resource stream.", ex, debuglog);//$NON-NLS-1$ return -1; } + } - int magic = ((bytes[0] & 0xFF) << 24) | ((bytes[1] & 0xFF) << 16) | ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF); - if (magic != 0xCAFEBABE) { - if (debuglog) { - System.err.println("Invalid java/lang/Object.class magic."); //$NON-NLS-1$ + private static void printErrorMessage(String errorMessage, Exception ex, boolean debuglog) { + if (debuglog) { + System.err.println(errorMessage); + if (ex != null) { + ex.printStackTrace(System.err); } - return -1; } - - return (short) (((bytes[offset] & 0xFF) << 8) | (bytes[offset + 1] & 0xFF)); } } diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.javaagent/src/main/java/org/eclipse/jdt/launching/internal/weaving/ClassfileTransformer.java eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.javaagent/src/main/java/org/eclipse/jdt/launching/internal/weaving/ClassfileTransformer.java --- eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.javaagent/src/main/java/org/eclipse/jdt/launching/internal/weaving/ClassfileTransformer.java 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.javaagent/src/main/java/org/eclipse/jdt/launching/internal/weaving/ClassfileTransformer.java 2022-11-07 18:51:46.000000000 +0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014, 2019 Igor Fedorenko + * Copyright (c) 2014, 2022 Igor Fedorenko * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -25,7 +25,7 @@ private static final String STRATA_ID = "jdt"; //$NON-NLS-1$ /** max supported java class format major version, must match {@link #ASM_API} below **/ - public static final int MAX_CLASS_MAJOR = Opcodes.V18; + public static final int MAX_CLASS_MAJOR = Opcodes.V20; /** supported ASM API version, must match {@link #MAX_CLASS_MAJOR} above */ private static final int ASM_API = Opcodes.ASM9; diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.macosx/.classpath eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.macosx/.classpath --- eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.macosx/.classpath 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.macosx/.classpath 2022-11-07 18:51:46.000000000 +0000 @@ -1,6 +1,10 @@ - + + + + + diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.macosx/META-INF/MANIFEST.MF eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.macosx/META-INF/MANIFEST.MF --- eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.macosx/META-INF/MANIFEST.MF 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.macosx/META-INF/MANIFEST.MF 2022-11-07 18:51:46.000000000 +0000 @@ -2,18 +2,18 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jdt.launching.macosx; singleton:=true -Bundle-Version: 3.4.800.qualifier +Bundle-Version: 3.5.100.qualifier Bundle-Activator: org.eclipse.jdt.internal.launching.macosx.MacOSXLaunchingPlugin Bundle-Vendor: %providerName Bundle-Localization: plugin Require-Bundle: org.eclipse.debug.core;bundle-version="[3.12.0,4.0.0)", - org.eclipse.jdt.debug;bundle-version="[3.17.0,4.0.0)", + org.eclipse.jdt.debug;bundle-version="[3.20.0,4.0.0)", org.eclipse.core.runtime;bundle-version="[3.11.0,4.0.0)", - org.eclipse.jdt.core;bundle-version="[3.28.0,4.0.0)", + org.eclipse.jdt.core;bundle-version="[3.32.0,4.0.0)", org.eclipse.jdt.launching;bundle-version="[3.19.0,4.0.0)" Eclipse-LazyStart: true Eclipse-PlatformFilter: (osgi.os=macosx) -Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.jdt.internal.launching.macosx;x-internal:=true Automatic-Module-Name: org.eclipse.jdt.launching.macosx diff -Nru eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.macosx/pom.xml eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.macosx/pom.xml --- eclipse-jdt-debug-4.23/org.eclipse.jdt.launching.macosx/pom.xml 2022-03-01 05:51:47.000000000 +0000 +++ eclipse-jdt-debug-4.26/org.eclipse.jdt.launching.macosx/pom.xml 2022-11-07 18:51:46.000000000 +0000 @@ -1,6 +1,6 @@