diff --git a/harness/nbjunit/src/org/netbeans/junit/NbTestCase.java b/harness/nbjunit/src/org/netbeans/junit/NbTestCase.java index b7ee78df5493..56738d166ba8 100644 --- a/harness/nbjunit/src/org/netbeans/junit/NbTestCase.java +++ b/harness/nbjunit/src/org/netbeans/junit/NbTestCase.java @@ -739,7 +739,7 @@ static public void assertFile(String message, File test, File pass, File diff, D } else { try { if (diffImpl.diff(test, pass, diffFile)) { - throw new AssertionFileFailedError(message, null == diffFile ? "" : diffFile.getAbsolutePath()); + throw new AssertionFileFailedError(message+"\n diff: "+diffFile, null == diffFile ? "" : diffFile.getAbsolutePath()); } } catch (IOException e) { fail("exception in assertFile : " + e.getMessage()); @@ -760,7 +760,7 @@ static public void assertFile(String message, File test, File pass, File diff, D * already initialized, when passed in this assertFile function. */ static public void assertFile(File test, File pass, File diff, Diff externalDiff) { - assertFile(null, test, pass, diff, externalDiff); + assertFile("Difference between " + test + " and " + pass, test, pass, diff, externalDiff); } /** * Asserts that two files are the same, it compares two files and stores possible differences @@ -789,7 +789,7 @@ static public void assertFile(String message, File test, File pass, File diff) { * by the '.diff'. */ static public void assertFile(File test, File pass, File diff) { - assertFile(null, test, pass, diff, null); + assertFile("Difference between " + test + " and " + pass, test, pass, diff, null); } /** * Asserts that two files are the same, it just compares two files and doesn't produce any additional output. diff --git a/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java b/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java index 2e8db5f7cc2b..bdb37a32ead6 100644 --- a/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java +++ b/java/java.completion/src/org/netbeans/modules/java/completion/JavaCompletionTask.java @@ -4859,12 +4859,18 @@ private void addClassModifiers(Env env, Set modifiers) { if (!modifiers.contains(PUBLIC) && !modifiers.contains(PRIVATE)) { kws.add(PUBLIC_KEYWORD); } - if (!modifiers.contains(FINAL) && !modifiers.contains(ABSTRACT) && !modifiers.contains(SEALED_KEYWORD) && !modifiers.contains(NON_SEALED_KEYWORD)) { - kws.add(ABSTRACT_KEYWORD); - kws.add(FINAL_KEYWORD); - if (isSealedSupported(env)) { - kws.add(SEALED_KEYWORD); - kws.add(NON_SEALED_KEYWORD); + if (!modifiers.contains(FINAL)) { + if (!modifiers.contains(ABSTRACT)) { + kws.add(ABSTRACT_KEYWORD); + } + if (!contains(modifiers, "SEALED") && !contains(modifiers, "NON_SEALED")) { + if (!modifiers.contains(ABSTRACT)) { + kws.add(FINAL_KEYWORD); + } + if (isSealedSupported(env)) { + kws.add(SEALED_KEYWORD); + kws.add(NON_SEALED_KEYWORD); + } } } kws.add(CLASS_KEYWORD); @@ -4880,6 +4886,14 @@ private void addClassModifiers(Env env, Set modifiers) { } } + private static boolean contains(Set modifiers, String modifier) { + try { + return modifiers.contains(Modifier.valueOf(modifier)); + } catch (IllegalArgumentException ex) { + return false; + } + } + private void addMemberModifiers(Env env, Set modifiers, boolean isLocal) { String prefix = env.getPrefix(); List kws = new ArrayList<>(); diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/afterAbstract.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/afterAbstract.pass new file mode 100644 index 000000000000..35f2d0a1f951 --- /dev/null +++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/afterAbstract.pass @@ -0,0 +1,6 @@ +class +enum +interface +non-sealed +record +sealed diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/afterSealed.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/afterSealed.pass new file mode 100644 index 000000000000..d00a16d3b48a --- /dev/null +++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/afterSealed.pass @@ -0,0 +1,4 @@ +class +enum +interface +record diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/afterSealedClassName.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/afterSealedClassName.pass new file mode 100644 index 000000000000..d9f7e7b6b36c --- /dev/null +++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/afterSealedClassName.pass @@ -0,0 +1,3 @@ +extends +implements +permits diff --git a/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/finalClass.pass b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/finalClass.pass new file mode 100644 index 000000000000..d00a16d3b48a --- /dev/null +++ b/java/java.completion/test/unit/data/goldenfiles/org/netbeans/modules/java/completion/JavaCompletionTaskTest/1.8/finalClass.pass @@ -0,0 +1,4 @@ +class +enum +interface +record diff --git a/java/java.completion/test/unit/data/org/netbeans/modules/java/completion/data/Sealed.java b/java/java.completion/test/unit/data/org/netbeans/modules/java/completion/data/Sealed.java new file mode 100644 index 000000000000..a3f72c2758be --- /dev/null +++ b/java/java.completion/test/unit/data/org/netbeans/modules/java/completion/data/Sealed.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package test; + +public abstract sealed class Shape permits Circle, Rectangle { + +} diff --git a/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask115FeaturesTest.java b/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask115FeaturesTest.java new file mode 100644 index 000000000000..dc2370deb38a --- /dev/null +++ b/java/java.completion/test/unit/src/org/netbeans/modules/java/completion/JavaCompletionTask115FeaturesTest.java @@ -0,0 +1,107 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.netbeans.modules.java.completion; + +import java.util.ArrayList; +import java.util.List; +import javax.lang.model.SourceVersion; +import javax.swing.event.ChangeListener; +import org.netbeans.junit.NbTestSuite; +import org.netbeans.modules.java.source.parsing.JavacParser; +import org.netbeans.spi.java.queries.CompilerOptionsQueryImplementation; +import org.openide.filesystems.FileObject; +import org.openide.util.lookup.ServiceProvider; + +/** + * + * @author mbien + */ +public class JavaCompletionTask115FeaturesTest extends CompletionTestBase { + + private static final String SOURCE_LEVEL = "15"; + + static { + JavacParser.DISABLE_SOURCE_LEVEL_DOWNGRADE = true; + } + + public JavaCompletionTask115FeaturesTest(String testName) { + super(testName); + } + + public static NbTestSuite suite() { + NbTestSuite suite = new NbTestSuite(); + try { + SourceVersion.valueOf("RELEASE_"+SOURCE_LEVEL); + suite.addTestSuite(JavaCompletionTask115FeaturesTest.class); + } catch (IllegalArgumentException ex) { + suite.addTest(new JavaCompletionTask115FeaturesTest("noop")); + } + return suite; + } + + public void noop() { } + + + public void testFinalCantBeSealed() throws Exception { + TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--enable-preview"); + performTest("Sealed", 831, "final ", "finalClass.pass", getLatestSource()); + } + + public void testAbstractCanBeSealed() throws Exception { + TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--enable-preview"); + performTest("Sealed", 840, null, "afterAbstract.pass", getLatestSource()); + } + + public void testAfterSealed() throws Exception { + TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--enable-preview"); + performTest("Sealed", 847, null, "afterSealed.pass", getLatestSource()); + } + + public void testPermitsAfterSealedClassName() throws Exception { + TestCompilerOptionsQueryImplementation.EXTRA_OPTIONS.add("--enable-preview"); + performTest("Sealed", 859, null, "afterSealedClassName.pass", getLatestSource()); + } + + private String getLatestSource() { + return SourceVersion.latest().name().substring(SourceVersion.latest().name().indexOf("_")+1); + } + + + @ServiceProvider(service = CompilerOptionsQueryImplementation.class, position = 100) + public static class TestCompilerOptionsQueryImplementation implements CompilerOptionsQueryImplementation { + + private static final List EXTRA_OPTIONS = new ArrayList<>(); + + @Override + public CompilerOptionsQueryImplementation.Result getOptions(FileObject file) { + return new CompilerOptionsQueryImplementation.Result() { + @Override + public List getArguments() { + return EXTRA_OPTIONS; + } + + @Override + public void addChangeListener(ChangeListener listener) {} + + @Override + public void removeChangeListener(ChangeListener listener) {} + }; + } + } +}