diff --git a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin26.jar b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin26.jar
new file mode 100644
index 00000000000..03d5e34b0dc
Binary files /dev/null and b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin26.jar differ
diff --git a/org.eclipse.jdt.core.tests.model/JCL/converterJclMin26src.zip b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin26src.zip
new file mode 100644
index 00000000000..25d780f788d
Binary files /dev/null and b/org.eclipse.jdt.core.tests.model/JCL/converterJclMin26src.zip differ
diff --git a/org.eclipse.jdt.core.tests.model/JCL/jclMin26.jar b/org.eclipse.jdt.core.tests.model/JCL/jclMin26.jar
index 5da1f58e476..911e641ec26 100644
Binary files a/org.eclipse.jdt.core.tests.model/JCL/jclMin26.jar and b/org.eclipse.jdt.core.tests.model/JCL/jclMin26.jar differ
diff --git a/org.eclipse.jdt.core.tests.model/JCL/jclMin26src.zip b/org.eclipse.jdt.core.tests.model/JCL/jclMin26src.zip
index 19def4c801a..25d780f788d 100644
Binary files a/org.eclipse.jdt.core.tests.model/JCL/jclMin26src.zip and b/org.eclipse.jdt.core.tests.model/JCL/jclMin26src.zip differ
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterMarkdownSnippetTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterMarkdownSnippetTest.java
new file mode 100644
index 00000000000..cc678c9f1b4
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterMarkdownSnippetTest.java
@@ -0,0 +1,612 @@
+/*******************************************************************************
+ * Copyright (c) 2026 IBM 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.tests.dom;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.Javadoc;
+import org.eclipse.jdt.core.dom.TagElement;
+import org.eclipse.jdt.core.dom.TextElement;
+import org.eclipse.jdt.internal.compiler.parser.JavadocTagConstants;
+import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
+
+/**
+ * Class to test DOM/AST nodes built for markdown snippet tags.
+ *
+ * Most of tests are 'automatic'. It means that to add a new tests, you only need to
+ * create one or several CUs and put them in org.eclipse.jdt.core.model.tests/workspace/Converter/src/markdown/testXXX
+ * folder and add the corresponding test in this class:
+ *
+ * public void testXXX() throws JavaModelException {
+ * verifyComments("testXXX");
+ * }
+ *
+ *
+ * Note that when a test fails, the easiest way to debug it is to open
+ * a runtime workbench, create a project 'Converter', delete the default 'src' source folder
+ * and replace it by a linked source to the 'src' folder of org.eclipse.jdt.core.model.tests/workspace/Converter/src
+ * in your workspace.
+ *
+ * Then open the CU on which the test fails in a ASTView and verify the offset/length
+ * of the offending node located at the positions displayed in the console when the test failed...
+ *
+ * Since 3.4, the failing test also provides the comparison between the source of the comment
+ * and the string get from the built DOM/AST nodes in the comment (see {@link ASTConverterJavadocFlattener})
+ * but this may be not enough to see precisely the origin of the problem.
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class ASTConverterMarkdownSnippetTest extends ConverterTestSetup {
+
+ // Flag to know whether Converter directory should be copied from org.eclipse.jdt.core.tests.model project
+ static protected boolean COPY_DIR = true;
+
+ // Test counters
+ protected static int[] TEST_COUNTERS = { 0, 0, 0, 0 };
+ // Unicode tests
+ protected static boolean UNICODE = false;
+ // Unix tests
+ final boolean unix;
+ static final String UNIX_SUPPORT = System.getProperty("unix");
+ // Doc Comment support
+ static final String DOC_COMMENT_SUPPORT = System.getProperty("doc.support");
+ final String docCommentSupport;
+
+ List comments = new ArrayList();
+ // List of tags contained in each comment read from test source.
+ List allTags = new ArrayList();
+ // tags inhibiting inline tags
+ static final String TAG_CODE = "code";
+ static final String TAG_LITERAL = "literal";
+ // Current compilation unit
+ protected ICompilationUnit sourceUnit;
+ // Test package binding
+ protected boolean resolveBinding = true;
+ protected boolean packageBinding = true;
+ // AST Level
+ /** @deprecated using deprecated code */
+ protected int astLevel = AST.JLS23;
+ protected int savedLevel;
+ // Debug
+ protected String prefix = "";
+ protected boolean debug = false;
+ protected StringBuilder problems;
+ protected String compilerOption = JavaCore.IGNORE;
+ protected List failures;
+ Map savedOptions = null;
+
+ private static String SNIPPET_TAG = '@' + new String(JavadocTagConstants.TAG_SNIPPET);
+
+ public ASTConverterMarkdownSnippetTest(String name, String support, String unix) {
+ super(name);
+ this.docCommentSupport = support;
+ this.unix = "true".equals(unix);
+ }
+ public ASTConverterMarkdownSnippetTest(String name) {
+ this(preHyphen(name), nameToSupport(name),
+ name.indexOf(" - Unix") != -1 ? "true" : "false");
+ }
+
+ private static String preHyphen(String name) {
+ int hyphenInd = name.indexOf(" - ");
+ String r = hyphenInd == -1 ? name : name.substring(0, hyphenInd);
+ return r;
+ }
+ private static String nameToSupport(String name) {
+ int ind1 = name.indexOf(" - Doc ");
+ int ind2 = name.lastIndexOf("abled");
+ if( ind1 == -1 || ind2 == -1 )
+ return name;
+ String s = name.substring(name.indexOf(" - Doc ") + 7, name.lastIndexOf("abled") + 5);
+ return s;
+ }
+
+ /* (non-Javadoc)
+ * @see junit.framework.TestCase#getName()
+ */
+ public String getName() {
+ String strUnix = this.unix ? " - Unix" : "";
+ return super.getName()+" - Doc "+this.docCommentSupport+strUnix;
+ }
+
+ public static Test suite() {
+ TestSuite suite = new Suite(ASTConverterMarkdownSnippetTest.class.getName());
+ if (DOC_COMMENT_SUPPORT == null) {
+ buildSuite(suite, JavaCore.ENABLED);
+ buildSuite(suite, JavaCore.DISABLED);
+ } else {
+ String support = DOC_COMMENT_SUPPORT==null ? JavaCore.DISABLED : (DOC_COMMENT_SUPPORT.equals(JavaCore.DISABLED)?JavaCore.DISABLED:JavaCore.ENABLED);
+ buildSuite(suite, support);
+ }
+ return suite;
+ }
+
+ public static void buildSuite(TestSuite suite, String support) {
+ Class c = ASTConverterMarkdownSnippetTest.class;
+ Method[] methods = c.getMethods();
+ for (int i = 0, max = methods.length; i < max; i++) {
+ if (methods[i].getName().startsWith("test")) { //$NON-NLS-1$
+ suite.addTest(new ASTConverterMarkdownSnippetTest(methods[i].getName(), support, UNIX_SUPPORT));
+ }
+ }
+ // when unix support not specified, also run using unix format
+ if (UNIX_SUPPORT == null && JavaCore.ENABLED.equals(support)) {
+ for (int i = 0, max = methods.length; i < max; i++) {
+ if (methods[i].getName().startsWith("test")) { //$NON-NLS-1$
+ suite.addTest(new ASTConverterMarkdownSnippetTest(methods[i].getName(), support, "true"));
+ }
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.core.tests.model.AbstractJavaModelTests#copyDirectory(java.io.File, java.io.File)
+ */
+ @Override
+ protected void copyDirectory(File sourceDir, File targetDir) throws IOException {
+ if (COPY_DIR) {
+ super.copyDirectory(sourceDir, targetDir);
+ } else {
+ targetDir.mkdirs();
+ File sourceFile = new File(sourceDir, ".project");
+ File targetFile = new File(targetDir, ".project");
+ targetFile.createNewFile();
+ copy(sourceFile, targetFile);
+ sourceFile = new File(sourceDir, ".classpath");
+ targetFile = new File(targetDir, ".classpath");
+ targetFile.createNewFile();
+ copy(sourceFile, targetFile);
+ }
+ }
+ /* (non-Javadoc)
+ * @see junit.framework.TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ TEST_COUNTERS[0]++;
+ setCompliancesLevel();
+ this.failures = new ArrayList();
+ this.problems = new StringBuilder();
+ this.workingCopies = null;
+ this.savedLevel = this.astLevel;
+ }
+ @Override
+ protected void tearDown() throws Exception {
+ int size = this.failures.size();
+ String title = size+" positions/bindings were incorrect in "+getName();
+ if (size == 0) {
+ TEST_COUNTERS[1]++;
+ } else if (this.problems.length() > 0) {
+ if (this.debug) {
+ System.out.println("Compilation warnings/errors occured:");
+ System.out.println(this.problems.toString());
+ }
+ TEST_COUNTERS[2]++;
+ } else {
+ TEST_COUNTERS[3]++;
+ System.out.println(title+":");
+ for (int i=0; i 0);
+ super.tearDown();
+
+ // Restore saved ast level
+ this.astLevel = this.savedLevel;
+ }
+
+ @Override
+ public void tearDownSuite() throws Exception {
+ // put default options on project
+ if (this.currentProject != null && this.savedOptions != null) {
+ this.currentProject.setOptions(this.savedOptions);
+ }
+ super.tearDownSuite();
+ if (TEST_COUNTERS[0] != TEST_COUNTERS[1]) {
+ NumberFormat intFormat = NumberFormat.getInstance();
+ intFormat.setMinimumIntegerDigits(3);
+ intFormat.setMaximumIntegerDigits(3);
+ System.out.println("=====================================");
+ System.out.println(intFormat.format(TEST_COUNTERS[0])+" tests have been executed:");
+ System.out.println(" - "+intFormat.format(TEST_COUNTERS[1])+" tests have been actually executed.");
+ System.out.println(" - "+intFormat.format(TEST_COUNTERS[2])+" tests were skipped due to compilation errors.");
+ System.out.println(" - "+intFormat.format(TEST_COUNTERS[3])+" tests failed.");
+ }
+ }
+ @Override
+ public ASTNode runConversion(ICompilationUnit unit, boolean resolveBindings) {
+ return runConversion(AST.JLS23, unit, resolveBindings);
+ }
+ @Override
+ public ASTNode runConversion(char[] source, String unitName, IJavaProject project) {
+ ASTParser parser = ASTParser.newParser(this.astLevel);
+ parser.setSource(source);
+ parser.setUnitName(unitName);
+ parser.setProject(project);
+ parser.setResolveBindings(this.resolveBinding);
+ return parser.createAST(null);
+ }
+
+ @Override
+ public ASTNode runConversion(char[] source, String unitName, IJavaProject project, Map options) {
+ if (project == null) {
+ ASTParser parser = ASTParser.newParser(this.astLevel);
+ parser.setSource(source);
+ parser.setUnitName(unitName);
+ parser.setCompilerOptions(options);
+ parser.setResolveBindings(this.resolveBinding);
+ return parser.createAST(null);
+ }
+ return runConversion(source, unitName, project);
+ }
+ /*
+ * Convert Javadoc source to match markdown.toString().
+ * Store converted comments and their corresponding tags respectively
+ * in comments and allTags fields
+ */
+ char[] getUnicodeSource(char[] source) {
+ int length = source.length;
+ int unicodeLength = length*6;
+ char[] unicodeSource = new char[unicodeLength];
+ int u=0;
+ for (int i=0; i 15 || c1 < 0)
+ || ((c2 = ScannerHelper.getHexadecimalValue(source[i+2])) > 15 || c2 < 0)
+ || ((c3 = ScannerHelper.getHexadecimalValue(source[i+3])) > 15 || c3 < 0)
+ || ((c4 = ScannerHelper.getHexadecimalValue(source[i+4])) > 15 || c4 < 0)) {
+ throw new RuntimeException("Invalid unicode in source at "+i);
+ }
+ for (int j=0; j<4; j++) unicodeSource[u++] = source[++i];
+ } else {
+ unicodeSource[u++] = '\\';
+ unicodeSource[u++] = 'u';
+ unicodeSource[u++] = '0';
+ unicodeSource[u++] = '0';
+ int val = source[i]/16;
+ unicodeSource[u++] = (char) (val<10 ? val+ 0x30 : val-10+0x61);
+ val = source[i]%16;
+ unicodeSource[u++] = (char) (val<10 ? val+ 0x30 : val-10+0x61);
+ }
+ }
+ // Return one well sized array
+ if (u != unicodeLength) {
+ char[] result = new char[u];
+ System.arraycopy(unicodeSource, 0, result, 0, u);
+ return result;
+ }
+ return unicodeSource;
+ }
+
+ /*
+ * Convert Javadoc source to match markdown.toString().
+ * Store converted comments and their corresponding tags respectively
+ * in comments and allTags fields
+ */
+ char[] getUnixSource(char[] source) {
+ int length = source.length;
+ int unixLength = length;
+ char[] unixSource = new char[unixLength];
+ int u=0;
+ for (int i=0; i actual:<"+actual+'>');
+ }
+
+
+ /* (non-Javadoc)
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void verifyComments(String test) throws JavaModelException {
+ ICompilationUnit[] units = getCompilationUnits("Converter_26" , "src", "markdown."+test); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ for (int i=0; i0);
+ for (int i=0; i 0) {
+ this.problems.append(" - "+this.prefix+length+" problems:"); //$NON-NLS-1$
+ for (int i = 0; i < problemsList.length; i++) {
+ this.problems.append(" + ");
+ this.problems.append(problemsList[i]);
+ this.problems.append("\n");
+ }
+ }
+ }
+ unitComments = compilUnit.getCommentList();
+ assumeNotNull(this.prefix+"Unexpected problems", unitComments);
+
+ return compilUnit;
+ }
+ private TagElement getSnippetTag(Javadoc docComment) {
+ TagElement snippet = null;
+ if (docComment != null) {
+ for (Object tag : docComment.tags()) {
+ if (tag instanceof TagElement) {
+ TagElement tagElement = (TagElement) tag;
+ if (SNIPPET_TAG.equals(tagElement.getTagName())) {
+ return tagElement;
+ }
+ List fragments = tagElement.fragments();
+ for (Object fragment : fragments) {
+ if (fragment instanceof TagElement) {
+ TagElement tagElem = (TagElement) fragment;
+ if (SNIPPET_TAG.equals(tagElem.getTagName())) {
+ return tagElem;
+ }
+ }
+ }
+
+ }
+ }
+ }
+ return snippet;
+ }
+
+ // empty body
+ public void testSnippetTagforMarkdown_01() throws JavaModelException {
+ String source = """
+ /// {@snippet :
+ /// }
+ public class Markdown {}
+ """;
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/Converter_26/src/markdown/Markdown.java", source, null);
+ CompilationUnit compilUnit = verifyComments(this.workingCopies[0]);
+ if (this.docCommentSupport.equals(JavaCore.ENABLED)) {
+ List unitComments = compilUnit.getCommentList();
+ int size = unitComments.size();
+ assertEquals("Wrong number of comments", 1, size);
+ Javadoc javadoc = (Javadoc) unitComments.get(0);
+ TagElement snippetTag = getSnippetTag(javadoc);
+ List> frags = snippetTag.fragments();
+ assertEquals("Fragments should be empty", 0, frags.size());
+ }
+ }
+
+ // Single element
+ public void testSnippetMarkdownTest_02() throws JavaModelException {
+ String source = """
+ /// {@snippet:
+ /// int x = 2;
+ /// }
+ public class Markdown {}
+ """;
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/Converter_26/src/markdown/Markdown.java", source, null);
+ if (this.docCommentSupport.equals(JavaCore.ENABLED)) {
+ CompilationUnit compilUnit = verifyComments(this.workingCopies[0]);
+ List unitComments = compilUnit.getCommentList();
+ int size = unitComments.size();
+ assertEquals("Wrong number of comments", 1, size);
+ Javadoc javadoc = (Javadoc) unitComments.get(0);
+ TagElement snippetTag = getSnippetTag(javadoc);
+ List frags = snippetTag.fragments();
+ assertEquals("Fragments should be 1", 1, frags.size());
+ assertEquals("Incorrect text content", " int x = 2;", frags.get(0).getText());
+ }
+ }
+
+ // Blank line inside the body
+ public void testSnippetMarkdownTest_03() throws JavaModelException {
+ String source = """
+ /// {@snippet:
+ ///
+ /// int a = 1;
+ ///
+ /// int b = 2;
+ /// }
+ public class Markdown {}
+ """;
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/Converter_26/src/markdown/Markdown.java", source, null);
+ if (this.docCommentSupport.equals(JavaCore.ENABLED)) {
+ CompilationUnit compilUnit = verifyComments(this.workingCopies[0]);
+ List unitComments = compilUnit.getCommentList();
+ int size = unitComments.size();
+ assertEquals("Wrong number of comments", 1, size);
+ Javadoc javadoc = (Javadoc) unitComments.get(0);
+ TagElement snippetTag = getSnippetTag(javadoc);
+ List frags = snippetTag.fragments();
+ assertEquals("Fragments should be 4", 4, frags.size());
+ assertEquals("Incorrect text content", "", frags.get(0).getText());
+ assertEquals("Incorrect text content", " int a = 1;", frags.get(1).getText());
+ assertEquals("Incorrect text content", "", frags.get(2).getText());
+ assertEquals("Incorrect text content", " int b = 2;", frags.get(3).getText());
+ }
+ }
+
+ // {@code} tag inside the snippet
+ public void testSnippetMarkdownTest_04() throws JavaModelException {
+ String source = """
+ /// {@snippet :
+ /// {@code int a = 0;}
+ /// }
+ """;
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy("/Converter_26/src/markdown/Markdown.java", source, null);
+ if (this.docCommentSupport.equals(JavaCore.ENABLED)) {
+ CompilationUnit compilUnit = verifyComments(this.workingCopies[0]);
+ List unitComments = compilUnit.getCommentList();
+ int size = unitComments.size();
+ assertEquals("Wrong number of comments", 1, size);
+ Javadoc javadoc = (Javadoc) unitComments.get(0);
+ TagElement snippetTag = getSnippetTag(javadoc);
+ List frags = snippetTag.fragments();
+ assertEquals("Fragments should be 1", 1, frags.size());
+ assertEquals("Incorrect text content", " {@code int a = 0;}", frags.get(0).getText());
+ }
+ }
+}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java
index df346273acd..27c98739434 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ConverterTestSetup.java
@@ -99,6 +99,7 @@ public void tearDownSuite() throws Exception {
this.deleteProject("Converter_23"); //$NON-NLS-1$
this.deleteProject("Converter_24"); //$NON-NLS-1$
this.deleteProject("Converter_25"); //$NON-NLS-1$
+ this.deleteProject("Converter_26"); //$NON-NLS-1$
PROJECT_SETUP = false;
} else {
TEST_SUITES.remove(getClass());
@@ -123,6 +124,7 @@ public void tearDownSuite() throws Exception {
this.deleteProject("Converter_23"); //$NON-NLS-1$
this.deleteProject("Converter_24"); //$NON-NLS-1$
this.deleteProject("Converter_25"); //$NON-NLS-1$
+ this.deleteProject("Converter_26"); //$NON-NLS-1$
PROJECT_SETUP = false;
}
}
@@ -290,6 +292,7 @@ public void setUpSuite() throws Exception {
setUpJavaProject("Converter_23", "23"); //$NON-NLS-1$ //$NON-NLS-2$
setUpJavaProject("Converter_24", "24"); //$NON-NLS-1$ //$NON-NLS-2$
setUpJavaProject("Converter_25", "25"); //$NON-NLS-1$ //$NON-NLS-2$
+ setUpJavaProject("Converter_26", "26"); //$NON-NLS-1$ //$NON-NLS-2$
waitUntilIndexesReady(); // needed to find secondary types
PROJECT_SETUP = true;
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java
index 3bc73258e05..20251b4874f 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java
@@ -63,7 +63,8 @@ public static Class[] getAllTestClasses() {
ASTConverterSuperAfterStatements.class,
ASTConverterEitherOrMultiPatternTest.class,
CompilationUnitResolverDiscoveryTest.class,
- ASTConverterMarkdownTest.class
+ ASTConverterMarkdownTest.class,
+ ASTConverterMarkdownSnippetTest.class
};
}
public static Test suite() {
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Converter_26/.classpath b/org.eclipse.jdt.core.tests.model/workspace/Converter_26/.classpath
new file mode 100644
index 00000000000..95b37bfb0a6
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Converter_26/.classpath
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Converter_26/.project b/org.eclipse.jdt.core.tests.model/workspace/Converter_26/.project
new file mode 100644
index 00000000000..690f552399b
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Converter_26/.project
@@ -0,0 +1,17 @@
+
+
+ Converter_25
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/org.eclipse.jdt.core.tests.model/workspace/Converter_26/src/X.java b/org.eclipse.jdt.core.tests.model/workspace/Converter_26/src/X.java
new file mode 100644
index 00000000000..ade997b01dc
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/workspace/Converter_26/src/X.java
@@ -0,0 +1,4 @@
+public/// {
+ public/// {
+ }
+}
\ No newline at end of file