diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ASTBasedDeclarationImpl.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ASTBasedDeclarationImpl.java index a612dcee4fa..0fddeb87022 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ASTBasedDeclarationImpl.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/ASTBasedDeclarationImpl.java @@ -28,7 +28,6 @@ import org.eclipse.jdt.core.dom.IAnnotationBinding; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.VariableDeclaration; -import org.eclipse.jdt.core.dom.VariableDeclarationFragment; import com.sun.mirror.declaration.AnnotationMirror; import com.sun.mirror.declaration.Modifier; @@ -76,7 +75,7 @@ public Collection getModifiers() else if( _astNode instanceof SingleVariableDeclaration ) modBits = ((SingleVariableDeclaration)_astNode).getModifiers(); else{ - ASTNode parent = ((VariableDeclarationFragment)_astNode).getParent(); + ASTNode parent = _astNode.getParent(); if( _astNode instanceof BodyDeclaration ) modBits = ((BodyDeclaration)parent).getModifiers(); } @@ -148,7 +147,7 @@ private IAnnotationBinding[] getAnnotationInstancesFromAST() extendsMods = ((SingleVariableDeclaration)_astNode).modifiers(); break; case ASTNode.VARIABLE_DECLARATION_FRAGMENT: - final ASTNode parent = ((VariableDeclarationFragment)_astNode).getParent(); + final ASTNode parent = _astNode.getParent(); if( parent instanceof BodyDeclaration ) extendsMods = ((BodyDeclaration)parent).modifiers(); break; diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/MemberDeclarationImpl.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/MemberDeclarationImpl.java index 6e883f8ce59..6625632e27f 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/MemberDeclarationImpl.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/declaration/MemberDeclarationImpl.java @@ -59,13 +59,13 @@ private IAnnotationBinding[] getAnnotationInstances() switch( binding.getKind() ) { case IBinding.TYPE: - instances = ((ITypeBinding)binding).getAnnotations(); + instances = binding.getAnnotations(); break; case IBinding.METHOD: - instances = ((IMethodBinding)binding).getAnnotations(); + instances = binding.getAnnotations(); break; case IBinding.VARIABLE: - instances = ((IVariableBinding)binding).getAnnotations(); + instances = binding.getAnnotations(); break; case IBinding.PACKAGE: // TODO: support package annotation diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BinaryFileOutputStream.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BinaryFileOutputStream.java index 3c4eb8acc6c..c92f85dad66 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BinaryFileOutputStream.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/env/BinaryFileOutputStream.java @@ -14,17 +14,13 @@ *******************************************************************************/ package org.eclipse.jdt.apt.core.internal.env; -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.InputStream; +import java.util.Arrays; import java.util.Collections; import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; -import org.eclipse.jdt.apt.core.internal.AptPlugin; import org.eclipse.jdt.apt.core.internal.util.FileSystemUtil; /** @@ -46,40 +42,20 @@ public BinaryFileOutputStream(IFile file, BuildEnv env) { public void close() throws IOException { super.close(); - InputStream contents = new ByteArrayInputStream(toByteArray()); + byte[] newContent = toByteArray(); + boolean contentsChanged = true; try { - - boolean contentsChanged = true; - if (!_file.exists()) { - saveToDisk(contents, true); - } - else { - InputStream in = null; - InputStream oldData = null; - try { - // Only write the contents if the data is different - in = new ByteArrayInputStream(toByteArray()); - oldData = new BufferedInputStream(_file.getContents()); - if (FileSystemUtil.compareStreams(in, oldData)) { - contentsChanged = false; - } - } - catch (CoreException ce) { - // Ignore -- couldn't read the old data, so assume it's different - contentsChanged = true; - } - finally { - closeInputStream(in); - closeInputStream(oldData); - } - if (contentsChanged) { - contents.reset(); - saveToDisk(contents, false); - } + // Only write the contents if the data is different + byte[] oldContent = _file.readAllBytes(); + if (Arrays.equals(newContent, oldContent)) { + contentsChanged = false; } + } catch (CoreException ce) { + // Ignore -- couldn't read the old data, so assume it's different + contentsChanged = true; } - finally { - closeInputStream(contents); + if (contentsChanged) { + FileSystemUtil.saveToDisk(_file, newContent); } IFile parentFile = _env.getFile(); @@ -88,35 +64,4 @@ public void close() throws IOException { _env.addGeneratedNonSourceFile(_file); } } - - private void closeInputStream(InputStream stream) { - if (stream != null) { - try { - stream.close(); - } - catch (IOException ioe) {} - } - } - - private void saveToDisk(InputStream toSave, boolean create) throws IOException{ - try { - FileSystemUtil.makeDerivedParentFolders(_file.getParent()); - if (create) { - _file.create(toSave, IResource.FORCE | IResource.DERIVED, null); - } else { - _file.setContents(toSave, true, false, null); - } - } - catch (CoreException ce) { - if (_file.exists()) { - // Do nothing. This is a case-insensitive file system mismatch, - // and the underlying platform has saved the contents already. - } - else { - AptPlugin.log(ce, "Could not create generated file"); //$NON-NLS-1$ - throw new IOException(ce.getMessage(), ce); - } - } - } - } diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/FileSystemUtil.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/FileSystemUtil.java index e90093cc0a5..199655c1d27 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/FileSystemUtil.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/FileSystemUtil.java @@ -14,7 +14,6 @@ package org.eclipse.jdt.apt.core.internal.util; import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -124,6 +123,21 @@ public static void makeDerivedParentFolders (IContainer container) throws CoreEx container.setDerived(true, null); } } + public static void saveToDisk(IFile file, byte[] toSave) throws IOException{ + try { + FileSystemUtil.makeDerivedParentFolders(file.getParent()); + file.write(toSave, true, true, false, null); + } catch (CoreException ce) { + if (file.exists()) { + // Do nothing. This is a case-insensitive file system mismatch, + // and the underlying platform has saved the contents already. + } + else { + AptPlugin.log(ce, "Could not create generated file"); //$NON-NLS-1$ + throw new IOException(ce.getMessage(), ce); + } + } + } /** * Returns the contents of a IFile as a string in UTF8 format @@ -145,21 +159,20 @@ public static String getContentsOfFile(File file) throws IOException { * @throws IOException * @throws CoreException */ - public static void writeStringToIFile(IFile file, String contents) throws IOException, CoreException { - byte[] data = contents.getBytes("UTF8"); //$NON-NLS-1$ - ByteArrayInputStream input = new ByteArrayInputStream(data); - if (file.exists()) { - if (file.isReadOnly()) { + public static void writeStringToIFile(IFile file, String contents) throws IOException, CoreException { + byte[] data = contents.getBytes(StandardCharsets.UTF_8); + try { + file.write(data, true, false, false, null); + } catch (CoreException e) { + if (file.exists() && file.isReadOnly()) { // provide opportunity to checkout read-only .factorypath file - ResourcesPlugin.getWorkspace().validateEdit(new IFile[]{file}, null); + ResourcesPlugin.getWorkspace().validateEdit(new IFile[] { file }, null); + file.write(data, true, false, false, null); + } else { + throw e; } - file.setContents(input, true, false, null); - } - else { - // Even with FORCE, create() will still throw if the file already exists. - file.create(input, IResource.FORCE, null); - } - } + } + } /** * Stores a string into an ordinary workspace file in UTF8 format. diff --git a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/TestCodeUtil.java b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/TestCodeUtil.java index 810a70a0d3b..22e3cdcb0ec 100644 --- a/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/TestCodeUtil.java +++ b/org.eclipse.jdt.apt.core/src/org/eclipse/jdt/apt/core/internal/util/TestCodeUtil.java @@ -24,7 +24,7 @@ private TestCodeUtil() { } public static boolean isTestCode(ICompilationUnit cu) { - IPackageFragmentRoot packageFragmentRoot = (IPackageFragmentRoot) ((IJavaElement) cu) + IPackageFragmentRoot packageFragmentRoot = (IPackageFragmentRoot) cu .getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); if (packageFragmentRoot != null) { try { diff --git a/org.eclipse.jdt.apt.pluggable.core/META-INF/MANIFEST.MF b/org.eclipse.jdt.apt.pluggable.core/META-INF/MANIFEST.MF index c71479cf71d..722e0e78315 100644 --- a/org.eclipse.jdt.apt.pluggable.core/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.apt.pluggable.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jdt.apt.pluggable.core;singleton:=true -Bundle-Version: 1.4.400.qualifier +Bundle-Version: 1.4.500.qualifier Bundle-Activator: org.eclipse.jdt.internal.apt.pluggable.core.Apt6Plugin Bundle-Vendor: %providerName Require-Bundle: org.eclipse.core.runtime, diff --git a/org.eclipse.jdt.apt.pluggable.core/src/org/eclipse/jdt/internal/apt/pluggable/core/filer/IdeClassOutputStream.java b/org.eclipse.jdt.apt.pluggable.core/src/org/eclipse/jdt/internal/apt/pluggable/core/filer/IdeClassOutputStream.java index d253e66c75a..c9afbf8e782 100644 --- a/org.eclipse.jdt.apt.pluggable.core/src/org/eclipse/jdt/internal/apt/pluggable/core/filer/IdeClassOutputStream.java +++ b/org.eclipse.jdt.apt.pluggable.core/src/org/eclipse/jdt/internal/apt/pluggable/core/filer/IdeClassOutputStream.java @@ -14,14 +14,10 @@ package org.eclipse.jdt.internal.apt.pluggable.core.filer; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.InputStream; import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.apt.core.internal.util.FileSystemUtil; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.apt.pluggable.core.Apt6Plugin; @@ -49,21 +45,11 @@ public IdeClassOutputStream(IdeProcessingEnvImpl env, IFile file) { public void close() throws IOException { super.close(); byte[] byteArray = toByteArray(); - InputStream contents = new ByteArrayInputStream(byteArray); Compiler compiler = this._env.getCompiler(); IBinaryType binaryType = null; try { - try { - binaryType = ClassFileReader.read(this._file.getLocation().toString()); - } catch(IOException ioe) { - // Files doesn't yet exist - } - if (binaryType == null) { - saveToDisk(contents, true); - } else { - saveToDisk(contents, false); - } + FileSystemUtil.saveToDisk(_file, byteArray); binaryType = ClassFileReader.read(this._file.getLocation().toString()); char[][] splitOn = CharOperation.splitOn('/', binaryType.getName()); ReferenceBinding type = compiler.lookupEnvironment.getType(splitOn); @@ -79,37 +65,5 @@ public void close() throws IOException { } catch(Exception ex) { Apt6Plugin.log(ex, "Could not create generated class file " + _file.getName()); //$NON-NLS-1$ } - finally { - closeInputStream(contents); - } - } - - private void closeInputStream(InputStream stream) { - if (stream != null) { - try { - stream.close(); - } catch (IOException ioe) { - // Nothing to do - } - } - } - private void saveToDisk(InputStream toSave, boolean create) throws IOException{ - try { - FileSystemUtil.makeDerivedParentFolders(_file.getParent()); - if (create) { - _file.create(toSave, IResource.FORCE | IResource.DERIVED, null); - } else { - _file.setContents(toSave, true, false, null); - } - } - catch (CoreException ce) { - if (_file.exists()) { - // Do nothing. This is a case-insensitive file system mismatch, - // and the underlying platform has saved the contents already. - } else { - Apt6Plugin.log(ce, "Could not create generated class file " + _file.getName()); //$NON-NLS-1$ - throw new IOException(ce); - } - } } } diff --git a/org.eclipse.jdt.apt.pluggable.core/src/org/eclipse/jdt/internal/apt/pluggable/core/filer/IdeNonSourceOutputStream.java b/org.eclipse.jdt.apt.pluggable.core/src/org/eclipse/jdt/internal/apt/pluggable/core/filer/IdeNonSourceOutputStream.java index a466bb8b80f..db7abad76f7 100644 --- a/org.eclipse.jdt.apt.pluggable.core/src/org/eclipse/jdt/internal/apt/pluggable/core/filer/IdeNonSourceOutputStream.java +++ b/org.eclipse.jdt.apt.pluggable.core/src/org/eclipse/jdt/internal/apt/pluggable/core/filer/IdeNonSourceOutputStream.java @@ -14,19 +14,15 @@ package org.eclipse.jdt.internal.apt.pluggable.core.filer; -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.InputStream; +import java.util.Arrays; import java.util.Collection; import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.apt.core.internal.env.BinaryFileOutputStream; import org.eclipse.jdt.apt.core.internal.util.FileSystemUtil; -import org.eclipse.jdt.internal.apt.pluggable.core.Apt6Plugin; import org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeProcessingEnvImpl; /** @@ -48,40 +44,20 @@ public IdeNonSourceOutputStream(IdeProcessingEnvImpl env, IFile file, Collection public void close() throws IOException { super.close(); - InputStream contents = new ByteArrayInputStream(toByteArray()); + byte[] newContent = toByteArray(); + boolean contentsChanged = true; try { - - boolean contentsChanged = true; - if (!_file.exists()) { - saveToDisk(contents, true); - } - else { - InputStream in = null; - InputStream oldData = null; - try { - // Only write the contents if the data is different - in = new ByteArrayInputStream(toByteArray()); - oldData = new BufferedInputStream(_file.getContents()); - if (FileSystemUtil.compareStreams(in, oldData)) { - contentsChanged = false; - } - } - catch (CoreException ce) { - // Ignore -- couldn't read the old data, so assume it's different - contentsChanged = true; - } - finally { - closeInputStream(in); - closeInputStream(oldData); - } - if (contentsChanged) { - contents.reset(); - saveToDisk(contents, false); - } + // Only write the contents if the data is different + byte[] oldContent = _file.readAllBytes(); + if (Arrays.equals(newContent, oldContent)) { + contentsChanged = false; } + } catch (CoreException ce) { + // Ignore -- couldn't read the old data, so assume it's different + contentsChanged = true; } - finally { - closeInputStream(contents); + if (contentsChanged) { + FileSystemUtil.saveToDisk(_file, newContent); } // If there are no parents, we don't need to track dependencies @@ -90,36 +66,4 @@ public void close() throws IOException { _env.addNewResource(_file); } } - - private void closeInputStream(InputStream stream) { - if (stream != null) { - try { - stream.close(); - } - catch (IOException ioe) {} - } - } - - private void saveToDisk(InputStream toSave, boolean create) throws IOException{ - try { - FileSystemUtil.makeDerivedParentFolders(_file.getParent()); - if (create) { - _file.create(toSave, IResource.FORCE | IResource.DERIVED, null); - } - else { - _file.setContents(toSave, true, false, null); - } - } - catch (CoreException ce) { - if (_file.exists()) { - // Do nothing. This is a case-insensitive file system mismatch, - // and the underlying platform has saved the contents already. - } - else { - Apt6Plugin.log(ce, "Could not create generated non-Java file " + _file.getName()); //$NON-NLS-1$ - throw new IOException(ce); - } - } - } - } diff --git a/org.eclipse.jdt.apt.pluggable.tests/META-INF/MANIFEST.MF b/org.eclipse.jdt.apt.pluggable.tests/META-INF/MANIFEST.MF index 5676a12dd2d..ada8f22e8e9 100644 --- a/org.eclipse.jdt.apt.pluggable.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.apt.pluggable.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jdt.apt.pluggable.tests;singleton:=true -Bundle-Version: 3.6.400.qualifier +Bundle-Version: 3.6.500.qualifier Bundle-Activator: org.eclipse.jdt.apt.pluggable.tests.Apt6TestsPlugin Bundle-Localization: plugin Require-Bundle: org.junit, diff --git a/org.eclipse.jdt.apt.pluggable.tests/pom.xml b/org.eclipse.jdt.apt.pluggable.tests/pom.xml index 99b8b356f1e..7bd9f16f03d 100644 --- a/org.eclipse.jdt.apt.pluggable.tests/pom.xml +++ b/org.eclipse.jdt.apt.pluggable.tests/pom.xml @@ -19,7 +19,7 @@ ../tests-pom/ org.eclipse.jdt.apt.pluggable.tests - 3.6.400-SNAPSHOT + 3.6.500-SNAPSHOT eclipse-test-plugin ${project.artifactId} diff --git a/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/FilerTests.java b/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/FilerTests.java index 3f32e5ac7f4..3f887fef48c 100644 --- a/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/FilerTests.java +++ b/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/FilerTests.java @@ -14,9 +14,7 @@ package org.eclipse.jdt.apt.pluggable.tests; -import java.io.ByteArrayInputStream; import java.io.File; -import java.io.InputStream; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; @@ -230,8 +228,7 @@ public void testGetResource02() throws Throwable { IFolder textFileFolder = proj.getFolder("src/t"); textFileFolder.create(false, true, null); IFile textFile = proj.getFile(textFileFolder.getProjectRelativePath().append("Test.txt")); - InputStream textSource = new ByteArrayInputStream(FilerTesterProc.resource02FileContents.getBytes()); - textFile.create(textSource, false, null); + textFile.create(FilerTesterProc.resource02FileContents.getBytes(), false, false, null); fullBuild(); expectingNoProblems(); @@ -319,8 +316,7 @@ public void testURI() throws Throwable { IFolder textFileFolder = proj.getFolder("src/t"); textFileFolder.create(false, true, null); IFile textFile = proj.getFile(textFileFolder.getProjectRelativePath().append("Test.txt")); - InputStream textSource = new ByteArrayInputStream(FilerTesterProc.helloStr.getBytes()); - textFile.create(textSource, false, null); + textFile.create(FilerTesterProc.helloStr.getBytes(), false, false, null); AptConfig.setEnabled(jproj, true); diff --git a/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/TestBase.java b/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/TestBase.java index 05d3304d8c4..3c256d7a621 100644 --- a/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/TestBase.java +++ b/org.eclipse.jdt.apt.pluggable.tests/src/org/eclipse/jdt/apt/pluggable/tests/TestBase.java @@ -63,18 +63,16 @@ public static Test suite() { private static void addAnnotationJar(IJavaProject jproj, boolean addToModulePath) throws Exception { final String resName = "lib/annotations.jar"; // name in bundle final String libName = resName; // name in destination project - InputStream is = null; URL resURL = Apt6TestsPlugin.thePlugin().getBundle().getEntry(resName); - is = resURL.openStream(); + byte[] bytes; + try (InputStream is = resURL.openStream()) { + bytes= is.readAllBytes(); + } IPath projPath = jproj.getPath(); IProject proj = jproj.getProject(); IFile libFile = proj.getFile(libName); env.addFolder(projPath, "lib"); - if (libFile.exists()) { - libFile.setContents(is, true, false, null); - } else { - libFile.create(is, true, null); - } + libFile.write(bytes, true, false, false, null); if (addToModulePath) { IClasspathAttribute[] attributes = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") }; env.addEntry(projPath, JavaCore.newLibraryEntry(libFile.getFullPath(), null, null, diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java index da73d9101b8..e78f05658f9 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java @@ -175,7 +175,7 @@ public R accept(ElementVisitor visitor, P param) { } @Override protected AnnotationBinding[] getAnnotationBindings() { - return ((ModuleBinding) this._binding).getAnnotations(); + return this._binding.getAnnotations(); } abstract class PackageDirectiveImpl { diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java index f1e94a9c97d..ac94a2af8eb 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java @@ -107,7 +107,7 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks; boolean hasResourceWrapperType = analyseResources && this.resolvedType instanceof ReferenceBinding - && ((ReferenceBinding)this.resolvedType).hasTypeBit(TypeIds.BitWrapperCloseable); + && this.resolvedType.hasTypeBit(TypeIds.BitWrapperCloseable); for (int i = 0, count = this.arguments.length; i < count; i++) { Expression argument = this.arguments[i]; flowInfo = diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Expression.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Expression.java index f5883da658b..db2e4adff30 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Expression.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Expression.java @@ -462,6 +462,8 @@ public final boolean checkCastTypesCompatibility(Scope scope, TypeBinding castTy if (match != null) { return checkUnsafeCast(scope, castType, interfaceType, match, true); } + if (((ReferenceBinding) castType).isDisjointFrom(interfaceType)) + return false; if (use15specifics) { checkUnsafeCast(scope, castType, expressionType, null /*no match*/, true); // ensure there is no collision between both interfaces: i.e. I1 extends List, I2 extends List @@ -504,8 +506,7 @@ public final boolean checkCastTypesCompatibility(Scope scope, TypeBinding castTy if (match != null) { return checkUnsafeCast(scope, castType, expressionType, match, true); } - if (((ReferenceBinding) castType).isFinal()) { - // no subclass for castType, thus compile-time check is invalid + if (((ReferenceBinding) castType).isDisjointFrom((ReferenceBinding) expressionType)) { return false; } if (use15specifics) { @@ -554,8 +555,7 @@ public final boolean checkCastTypesCompatibility(Scope scope, TypeBinding castTy if (match != null) { return checkUnsafeCast(scope, castType, expressionType, match, false); } - // unless final a subclass may implement the interface ==> no check at compile time - if (refExprType.isFinal()) { + if (refExprType.isDisjointFrom((ReferenceBinding) castType)) { return false; } tagAsNeedCheckCast(); diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java index 2d20957884c..80e4ba23f64 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java @@ -430,13 +430,13 @@ public static void analyseCloseableAllocation(BlockScope scope, FlowInfo flowInf if (flowInfo.reachMode() != FlowInfo.REACHABLE) return; // client has checked that the resolvedType is an AutoCloseable, hence the following cast is safe: - if (((ReferenceBinding)allocation.resolvedType).hasTypeBit(TypeIds.BitResourceFreeCloseable)) { + if (allocation.resolvedType.hasTypeBit(TypeIds.BitResourceFreeCloseable)) { // remove unnecessary attempts (closeable is not relevant) if (allocation.closeTracker != null) { allocation.closeTracker.withdraw(); allocation.closeTracker = null; } - } else if (((ReferenceBinding)allocation.resolvedType).hasTypeBit(TypeIds.BitWrapperCloseable)) { + } else if (allocation.resolvedType.hasTypeBit(TypeIds.BitWrapperCloseable)) { boolean isWrapper = true; if (allocation.arguments != null && allocation.arguments.length > 0) { // find the wrapped resource represented by its tracking var: @@ -511,7 +511,7 @@ public static FlowInfo analyseCloseableAcquisition(BlockScope scope, FlowInfo fl return flowInfo; } // client has checked that the resolvedType is an AutoCloseable, hence the following cast is safe: - if (((ReferenceBinding)acquisition.resolvedType).hasTypeBit(TypeIds.BitResourceFreeCloseable) + if (acquisition.resolvedType.hasTypeBit(TypeIds.BitResourceFreeCloseable) && !isBlacklistedMethod(acquisition)) { // remove unnecessary attempts (closeable is not relevant) if (acquisition.closeTracker != null) { @@ -1093,7 +1093,7 @@ protected boolean handle(FakedTrackingVariable closeTracker, FlowInfo flow, ASTN /** Answer wither the given type binding is a subtype of java.lang.AutoCloseable. */ public static boolean isAnyCloseable(TypeBinding typeBinding) { return typeBinding instanceof ReferenceBinding - && ((ReferenceBinding)typeBinding).hasTypeBit(TypeIds.BitAutoCloseable|TypeIds.BitCloseable); + && typeBinding.hasTypeBit(TypeIds.BitAutoCloseable|TypeIds.BitCloseable); } /** Answer wither the given type binding is a subtype of java.lang.AutoCloseable. */ diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java index 960d904ca75..bc675119594 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java @@ -457,9 +457,9 @@ public static TypeBinding getCollectionElementType(BlockScope scope, TypeBinding if (collectionType.isArrayType()) { // for(E e : E[]) return ((ArrayBinding) collectionType).elementsType(); } else if (collectionType instanceof ReferenceBinding) { - ReferenceBinding iterableType = ((ReferenceBinding)collectionType).findSuperTypeOriginatingFrom(T_JavaLangIterable, false /*Iterable is not a class*/); + ReferenceBinding iterableType = collectionType.findSuperTypeOriginatingFrom(T_JavaLangIterable, false /*Iterable is not a class*/); if (iterableType == null && isTargetJsr14) { - iterableType = ((ReferenceBinding)collectionType).findSuperTypeOriginatingFrom(T_JavaUtilCollection, false /*Iterable is not a class*/); + iterableType = collectionType.findSuperTypeOriginatingFrom(T_JavaUtilCollection, false /*Iterable is not a class*/); } if (iterableType == null) return null; @@ -570,22 +570,22 @@ public void resolve(BlockScope upperScope) { this.collection.computeConversion(this.scope, expectedCollectionType, collectionType); } } else if (collectionType instanceof ReferenceBinding) { - ReferenceBinding iterableType = ((ReferenceBinding)collectionType).findSuperTypeOriginatingFrom(T_JavaLangIterable, false /*Iterable is not a class*/); + ReferenceBinding iterableType = collectionType.findSuperTypeOriginatingFrom(T_JavaLangIterable, false /*Iterable is not a class*/); if (iterableType == null && isTargetJsr14) { - iterableType = ((ReferenceBinding)collectionType).findSuperTypeOriginatingFrom(T_JavaUtilCollection, false /*Iterable is not a class*/); + iterableType = collectionType.findSuperTypeOriginatingFrom(T_JavaUtilCollection, false /*Iterable is not a class*/); } checkIterable: { if (iterableType == null) break checkIterable; this.iteratorReceiverType = collectionType.erasure(); if (isTargetJsr14) { - if (((ReferenceBinding)this.iteratorReceiverType).findSuperTypeOriginatingFrom(T_JavaUtilCollection, false) == null) { + if (this.iteratorReceiverType.findSuperTypeOriginatingFrom(T_JavaUtilCollection, false) == null) { this.iteratorReceiverType = iterableType; // handle indirect inheritance thru variable secondary bound this.collection.computeConversion(this.scope, iterableType, collectionType); } else { this.collection.computeConversion(this.scope, collectionType, collectionType); } - } else if (((ReferenceBinding)this.iteratorReceiverType).findSuperTypeOriginatingFrom(T_JavaLangIterable, false) == null) { + } else if (this.iteratorReceiverType.findSuperTypeOriginatingFrom(T_JavaLangIterable, false) == null) { this.iteratorReceiverType = iterableType; // handle indirect inheritance thru variable secondary bound this.collection.computeConversion(this.scope, iterableType, collectionType); } else { diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/MessageSend.java index 56aac67bf0a..9bc7180ee50 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/MessageSend.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/MessageSend.java @@ -97,6 +97,7 @@ import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment; import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; import org.eclipse.jdt.internal.compiler.lookup.MethodScope; +import org.eclipse.jdt.internal.compiler.lookup.MethodVerifier; import org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding; import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding; import org.eclipse.jdt.internal.compiler.lookup.ParameterizedMethodBinding; @@ -807,25 +808,14 @@ public TypeBinding resolveType(BlockScope scope) { if (this.constant != Constant.NotAConstant) { this.constant = Constant.NotAConstant; long sourceLevel = scope.compilerOptions().sourceLevel; - boolean receiverCast = false; if (this.receiver instanceof CastExpression) { this.receiver.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on - receiverCast = true; } this.actualReceiverType = this.receiver.resolveType(scope); if (this.actualReceiverType instanceof InferenceVariable) { return null; // not yet ready for resolving } this.receiverIsType = this.receiver.isType(); - if (receiverCast && this.actualReceiverType != null) { - // due to change of declaring class with receiver type, only identity cast should be notified - TypeBinding resolvedType2 = ((CastExpression)this.receiver).expression.resolvedType; - if (TypeBinding.equalsEquals(resolvedType2, this.actualReceiverType)) { - if (!scope.environment().usesNullTypeAnnotations() || !NullAnnotationMatching.analyse(this.actualReceiverType, resolvedType2, -1).isAnyMismatch()) { - scope.problemReporter().unnecessaryCast((CastExpression) this.receiver); - } - } - } // resolve type arguments (for generic constructor call) if (this.typeArguments != null) { int length = this.typeArguments.length; @@ -977,6 +967,12 @@ public TypeBinding resolveType(BlockScope scope) { return null; } + if (this.receiver instanceof CastExpression castedRecevier) { + // this check was suppressed while resolving receiver, check now based on the resolved method + if (isUnnecessaryReceiverCast(scope, castedRecevier.expression.resolvedType)) + scope.problemReporter().unnecessaryCast(castedRecevier); + } + if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) { ImplicitNullAnnotationVerifier.ensureNullnessIsKnown(this.binding, scope); if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8) { @@ -1096,6 +1092,26 @@ public TypeBinding resolveType(BlockScope scope) { : null; } +protected boolean isUnnecessaryReceiverCast(BlockScope scope, TypeBinding uncastedReceiverType) { + if (uncastedReceiverType == null || !uncastedReceiverType.isCompatibleWith(this.binding.declaringClass)) { + return false; + } + if (uncastedReceiverType.isRawType() && this.binding.declaringClass.isParameterizedType()) { + return false; + } + MethodBinding otherMethod = scope.getMethod(uncastedReceiverType, this.selector, this.argumentTypes, this); + if (!otherMethod.isValidBinding()) { + return false; + } + if (scope.environment().usesNullTypeAnnotations() + && NullAnnotationMatching.analyse(this.actualReceiverType, uncastedReceiverType, -1).isAnyMismatch()) { + return false; + } + return otherMethod == this.binding + || MethodVerifier.doesMethodOverride(this.binding, otherMethod, scope.environment()) + || MethodVerifier.doesMethodOverride(otherMethod, this.binding, scope.environment()); +} + protected TypeBinding handleNullnessCodePatterns(BlockScope scope, TypeBinding returnType) { // j.u.s.Stream.filter() may modify nullness of stream elements: if (this.binding.isWellknownMethod(TypeConstants.JAVA_UTIL_STREAM__STREAM, TypeConstants.FILTER) diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java index 5e89620124b..2aae1b181d1 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java @@ -125,7 +125,7 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks; boolean hasResourceWrapperType = analyseResources && this.resolvedType instanceof ReferenceBinding - && ((ReferenceBinding)this.resolvedType).hasTypeBit(TypeIds.BitWrapperCloseable); + && this.resolvedType.hasTypeBit(TypeIds.BitWrapperCloseable); for (int i = 0, count = this.arguments.length; i < count; i++) { flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo); if (analyseResources && !hasResourceWrapperType) { // allocation of wrapped closeables is analyzed specially diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java index f2fe2e72a5f..5c88b9ec9c4 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SingleTypeReference.java @@ -115,7 +115,7 @@ public TypeBinding resolveTypeEnclosing(BlockScope scope, ReferenceBinding enclo if (!memberType.isValidBinding()) { hasError = true; scope.problemReporter().invalidEnclosingType(this, memberType, enclosingType); - memberType = ((ReferenceBinding)memberType).closestMatch(); + memberType = memberType.closestMatch(); if (memberType == null) { return null; } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java index de112587018..bd57ce20c6c 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java @@ -21,11 +21,7 @@ import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Set; import java.util.function.Function; import java.util.function.IntPredicate; import org.eclipse.jdt.internal.compiler.ASTVisitor; @@ -243,7 +239,7 @@ public void addPattern(RecordPattern rp, int i) { TypeBinding ref = SwitchStatement.this.expression.resolvedType; if (!(ref instanceof ReferenceBinding)) return; - RecordComponentBinding[] comps = ((ReferenceBinding)ref).components(); + RecordComponentBinding[] comps = ref.components(); if (comps == null || comps.length <= i) // safety-net for incorrect code. return; if (this.next == null) @@ -352,8 +348,8 @@ public boolean visit(TNode node) { availableTypes.add(child.type); } } - if (node.type instanceof ReferenceBinding && ((ReferenceBinding)node.type).isSealed()) { - List allAllowedTypes = getAllPermittedTypes((ReferenceBinding) node.type); + if (node.type instanceof ReferenceBinding ref && ref.isSealed()) { + List allAllowedTypes = ref.getAllEnumerableReferenceTypes(); this.covers &= isExhaustiveWithCaseTypes(allAllowedTypes, availableTypes); return this.covers; } @@ -425,12 +421,12 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl this.scope.enclosingCase = this.cases[caseIndex]; // record entering in a switch case block caseIndex++; if (prevCaseStmtIndex == i - 1) { - if (((CaseStatement) this.statements[prevCaseStmtIndex]).containsPatternVariable()) + if (this.statements[prevCaseStmtIndex].containsPatternVariable()) this.scope.problemReporter().illegalFallthroughFromAPattern(this.statements[prevCaseStmtIndex]); } prevCaseStmtIndex = i; if (fallThroughState == FALLTHROUGH && complaintLevel <= NOT_COMPLAINED) { - if (((CaseStatement) statement).containsPatternVariable()) + if (statement.containsPatternVariable()) this.scope.problemReporter().IllegalFallThroughToPattern(this.scope.enclosingCase); else if ((statement.bits & ASTNode.DocumentedFallthrough) == 0) { // the case is not fall-through protected by a line comment this.scope.problemReporter().possibleFallThroughCase(this.scope.enclosingCase); @@ -1377,7 +1373,7 @@ private boolean checkAndFlagDefaultSealed(BlockScope skope, CompilerOptions comp return checkAndFlagDefaultRecord(skope, compilerOptions, ref); } if (!ref.isSealed()) return false; - if (!isExhaustiveWithCaseTypes(getAllPermittedTypes(ref), this.caseLabelElementTypes)) { + if (!isExhaustiveWithCaseTypes(ref.getAllEnumerableReferenceTypes(), this.caseLabelElementTypes)) { if (this instanceof SwitchExpression) // non-exhaustive switch expressions will be flagged later. return false; skope.problemReporter().enhancedSwitchMissingDefaultCase(this.expression); @@ -1386,25 +1382,6 @@ private boolean checkAndFlagDefaultSealed(BlockScope skope, CompilerOptions comp this.switchBits |= SwitchStatement.Exhaustive; return false; } - List getAllPermittedTypes(ReferenceBinding ref) { - if (!ref.isSealed()) - return new ArrayList<>(0); - - Set permSet = new HashSet<>(Arrays.asList(ref.permittedTypes())); - if (ref.isClass() && (!ref.isAbstract())) - permSet.add(ref); - Set oldSet = new HashSet<>(permSet); - do { - for (ReferenceBinding type : permSet) { - oldSet.addAll(Arrays.asList(type.permittedTypes())); - } - Set tmp = oldSet; - oldSet = permSet; - permSet = tmp; - } while (oldSet.size() != permSet.size()); - return Arrays.asList(permSet.toArray(new ReferenceBinding[0])); - } - private boolean checkAndFlagDefaultRecord(BlockScope skope, CompilerOptions compilerOptions, ReferenceBinding ref) { RecordComponentBinding[] comps = ref.components(); List allallowedTypes = new ArrayList<>(); @@ -1431,7 +1408,6 @@ private boolean checkAndFlagDefaultRecord(BlockScope skope, CompilerOptions comp return false; } private boolean isExhaustiveWithCaseTypes(List allAllowedTypes, List listedTypes) { - // first KISS (Keep It Simple Stupid) int pendingTypes = allAllowedTypes.size(); for (ReferenceBinding pt : allAllowedTypes) { /* Per JLS 14.11.1.1: A type T that names an abstract sealed class or sealed interface is covered @@ -1450,63 +1426,7 @@ private boolean isExhaustiveWithCaseTypes(List allAllowedTypes } } } - if (pendingTypes == 0) - return true; - // else - #KICKME (Keep It Complicated Keep Me Employed)" - List coveredTypes = new ArrayList<>(listedTypes); - List remainingTypes = new ArrayList<>(allAllowedTypes); - remainingTypes.removeAll(coveredTypes); - - Map> impliedTypes = new HashMap<>(); - - for (ReferenceBinding type : remainingTypes) { - impliedTypes.put(type, new ArrayList<>()); - List typesToAdd = new ArrayList<>(); - for (ReferenceBinding impliedType : allAllowedTypes) { - if (impliedType.equals(type)) continue; - if (type.isClass()) { - if (impliedType.isAbstract() && type.superclass().equals(impliedType)) { - typesToAdd.add(impliedType); - } - if (Arrays.asList(type.superInterfaces()).contains(impliedType)) - typesToAdd.add(impliedType); - } else if (type.isInterface()) { - if (Arrays.asList(impliedType.superInterfaces()).contains(type)) - typesToAdd.add(impliedType); - } - } - if (!typesToAdd.isEmpty()) { - impliedTypes.get(type).addAll(typesToAdd); - } - } - boolean delta = true; - while (delta) { - delta = false; - List typesToAdd = new ArrayList<>(); - for (ReferenceBinding type : remainingTypes) { - boolean add = false; - if (type.isClass()) { - for (TypeBinding tb : impliedTypes.get(type)) { - if (coveredTypes.contains(tb)) { - add = true; - break; - } - } - } else if (type.isInterface()) { - add = coveredTypes.containsAll(impliedTypes.get(type)); - } - if (add) { - typesToAdd.add(type); - } - } - if (!typesToAdd.isEmpty()) { - remainingTypes.removeAll(typesToAdd); - coveredTypes.addAll(typesToAdd); - typesToAdd.clear(); - delta = true; - } - } - return remainingTypes.isEmpty(); + return pendingTypes == 0; } private boolean needPatternDispatchCopy() { if (this.containsPatterns || (this.switchBits & QualifiedEnum) != 0) diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithParameterAnnotations.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithParameterAnnotations.java index 79bce007add..daf79f786c3 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithParameterAnnotations.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/classfmt/MethodInfoWithParameterAnnotations.java @@ -26,25 +26,29 @@ class MethodInfoWithParameterAnnotations extends MethodInfoWithAnnotations { } @Override public IBinaryAnnotation[] getParameterAnnotations(int index, char[] classFileName) { - try { - return this.parameterAnnotations == null ? null : this.parameterAnnotations[index]; - } catch (ArrayIndexOutOfBoundsException aioobe) { - // detailed reporting to track down https://bugs.eclipse.org/474081 - StringBuilder message = new StringBuilder("Mismatching number of parameter annotations, "); //$NON-NLS-1$ - message.append(index); - message.append('>'); - message.append(this.parameterAnnotations.length-1); - message.append(" in "); //$NON-NLS-1$ - message.append(getSelector()); - char[] desc = getGenericSignature(); - if (desc != null) - message.append(desc); - else - message.append(getMethodDescriptor()); - if (classFileName != null) - message.append(" in ").append(classFileName); //$NON-NLS-1$ - throw new IllegalStateException(message.toString(), aioobe); + if (this.parameterAnnotations != null) { + if (index < this.parameterAnnotations.length) { + return this.parameterAnnotations[index]; + } + if (Boolean.getBoolean("jdt.reject.parameterAnnotations.countMismatch")) { //$NON-NLS-1$ + // detailed reporting to track down https://bugs.eclipse.org/474081 + StringBuilder message = new StringBuilder("Mismatching number of parameter annotations, "); //$NON-NLS-1$ + message.append(index); + message.append('>'); + message.append(this.parameterAnnotations.length-1); + message.append(" in "); //$NON-NLS-1$ + message.append(getSelector()); + char[] desc = getGenericSignature(); + if (desc != null) + message.append(desc); + else + message.append(getMethodDescriptor()); + if (classFileName != null) + message.append(" in ").append(classFileName); //$NON-NLS-1$ + throw new IllegalStateException(message.toString()); + } } + return null; } @Override public int getAnnotatedParametersCount() { diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java index ff91de90f58..e5df054c6b6 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java @@ -39,6 +39,7 @@ import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Map; +import java.util.Set; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.Compiler; @@ -263,6 +264,25 @@ public class CompilerOptions { * Note: Whenever a new version is added, make sure getLatestVersion() * is updated with it. */ + + /** + * Unsupported JLS versions + */ + /* + * Note: Whenever a new version is obsoleted, make sure getFirstVersion() is updated. + */ + public static Set UNSUPPORTED_VERSIONS = Set.of( + VERSION_1_1, + VERSION_1_2, + VERSION_1_3, + VERSION_1_4, + VERSION_JSR14, + VERSION_CLDC1_1, + VERSION_1_5, + VERSION_1_6, + VERSION_1_7 + ); + public static final String ERROR = "error"; //$NON-NLS-1$ public static final String WARNING = "warning"; //$NON-NLS-1$ public static final String INFO = "info"; //$NON-NLS-1$ @@ -652,6 +672,18 @@ public CompilerOptions(Map settings, boolean parseLiteralExpress this.parseLiteralExpressionsAsConstants = parseLiteralExpressionsAsConstants; } + /** + * Return the first (oldest) Java language version supported by the Eclipse compiler + */ + public static String getFirstSupportedJavaVersion() { + return VERSION_1_8; + } + /** + * Return the first (oldest) Java language level supported by the Eclipse compiler + */ + public static long getFirstSupportedJdkLevel() { + return ClassFileConstants.JDK1_8; + } /** * Return the latest Java language version supported by the Eclipse compiler */ diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/impl/Constant.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/impl/Constant.java index 27173b324e7..ab27bc512bb 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/impl/Constant.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/impl/Constant.java @@ -491,7 +491,7 @@ public static final Constant computeConstantOperationEQUAL_EQUAL(Constant left, if (rightId == T_JavaLangString) { //String are interned in th compiler==>thus if two string constant //get to be compared, it is an equal on the vale which is done - return BooleanConstant.fromValue(((StringConstant)left).hasSameValue(right)); + return BooleanConstant.fromValue(left.hasSameValue(right)); } break; case T_null : diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java index 97bf9d53505..b6b1f3cb8f7 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java @@ -910,7 +910,7 @@ public Object[] getEmulationPath(ReferenceBinding targetEnclosingType, boolean o if (enclosingArgument != null) { FieldBinding syntheticField = sourceType.getSyntheticField(enclosingArgument); if (syntheticField != null) { - if (TypeBinding.equalsEquals(syntheticField.type, targetEnclosingType) || (!onlyExactMatch && ((ReferenceBinding)syntheticField.type).findSuperTypeOriginatingFrom(targetEnclosingType) != null)) + if (TypeBinding.equalsEquals(syntheticField.type, targetEnclosingType) || (!onlyExactMatch && syntheticField.type.findSuperTypeOriginatingFrom(targetEnclosingType) != null)) return new Object[] { syntheticField }; } } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java index c8391b75c5b..dcb41ac6856 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/BoundSet.java @@ -1178,8 +1178,8 @@ public String toString() { } else { buf.append('\n'); for (Entry entry : this.captures.entrySet()) { - String lhs = String.valueOf(((TypeBinding)entry.getKey()).shortReadableName()); - String rhs = String.valueOf(((TypeBinding)entry.getValue()).shortReadableName()); + String lhs = String.valueOf(entry.getKey().shortReadableName()); + String rhs = String.valueOf(entry.getValue().shortReadableName()); buf.append('\t').append(lhs).append(" = capt(").append(rhs).append(")\n"); //$NON-NLS-1$ //$NON-NLS-2$ } } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java index 093a250204a..b002c03e3e3 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/IntersectionTypeBinding18.java @@ -212,7 +212,7 @@ public boolean isSubtypeOf(TypeBinding other, boolean simulatingBugJDK8026527) { if (TypeBinding.equalsEquals(this, other)) return true; if (other instanceof ReferenceBinding) { - TypeBinding[] rightIntersectingTypes = ((ReferenceBinding) other).getIntersectingTypes(); + TypeBinding[] rightIntersectingTypes = other.getIntersectingTypes(); if (rightIntersectingTypes != null && rightIntersectingTypes.length > 1) { int numRequired = rightIntersectingTypes.length; TypeBinding[] required = new TypeBinding[numRequired]; diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java index 6dc6f648f42..32df901927e 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java @@ -919,7 +919,7 @@ public boolean hasMemberTypes() { public boolean hasTypeBit(int bit) { TypeBinding erasure = erasure(); if (erasure instanceof ReferenceBinding) - return ((ReferenceBinding) erasure).hasTypeBit(bit); + return erasure.hasTypeBit(bit); return false; } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java index bf2de8a280f..0d4b2c04984 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ReferenceBinding.java @@ -53,7 +53,11 @@ package org.eclipse.jdt.internal.compiler.lookup; import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.ast.LambdaExpression; @@ -1558,6 +1562,7 @@ public final boolean isNonSealed() { /** * Answer true if the receiver has sealed modifier */ +@Override public boolean isSealed() { return (this.modifiers & ExtraCompilerModifiers.AccSealed) != 0; } @@ -1599,7 +1604,7 @@ protected boolean isSubTypeOfRTL(TypeBinding other) { return (lower != null && isSubtypeOf(lower, false)); } if (other instanceof ReferenceBinding) { - TypeBinding[] intersecting = ((ReferenceBinding) other).getIntersectingTypes(); + TypeBinding[] intersecting = other.getIntersectingTypes(); if (intersecting != null) { for (TypeBinding binding : intersecting) { if (!isSubtypeOf(binding, false)) @@ -2544,6 +2549,89 @@ public boolean hasEnclosingInstanceContext() { return !enclosingMethod.isStatic(); return false; } + +@Override +public List getAllEnumerableReferenceTypes() { + if (!isSealed()) + return Collections.emptyList(); + + Set permSet = new HashSet<>(Arrays.asList(permittedTypes())); + if (isClass() && (!isAbstract())) + permSet.add(this); + Set oldSet = new HashSet<>(permSet); + do { + for (ReferenceBinding type : permSet) { + oldSet.addAll(Arrays.asList(type.permittedTypes())); + } + Set tmp = oldSet; + oldSet = permSet; + permSet = tmp; + } while (oldSet.size() != permSet.size()); + return Arrays.asList(permSet.toArray(new ReferenceBinding[0])); +} + +// 5.1.6.1 Allowed Narrowing Reference Conversion +public boolean isDisjointFrom(ReferenceBinding that) { + if (this.isInterface()) { + if (that.isInterface()) { + /* • An interface named I is disjoint from another interface named J if (i) it is not that case that I <: J, and (ii) it is not the case that J <: I, and + * (iii) one of the following cases applies: + – I is sealed, and all of the permitted direct subclasses and subinterfaces of I are disjoint from J. + – J is sealed, and I is disjoint from all the permitted direct subclasses and subinterfaces of J. + */ + if (this.findSuperTypeOriginatingFrom(that) != null || that.findSuperTypeOriginatingFrom(this) != null) + return false; + if (this.isSealed()) { + for (ReferenceBinding directSubType : this.permittedTypes()) { + if (!directSubType.isDisjointFrom(that)) + return false; + } + return true; + } + if (that.isSealed()) { + for (ReferenceBinding directSubType : that.permittedTypes()) { + if (!this.isDisjointFrom(directSubType)) + return false; + } + return true; + } + return false; + } else { + // • An interface named I is disjoint from a class named C if C is disjoint from I. + return that.isDisjointFrom(this); + } + } else { + if (that.isInterface()) { + /* • A class named C is disjoint from an interface named I if (i) it is not the case that C <: I, and (ii) one of the following cases applies: + – C is final. + – C is sealed, and all of the permitted direct subclasses of C are disjoint from I. + – C is freely extensible (§8.1.1.2), and I is sealed, and C is disjoint from all of the permitted direct subclasses and subinterfaces of I + */ + if (this.findSuperTypeOriginatingFrom(that) != null) + return false; + if (this.isFinal()) + return true; + if (this.isSealed()) { + for (ReferenceBinding directSubclass : this.permittedTypes()) { + if (!directSubclass.isDisjointFrom(that)) + return false; + } + return true; + } + if (that.isSealed()) { + for (ReferenceBinding directSubType : that.permittedTypes()) { + if (!this.isDisjointFrom(directSubType)) + return false; + } + return true; + } + return false; + } else { + // • A class named C is disjoint from another class named D if (i) it is not the case that C <: D, and (ii) it is not the case that D <: C. + return this.findSuperTypeOriginatingFrom(that) == null && that.findSuperTypeOriginatingFrom(this) == null; + } + } +} static class InvalidBindingException extends Exception { private static final long serialVersionUID = 1L; diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java index e460788a9c2..0c5d3af098c 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java @@ -1660,7 +1660,7 @@ public MethodBinding findMethod(ReferenceBinding receiverType, char[] selector, if (method != null && method.isValidBinding() && method.isVarargs()) { TypeBinding elementType = method.parameters[method.parameters.length - 1].leafComponentType(); if (elementType instanceof ReferenceBinding) { - if (!((ReferenceBinding) elementType).erasure().canBeSeenBy(this)) { + if (!elementType.erasure().canBeSeenBy(this)) { return new ProblemMethodBinding(method, method.selector, invocationSite.genericTypeArguments(), ProblemReasons.VarargsElementTypeNotVisible); } } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java index fc924b9b506..ce91f97244a 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/TypeBinding.java @@ -38,6 +38,7 @@ *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -1806,4 +1807,12 @@ public boolean isNonDenotable() { return false; } +public boolean isSealed() { + return false; +} + +public List getAllEnumerableReferenceTypes() { + return Collections.emptyList(); +} + } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java index 65e58de3e7e..2df387dc489 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2022 IBM Corporation and others. + * Copyright (c) 2000, 2024 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -90,6 +90,7 @@ public abstract class AbstractCommentParser implements JavadocTagConstants { // Flags protected boolean lineStarted = false; protected boolean inlineTagStarted = false; + protected boolean inlineReturn= false; protected boolean abort = false; protected int kind; protected int tagValue = NO_TAG_VALUE; @@ -251,7 +252,7 @@ protected boolean commentParse() { openingBraces = 0; } } else if ((!this.lineStarted || previousChar == '{') || lookForTagsInSnippets()) { - if (this.inlineTagStarted) { + if (this.inlineTagStarted && !this.inlineReturn) { setInlineTagStarted(false); // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53279 // Cannot have @ inside inline comment @@ -352,6 +353,9 @@ protected boolean commentParse() { if (!isFormatterParser && !considerTagAsPlainText) this.textStart = this.index; setInlineTagStarted(false); + if (this.inlineReturn) { + addFragmentToInlineReturn(); + } } else { if (!this.lineStarted) { this.textStart = previousPosition; @@ -368,23 +372,26 @@ protected boolean commentParse() { if (considerTagAsPlainText) { openingBraces++; } else if (this.inlineTagStarted) { + if (this.tagValue == TAG_RETURN_VALUE) { + this.inlineReturn= true; + } + if (this.lineStarted && this.textStart != -1 && this.textStart < textEndPosition) { + pushText(this.textStart, textEndPosition); + } setInlineTagStarted(false); // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53279 // Cannot have opening brace in inline comment - if (this.reportProblems) { + if (this.reportProblems && !this.inlineReturn || peekChar() != '@') { int end = previousPosition testClass() { - return BatchCompilerTest_20.class; - } - - public BatchCompilerTest_20(String name) { - super(name); - } - - public void testIssue558_1() throws Exception { - String path = LIB_DIR; - String libPath = null; - if (path.endsWith(File.separator)) { - libPath = path + "lib.jar"; - } else { - libPath = path + File.separator + "lib.jar"; - } - Util.createJar(new String[] { - "p/Color.java", - "package p;\n" + - "public enum Color {\n" + - " R, Y;\n" + - " public static Color getColor() {\n" + - " return R;\n" + - " }\n" + - "}", - }, - libPath, - JavaCore.VERSION_20); - this.runConformTest( - new String[] { - "src/p/X.java", - "package p;\n" - + "import p.Color;\n" - + "public class X {\n" - + " public static void main(String argv[]) {\n" - + " Color c = Color.getColor();\n" - + " try {\n" - + " int a = switch (c) {\n" - + " case R -> 1;\n" - + " case Y -> 2;\n" - + " };\n" - + " } catch (MatchException e) {\n" - + " System.out.print(\"OK\");\n" - + " } catch (Exception e) {\n" - + " System.out.print(\"NOT OK: \" + e);\n" - + " }\n" - + " System.out.print(\"END\");\n" - + " }\n" - + "}", - }, - "\"" + OUTPUT_DIR + File.separator + "src/p/X.java\"" - + " -cp \"" + LIB_DIR + File.separator + "lib.jar\"" - + " -sourcepath \"" + OUTPUT_DIR + File.separator + "src\"" - + " --enable-preview -source 20 -warn:none" - + " -d \"" + OUTPUT_DIR + File.separator + "bin\" ", - "", - "", - true); - this.verifier.execute("p.X", new String[] {OUTPUT_DIR + File.separator + "bin", libPath}, new String[0], new String[] {"--enable-preview"}); - assertEquals("Incorrect output", "END", this.verifier.getExecutionOutput()); - Util.createJar(new String[] { - "p/Color.java", - "package p;\n" + - "public enum Color {\n" + - " R, Y, B;\n" + - " public static Color getColor() {\n" + - " return B;\n" + - " }\n" + - "}", - }, - libPath, - JavaCore.VERSION_20); - this.verifier.execute("p.X", new String[] {OUTPUT_DIR + File.separator + "bin", libPath}, new String[0], new String[] {"--enable-preview"}); - assertEquals("Incorrect output", "OKEND", this.verifier.getExecutionOutput()); - } - public void testIssue558_2() throws Exception { - String path = LIB_DIR; - String libPath = null; - if (path.endsWith(File.separator)) { - libPath = path + "lib.jar"; - } else { - libPath = path + File.separator + "lib.jar"; - } - Util.createJar(new String[] { - "p/I.java", - "package p;\n" + - "public sealed interface I {\n" + - " public static I getImpl() {\n" + - " return new A();\n" + - " }\n" + - "}\n" + - "final class A implements I {}\n" + - "final class B implements I {}", - }, - libPath, - JavaCore.VERSION_20); - this.runConformTest( - new String[] { - "src/p/X.java", - "package p;\n" - + "import p.I;\n" - + "public class X {\n" - + " public static void main(String argv[]) {\n" - + " I i = I.getImpl();\n" - + " try {\n" - + " int r = switch (i) {\n" - + " case A a -> 1;\n" - + " case B b -> 2;\n" - + " };\n" - + " } catch (MatchException e) {\n" - + " System.out.print(\"OK\");\n" - + " } catch (Exception e) {\n" - + " System.out.print(\"NOT OK: \" + e);\n" - + " }\n" - + " System.out.print(\"END\");\n" - + " }\n" - + "}", - }, - "\"" + OUTPUT_DIR + File.separator + "src/p/X.java\"" - + " -cp \"" + LIB_DIR + File.separator + "lib.jar\"" - + " -sourcepath \"" + OUTPUT_DIR + File.separator + "src\"" - + " --enable-preview -source 20 -warn:none" - + " -d \"" + OUTPUT_DIR + File.separator + "bin\" ", - "", - "", - true); - this.verifier.execute("p.X", new String[] {OUTPUT_DIR + File.separator + "bin", libPath}, new String[0], new String[] {"--enable-preview"}); - assertEquals("Incorrect output", "END", this.verifier.getExecutionOutput()); - Util.createJar(new String[] { - "p/I.java", - "package p;\n" + - "public sealed interface I {\n" + - " public static I getImpl() {\n" + - " return new C();\n" + - " }\n" + - "}\n" + - "final class A implements I {}\n" + - "final class B implements I {}\n" + - "final class C implements I {}", - }, - libPath, - JavaCore.VERSION_20); - this.verifier.execute("p.X", new String[] {OUTPUT_DIR + File.separator + "bin", libPath}, new String[0], new String[] {"--enable-preview"}); - assertEquals("Incorrect output", "OKEND", this.verifier.getExecutionOutput()); - } -} diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest_21.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest_21.java index 9d5eb3c101f..23180d0b346 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest_21.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest_21.java @@ -182,4 +182,143 @@ public void testGHI1774_Statement() throws Exception { assertEquals("Incorrect output", "OK!END", this.verifier.getExecutionOutput()); } + public void testIssue558_1() throws Exception { + String path = LIB_DIR; + String libPath = null; + if (path.endsWith(File.separator)) { + libPath = path + "lib.jar"; + } else { + libPath = path + File.separator + "lib.jar"; + } + Util.createJar(new String[] { + "p/Color.java", + "package p;\n" + + "public enum Color {\n" + + " R, Y;\n" + + " public static Color getColor() {\n" + + " return R;\n" + + " }\n" + + "}", + }, + libPath, + JavaCore.VERSION_21); + this.runConformTest( + new String[] { + "src/p/X.java", + "package p;\n" + + "import p.Color;\n" + + "public class X {\n" + + " public static void main(String argv[]) {\n" + + " Color c = Color.getColor();\n" + + " try {\n" + + " int a = switch (c) {\n" + + " case R -> 1;\n" + + " case Y -> 2;\n" + + " };\n" + + " } catch (MatchException e) {\n" + + " System.out.print(\"OK\");\n" + + " } catch (Exception e) {\n" + + " System.out.print(\"NOT OK: \" + e);\n" + + " }\n" + + " System.out.print(\"END\");\n" + + " }\n" + + "}", + }, + "\"" + OUTPUT_DIR + File.separator + "src/p/X.java\"" + + " -cp \"" + LIB_DIR + File.separator + "lib.jar\"" + + " -sourcepath \"" + OUTPUT_DIR + File.separator + "src\"" + + " -source 21 -warn:none" + + " -d \"" + OUTPUT_DIR + File.separator + "bin\" ", + "", + "", + true); + this.verifier.execute("p.X", new String[] {OUTPUT_DIR + File.separator + "bin", libPath}, new String[0], null); + assertEquals("Incorrect output", "END", this.verifier.getExecutionOutput()); + Util.createJar(new String[] { + "p/Color.java", + "package p;\n" + + "public enum Color {\n" + + " R, Y, B;\n" + + " public static Color getColor() {\n" + + " return B;\n" + + " }\n" + + "}", + }, + libPath, + JavaCore.VERSION_21); + this.verifier.execute("p.X", new String[] {OUTPUT_DIR + File.separator + "bin", libPath}, new String[0], null); + assertEquals("Incorrect output", "OKEND", this.verifier.getExecutionOutput()); + } + + public void testIssue558_2() throws Exception { + String path = LIB_DIR; + String libPath = null; + if (path.endsWith(File.separator)) { + libPath = path + "lib.jar"; + } else { + libPath = path + File.separator + "lib.jar"; + } + Util.createJar(new String[] { + "p/I.java", + "package p;\n" + + "public sealed interface I {\n" + + " public static I getImpl() {\n" + + " return new A();\n" + + " }\n" + + "}\n" + + "final class A implements I {}\n" + + "final class B implements I {}", + }, + libPath, + JavaCore.VERSION_21); + this.runConformTest( + new String[] { + "src/p/X.java", + "package p;\n" + + "import p.I;\n" + + "public class X {\n" + + " public static void main(String argv[]) {\n" + + " I i = I.getImpl();\n" + + " try {\n" + + " int r = switch (i) {\n" + + " case A a -> 1;\n" + + " case B b -> 2;\n" + + " };\n" + + " } catch (MatchException e) {\n" + + " System.out.print(\"OK\");\n" + + " } catch (Exception e) {\n" + + " System.out.print(\"NOT OK: \" + e);\n" + + " }\n" + + " System.out.print(\"END\");\n" + + " }\n" + + "}", + }, + "\"" + OUTPUT_DIR + File.separator + "src/p/X.java\"" + + " -cp \"" + LIB_DIR + File.separator + "lib.jar\"" + + " -sourcepath \"" + OUTPUT_DIR + File.separator + "src\"" + + " -source 21 -warn:none" + + " -d \"" + OUTPUT_DIR + File.separator + "bin\" ", + "", + "", + true); + this.verifier.execute("p.X", new String[] {OUTPUT_DIR + File.separator + "bin", libPath}, new String[0], null); + assertEquals("Incorrect output", "END", this.verifier.getExecutionOutput()); + Util.createJar(new String[] { + "p/I.java", + "package p;\n" + + "public sealed interface I {\n" + + " public static I getImpl() {\n" + + " return new C();\n" + + " }\n" + + "}\n" + + "final class A implements I {}\n" + + "final class B implements I {}\n" + + "final class C implements I {}", + }, + libPath, + JavaCore.VERSION_21); + this.verifier.execute("p.X", new String[] {OUTPUT_DIR + File.separator + "bin", libPath}, new String[0], null); + assertEquals("Incorrect output", "OKEND", this.verifier.getExecutionOutput()); + } + } \ No newline at end of file diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java index c1048fdaefa..58bae8fc451 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CastTest.java @@ -3649,6 +3649,170 @@ public void testBug572534() { } } +public void testGH2470() { + if (this.complianceLevel < ClassFileConstants.JDK1_6) return; + Runner runner = new Runner(); + runner.testFiles = new String[] { + "UnnecessaryCasts.java", + """ + public class UnnecessaryCasts { + void m(T t) { + C c = t; + + ((C) t).x(); + ((I) t).x(); + ((I) c).x(); + } + } + + interface I { + void x(); + } + class C implements I { + @Override + public void x() {} + } + """ + }; + runner.expectedCompilerLog = + "----------\n" + + "1. WARNING in UnnecessaryCasts.java (at line 5)\n" + + " ((C) t).x();\n" + + " ^^^^^^^\n" + + "Unnecessary cast from T to C\n" + + "----------\n" + + "2. WARNING in UnnecessaryCasts.java (at line 6)\n" + + " ((I) t).x();\n" + + " ^^^^^^^\n" + + "Unnecessary cast from T to I\n" + + "----------\n" + + "3. WARNING in UnnecessaryCasts.java (at line 7)\n" + + " ((I) c).x();\n" + + " ^^^^^^^\n" + + "Unnecessary cast from C to I\n" + + "----------\n"; + runner.runWarningTest(); +} + +public void testGH2470_generic() { + if (this.complianceLevel < ClassFileConstants.JDK1_8) return; + Runner runner = new Runner(); + runner.customOptions = getCompilerOptions(); + runner.customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); + runner.testFiles = new String[] { + "X.java", + """ + import java.util.List; + public class X { + void bar() {} + @SuppressWarnings({"unchecked"}) + void test(List list) { + ((List) list).get(0).bar(); + list.get(0).bar(); + } + } + """ + }; + runner.expectedCompilerLog = + """ + ---------- + 1. ERROR in X.java (at line 7) + list.get(0).bar(); + ^^^ + The method bar() is undefined for the type Object + ---------- + """; + runner.runNegativeTest(); +} + +public void testGH2470_generic2() { + if (this.complianceLevel < ClassFileConstants.JDK1_8) return; + Runner runner = new Runner(); + runner.customOptions = getCompilerOptions(); + runner.customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); + runner.testFiles = new String[] { + "X.java", + """ + import java.util.List; + import java.util.function.Supplier; + interface XListSupplier extends Supplier> {} + interface XList extends List {} + public class X { + void bar() {} + @SuppressWarnings({"unchecked"}) + void test0(Supplier sup) { + ((Supplier>) sup).get().get(0).bar(); + } + @SuppressWarnings({"unchecked"}) + void test1(Supplier sup) { + ((XListSupplier) sup).get().get(0).bar(); + } + @SuppressWarnings({"unchecked"}) + void test2(List list) { + ((XList) list).get(0).bar(); + list.get(0).bar(); + } + } + """ + }; + runner.expectedCompilerLog = + """ + ---------- + 1. ERROR in X.java (at line 9) + ((Supplier>) sup).get().get(0).bar(); + ^^^^^^^^^^^^^^^^^^^^^^^^^ + Cannot cast from Supplier to Supplier> + ---------- + 2. ERROR in X.java (at line 13) + ((XListSupplier) sup).get().get(0).bar(); + ^^^^^^^^^^^^^^^^^^^^^ + Cannot cast from Supplier to XListSupplier + ---------- + 3. ERROR in X.java (at line 18) + list.get(0).bar(); + ^^^ + The method bar() is undefined for the type Object + ---------- + """; + runner.runNegativeTest(); +} + +public void testGH2470_overload() { + Runner runner = new Runner(); + runner.customOptions = getCompilerOptions(); + runner.customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.ERROR); + runner.testFiles = new String[] { + "p1/C1.java", + """ + package p1; + import p2.C2; + public class C1 { + void m(String s) { + System.out.print("String."); + } + public void m(CharSequence s) { + System.out.print("CharSequence."); + } + + public static void main(String[] args) { + C1 c = new C2(); + ((C2)c).m("hallo"); + c.m("hallo"); + } + } + """, + "p2/C2.java", + """ + package p2; + import p1.C1; + public class C2 extends C1 { + } + """ + }; + runner.expectedOutputString = "CharSequence.String."; + runner.runConformTest(); +} + public static Class testClass() { return CastTest.class; } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ClassFileReaderTest_1_8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ClassFileReaderTest_1_8.java index 695daeef763..45559f7b3a3 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ClassFileReaderTest_1_8.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ClassFileReaderTest_1_8.java @@ -31,6 +31,7 @@ @SuppressWarnings({ "rawtypes" }) public class ClassFileReaderTest_1_8 extends AbstractRegressionTest { static { +// TESTS_NAMES = new String[] { "testGH2625" }; } public static Test suite() { @@ -470,6 +471,33 @@ public void testBug548596() { ); } + public void testGH2625() { + String[] libs = getDefaultClassPaths(); + int len = libs.length; + System.arraycopy(libs, 0, libs = new String[len+1], 0, len); + // in this jar the num_parameters field of RuntimeInvisibleParameterAnnotations has been manually set to 2 + // (annotations on the 3-arg method a(Function,Object,long)): + libs[libs.length-1] = this.getCompilerTestsPluginDirectoryPath() + File.separator + "workspace" + File.separator + "TestGH2625.jar"; + + runConformTest( + new String[] { + "Test.java", + """ + import a.A; + public class Test { + void test(A a) { + a.m(null, null, 0L); + } + } + """ + }, + "", + libs, + false, + null + ); + } + /** * Produce a nicely formatted type annotation for testing. Exercises the API for type annotations. * Output examples:
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java index a5d45448c24..951a8dcb2f2 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java @@ -5077,17 +5077,37 @@ public void test139() { } //check final modifier public void test140() { - this.runConformTest( - new String[] { - "X.java", - "public enum X {\n" + - " PLUS {/*ANONYMOUS*/}, MINUS;\n" + - " void bar(X x) {\n" + - " Runnable r = (Runnable)x;\n" + - " }\n" + - "}", // ================= - }, - ""); + if (this.complianceLevel < ClassFileConstants.JDK17) { + this.runConformTest( + new String[] { + "X.java", + "public enum X {\n" + + " PLUS {/*ANONYMOUS*/}, MINUS;\n" + + " void bar(X x) {\n" + + " Runnable r = (Runnable)x;\n" + + " }\n" + + "}", // ================= + }, + ""); + } else { + // An enum class E is implicitly sealed if its declaration contains at least one enum constant that has a class body + this.runNegativeTest( + new String[] { + "X.java", + "public enum X {\n" + + " PLUS {/*ANONYMOUS*/}, MINUS;\n" + + " void bar(X x) {\n" + + " Runnable r = (Runnable)x;\n" + + " }\n" + + "}", // ================= + }, + "----------\n" + + "1. ERROR in X.java (at line 4)\n" + + " Runnable r = (Runnable)x;\n" + + " ^^^^^^^^^^^\n" + + "Cannot cast from X to Runnable\n" + + "----------\n"); + } } //check final modifier public void test141() { diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java index b5600204415..2b0f686803c 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericTypeTest.java @@ -22763,19 +22763,7 @@ public void test0705() { } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=97219 public void test0706() { - String outputExpectedBelow17 = (this.complianceLevel == ClassFileConstants.JDK1_6)? - "----------\n" + - "1. WARNING in X.java (at line 9)\n" + - " class BB extends AA { BB test() {return null;} }\n" + - " ^^^^^^\n" + - "Name clash: The method test() of type BB has the same erasure as test() of type AA but does not override it\n" + - "----------\n": - "----------\n" + - "1. ERROR in X.java (at line 9)\n" + - " class BB extends AA { BB test() {return null;} }\n" + - " ^^^^^^\n" + - "Name clash: The method test() of type BB has the same erasure as test() of type AA but does not override it\n" + - "----------\n"; + if (this.complianceLevel < ClassFileConstants.JDK1_7) return; this.runNegativeTest( new String[] { "X.java", @@ -22783,16 +22771,14 @@ public void test0706() { " void foo() {\n" + " BB bb = new BB();\n" + " bb.test();\n" + - " ((AA) bb).test();\n" + + " ((AA) bb).test();\n" + // cast relevant for disambiguation " }\n" + "}\n" + "class AA { AA test() {return null;} }\n" + "class BB extends AA { BB test() {return null;} }\n" + "class CC {}\n", }, - (this.complianceLevel < ClassFileConstants.JDK1_7) - ? outputExpectedBelow17 - : "----------\n" + + "----------\n" + "1. ERROR in X.java (at line 4)\n" + " bb.test();\n" + " ^^^^\n" + @@ -29732,7 +29718,10 @@ public void test0899() { } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=97693 public void test0900() { - this.runNegativeTest( + Runner runner = new Runner(); + runner.customOptions = getCompilerOptions(); + runner.customOptions.put(CompilerOptions.OPTION_ReportUnnecessaryTypeCheck, CompilerOptions.IGNORE); + runner.testFiles = new String[] { "X.java", // ================= "public class X {\n" + @@ -29753,7 +29742,8 @@ public void test0900() { " Zork z;\n" + " }\n" + "}\n", - }, + }; + runner.expectedCompilerLog = "----------\n" + "1. WARNING in X.java (at line 11)\n" + " ((Comparable) new Implements()).toString();\n" + @@ -29769,7 +29759,8 @@ public void test0900() { " Zork z;\n" + " ^^^^\n" + "Zork cannot be resolved to a type\n" + - "----------\n"); + "----------\n"; + runner.runNegativeTest(); } // Object array vs Object into generic method public void test0901() { diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_16.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_16.java index 857897acc23..e14dd9c3c46 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_16.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/JavadocTest_16.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023 Andrey Loskutov (loskutov@gmx.de) and others. + * Copyright (c) 2023, 2024 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 @@ -144,7 +144,26 @@ public int sample() { } ); } - +public void testInlineReturn3() { + if(this.complianceLevel < ClassFileConstants.JDK16) { + return; + } + this.runConformTest( + new String[] { + "X.java", + """ + public class X { + /** {@return {@code true} or else + * {@code false}} + */ + public boolean sample() { + return false; + } + } + """, + } + ); +} public void testInlineReturn_broken1() { if(this.complianceLevel < ClassFileConstants.JDK16) { return; diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java index 6987ac1cacc..5bfe0dab08d 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java @@ -3076,7 +3076,7 @@ public void test043c() { // ambiguous message sends because of substitution from " void test(E e) { e.id(Integer.valueOf(111)); }\n" + " void test(M m) {\n" + " m.id(Integer.valueOf(111));\n" + - " ((E) m).id(Integer.valueOf(111));\n" + + " ((E) m).id(Integer.valueOf(111));\n" + // cast needed for disambiguation " }\n" + " void test(N n) { n.id(Integer.valueOf(111)); }\n" + "}\n" + diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SealedTypesTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SealedTypesTests.java index c1ac8493df7..c6fa2273f48 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SealedTypesTests.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SealedTypesTests.java @@ -6043,4 +6043,143 @@ public static void main(String [] args) { "Compiled and ran fine!"); } + + // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2595 + // [sealed types] ECJ accepts a cast from a disjoint interface to a sealed interface + public void testIssue2595_0() { + runNegativeTest( + new String[] { + "X.java", + """ + interface I { + } + + final class C { + } + + public class X { + void test(C c) { + if (c instanceof I) // Compile-time error! + System.out.println("It's an I"); + } + void test(I i) { + if (i instanceof C) // Compile-time error! + System.out.println("It's a C"); + } + } + """ + }, + "----------\n" + + "1. ERROR in X.java (at line 9)\n" + + " if (c instanceof I) // Compile-time error!\n" + + " ^^^^^^^^^^^^^^\n" + + "Incompatible conditional operand types C and I\n" + + "----------\n" + + "2. ERROR in X.java (at line 13)\n" + + " if (i instanceof C) // Compile-time error!\n" + + " ^^^^^^^^^^^^^^\n" + + "Incompatible conditional operand types I and C\n" + + "----------\n"); + } + + // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2595 + // [sealed types] ECJ accepts a cast from a disjoint interface to a sealed interface + public void testIssue2595_1() { + runNegativeTest( + new String[] { + "X.java", + """ + public class X { + interface I { + } + + sealed class C permits D { + } + + final class D extends C { + } + + void test(C c) { + if (c instanceof I) // Compile-time error! + System.out.println("It's an I"); + } + + void test(I i) { + if (i instanceof C) // Compile-time error! + System.out.println("It's a C"); + } + } + """ + }, + "----------\n" + + "1. ERROR in X.java (at line 12)\n" + + " if (c instanceof I) // Compile-time error!\n" + + " ^^^^^^^^^^^^^^\n" + + "Incompatible conditional operand types X.C and X.I\n" + + "----------\n" + + "2. ERROR in X.java (at line 17)\n" + + " if (i instanceof C) // Compile-time error!\n" + + " ^^^^^^^^^^^^^^\n" + + "Incompatible conditional operand types X.I and X.C\n" + + "----------\n"); + } + + // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2595 + // [sealed types] ECJ accepts a cast from a disjoint interface to a sealed interface + public void testIssue2595_2() { + runConformTest( + new String[] { + "X.java", + """ + public class X { + interface I {} + sealed class C permits D, E {} + non-sealed class D extends C {} + final class E extends C {} + class F extends D implements I {} + + void test (C c) { + if (c instanceof I) + System.out.println("It's an I"); + } + + void test (I i) { + if (i instanceof C) + System.out.println("It's a C"); + } + + public static void main(String [] args) { + new X().test(((C) new X().new F())); + new X().test(((I) new X().new F())); + } + } + """ + }, + "It's an I\nIt's a C"); + } + + // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2595 + // [sealed types] ECJ accepts a cast from a disjoint interface to a sealed interface + public void testIssue2595_3() { + runNegativeTest( + new String[] { + "X.java", + """ + sealed interface Intf permits PermittedA {} + final class PermittedA implements Intf {} + interface Standalone {} + public class X { + public Intf foo(Standalone st) { + return (Intf) st; + } + } + """ + }, + "----------\n" + + "1. ERROR in X.java (at line 6)\r\n" + + " return (Intf) st;\r\n" + + " ^^^^^^^^^\n" + + "Cannot cast from Standalone to Intf\n" + + "----------\n"); + } } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchPatternTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchPatternTest.java index 11f9d7cf451..bdc0abd2bc1 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchPatternTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchPatternTest.java @@ -7882,7 +7882,7 @@ public void testIssue2319() { } // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2503 // [Switch Expression] Switching on sealed interface instance compiles even when the switch expression does not cover all possible input values - public void _testIssue2503() { + public void testIssue2503() { runNegativeTest( new String[] { "X.java", @@ -7911,7 +7911,7 @@ public static void main(String[] args) { } // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2503 // [Switch Expression] Switching on sealed interface instance compiles even when the switch expression does not cover all possible input values - public void _testIssue2503_2() { + public void testIssue2503_2() { runNegativeTest( new String[] { "X.java", @@ -7933,11 +7933,48 @@ public static void main(String[] args) { }, "----------\n" + "1. ERROR in X.java (at line 9)\n" - + " System.out.println(switch((I) new J()) {\n" - + " ^^^^^^^^^^^\n" + + " System.out.println(switch((I) new J() {}) {\n" + + " ^^^^^^^^^^^^^^\n" + "A switch expression should have a default case\n" + "----------\n"); } + // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2503 + // [Switch Expression] Switching on sealed interface instance compiles even when the switch expression does not cover all possible input values + public void testIssue2503_3() { + runNegativeTest( + new String[] { + "X.java", + """ + sealed interface Outer permits Inner, Foo {} + sealed interface Inner extends Outer { + public static record A() implements Inner {} + public static record B() implements Inner {} + } + non-sealed interface Foo extends Outer {} + public class X { + public static void main(String[] args) { + Outer element = new FooImpl(); + + String test = switch(element) { + case Inner.A a -> "a"; + case Inner.B b -> "b"; + }; + + System.out.println(test); + } + + private static record FooImpl() implements Foo {} + } + """ + }, + "----------\n" + + "1. ERROR in X.java (at line 11)\n" + + " String test = switch(element) {\n" + + " ^^^^^^^\n" + + "A switch expression should have a default case\n" + + "----------\n"); + } + // https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2508 // [Switch expression] Compiler erroneously treats guarded case patterns as covering switch selector type public void testIssue2508() { diff --git a/org.eclipse.jdt.core.tests.compiler/workspace/TestGH2625.jar b/org.eclipse.jdt.core.tests.compiler/workspace/TestGH2625.jar new file mode 100644 index 00000000000..698dfacf661 Binary files /dev/null and b/org.eclipse.jdt.core.tests.compiler/workspace/TestGH2625.jar differ diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunVariousSealedTypeTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunVariousSealedTypeTests.java new file mode 100644 index 00000000000..bd2a7fa9995 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/RunVariousSealedTypeTests.java @@ -0,0 +1,133 @@ +/******************************************************************************* +* Copyright (c) 2024 Advantest Europe GmbH 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: +* Srikanth Sankaran - initial implementation +*******************************************************************************/ + +package org.eclipse.jdt.core.tests; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.eclipse.jdt.core.tests.builder.IncrementalTests; +import org.eclipse.jdt.core.tests.compiler.regression.BatchCompilerTest_15; +import org.eclipse.jdt.core.tests.compiler.regression.ClassFileReaderTest_17; +import org.eclipse.jdt.core.tests.compiler.regression.NegativeTypeAnnotationTest; +import org.eclipse.jdt.core.tests.compiler.regression.NullAnnotationTests21; +import org.eclipse.jdt.core.tests.compiler.regression.PatternMatching16Test; +import org.eclipse.jdt.core.tests.compiler.regression.RecordPatternProjectTest; +import org.eclipse.jdt.core.tests.compiler.regression.RecordPatternTest; +import org.eclipse.jdt.core.tests.compiler.regression.RecordsRestrictedClassTest; +import org.eclipse.jdt.core.tests.compiler.regression.ScannerTest; +import org.eclipse.jdt.core.tests.compiler.regression.SealedTypesTests; +import org.eclipse.jdt.core.tests.compiler.regression.SwitchPatternTest; +import org.eclipse.jdt.core.tests.compiler.regression.SwitchPatternTest21; +import org.eclipse.jdt.core.tests.compiler.regression.UnnamedPatternsAndVariablesTest; +import org.eclipse.jdt.core.tests.dom.ASTConverter_15Test; +import org.eclipse.jdt.core.tests.dom.ASTConverter_17Test; +import org.eclipse.jdt.core.tests.dom.ASTTest; +import org.eclipse.jdt.core.tests.dom.ConverterTestSetup; +import org.eclipse.jdt.core.tests.formatter.FormatterBugsTests; +import org.eclipse.jdt.core.tests.formatter.FormatterRegressionTests; +import org.eclipse.jdt.core.tests.model.CompletionTests16_1; +import org.eclipse.jdt.core.tests.model.CompletionTests17; +import org.eclipse.jdt.core.tests.model.Java21ElementTests; +import org.eclipse.jdt.core.tests.model.JavaSearchBugs15Tests; +import org.eclipse.jdt.core.tests.model.JavaSearchBugs17Tests; +import org.eclipse.jdt.core.tests.model.JavaSearchBugs19Tests; +import org.eclipse.jdt.core.tests.model.ReconcilerTests; +import org.eclipse.jdt.core.tests.model.ReconcilerTests21; +import org.eclipse.jdt.core.tests.model.ResolveTests21; +import org.eclipse.jdt.core.tests.model.SealedTypeModelTests; +import org.eclipse.jdt.core.tests.model.TypeHierarchyTests; +import org.eclipse.jdt.core.tests.rewrite.describing.ASTRewritingTypeDeclTest; +import org.eclipse.jdt.core.tests.util.AbstractCompilerTest; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +@SuppressWarnings({"rawtypes", "unchecked"}) +public class RunVariousSealedTypeTests extends TestCase { + + public RunVariousSealedTypeTests(String name) { + super(name); + } + public static Class[] getAllTestClasses() { + return new Class[] { +// SealedTypeElementProcessor.class, + IncrementalTests.class, + BatchCompilerTest_15.class, + ClassFileReaderTest_17.class, + NegativeTypeAnnotationTest.class, + NullAnnotationTests21.class, + PatternMatching16Test.class, + RecordPatternProjectTest.class, + RecordPatternTest.class, + RecordsRestrictedClassTest.class, + ScannerTest.class, + SealedTypesTests.class, + SwitchPatternTest.class, + SwitchPatternTest21.class, + UnnamedPatternsAndVariablesTest.class, + ASTRewritingTypeDeclTest.class, + ASTConverter_15Test.class, + ASTConverter_17Test.class, + ASTTest.class, + FormatterBugsTests.class, + FormatterRegressionTests.class, + CompletionTests16_1.class, + CompletionTests17.class, + Java21ElementTests.class, + JavaSearchBugs15Tests.class, + JavaSearchBugs17Tests.class, + JavaSearchBugs19Tests.class, + ReconcilerTests.class, + ReconcilerTests21.class, + ResolveTests21.class, + SealedTypeModelTests.class, + TypeHierarchyTests.class, + }; + } + + public static Test suite() { + TestSuite ts = new TestSuite(RunVariousSwitchTests.class.getName()); + + Class[] testClasses = getAllTestClasses(); + addTestsToSuite(ts, testClasses); + + AbstractCompilerTest.setpossibleComplianceLevels(AbstractCompilerTest.F_1_8); + + return ts; + } + public static void addTestsToSuite(TestSuite suite, Class[] testClasses) { + + for (int i = 0; i < testClasses.length; i++) { + Class testClass = testClasses[i]; + // call the suite() method and add the resulting suite to the suite + try { + Method suiteMethod = testClass.getDeclaredMethod("suite", new Class[0]); //$NON-NLS-1$ + Test test = (Test)suiteMethod.invoke(null, new Object[0]); + suite.addTest(test); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.getTargetException().printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } + } + } + protected void tearDown() throws Exception { + ConverterTestSetup.PROJECT_SETUP = false; + super.tearDown(); + } +} \ No newline at end of file diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java index 50725199053..d0d3b374509 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS4Test.java @@ -9346,7 +9346,7 @@ public void test0272() throws JavaModelException { assertEquals("Not an expression statement", ASTNode.EXPRESSION_STATEMENT, statement2.getNodeType()); Expression expression2 = ((ExpressionStatement) statement2).getExpression(); assertEquals("Not a method invocation", ASTNode.METHOD_INVOCATION, expression2.getNodeType()); - ITypeBinding typeBinding = ((MethodInvocation) expression2).resolveTypeBinding(); + ITypeBinding typeBinding = expression2.resolveTypeBinding(); assertTrue("Not a capture", typeBinding.isCapture()); assertNull("No binary type", typeBinding.getBinaryName()); } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS8Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS8Test.java index 67957399250..6ade032e52c 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS8Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15JLS8Test.java @@ -9334,7 +9334,7 @@ public void test0272() throws JavaModelException { assertEquals("Not an expression statement", ASTNode.EXPRESSION_STATEMENT, statement2.getNodeType()); Expression expression2 = ((ExpressionStatement) statement2).getExpression(); assertEquals("Not a method invocation", ASTNode.METHOD_INVOCATION, expression2.getNodeType()); - ITypeBinding typeBinding = ((MethodInvocation) expression2).resolveTypeBinding(); + ITypeBinding typeBinding = expression2.resolveTypeBinding(); assertTrue("Not a capture", typeBinding.isCapture()); assertNull("No binary type", typeBinding.getBinaryName()); } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java index 8e7b0cda48a..4f00d2300b4 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter15Test.java @@ -9381,7 +9381,7 @@ public void test0272() throws JavaModelException { assertEquals("Not an expression statement", ASTNode.EXPRESSION_STATEMENT, statement2.getNodeType()); Expression expression2 = ((ExpressionStatement) statement2).getExpression(); assertEquals("Not a method invocation", ASTNode.METHOD_INVOCATION, expression2.getNodeType()); - ITypeBinding typeBinding = ((MethodInvocation) expression2).resolveTypeBinding(); + ITypeBinding typeBinding = expression2.resolveTypeBinding(); assertTrue("Not a capture", typeBinding.isCapture()); assertNull("No binary type", typeBinding.getBinaryName()); } @@ -11372,7 +11372,7 @@ public void test0350() throws JavaModelException { true, true); ExpressionStatement statement = (ExpressionStatement) getASTNode(unit, 0, 1, 0); - ITypeBinding binding = ((MethodInvocation) statement.getExpression()).resolveTypeBinding(); + ITypeBinding binding = statement.getExpression().resolveTypeBinding(); assertTrue("Should be seen as a wildcard (really an intersection type)", binding.isWildcardType()); assertNull("should be null", binding.getGenericTypeOfWildcardType()); } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java index abf805f2d90..f02be4473d0 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter18Test.java @@ -1098,7 +1098,7 @@ public void test0007() throws JavaModelException { MethodDeclaration method = (MethodDeclaration) node; Type receiver = method.getReceiverType(); assertEquals("Not a simple type", ASTNode.SIMPLE_TYPE, receiver.getNodeType()); - assertEquals("Incorrect receiver signature", "@Marker @Marker2 X", ((SimpleType) receiver).toString()); + assertEquals("Incorrect receiver signature", "@Marker @Marker2 X", receiver.toString()); assertEquals("Incorrect annotations on receiver", 2, ((SimpleType) receiver).annotations().size()); assertNull("Incorrect receiver qualfier", method.getReceiverQualifier()); } @@ -1126,7 +1126,7 @@ public void test0008() throws JavaModelException { MethodDeclaration method = innerType.getMethods()[0]; Type receiver = method.getReceiverType(); assertEquals("Not a simple type", ASTNode.SIMPLE_TYPE, receiver.getNodeType()); - assertEquals("Incorrect receiver signature", "@Marker @Marker2 X", ((SimpleType) receiver).toString()); + assertEquals("Incorrect receiver signature", "@Marker @Marker2 X", receiver.toString()); assertEquals("Incorrect annotations on receiver", 2, ((SimpleType) receiver).annotations().size()); assertNotNull("Incorrect receiver qualfier", method.getReceiverQualifier()); assertEquals("Incorrect receiver qualfier", "X", method.getReceiverQualifier().getFullyQualifiedName()); @@ -2097,12 +2097,12 @@ public void testBug403132() throws JavaModelException { MethodDeclaration method = (MethodDeclaration) node; Type receiver = method.getReceiverType(); assertEquals("Not a qualified type", ASTNode.QUALIFIED_TYPE, receiver.getNodeType()); - assertEquals("Incorrect receiver", "@A X.@B Y", ((QualifiedType) receiver).toString()); + assertEquals("Incorrect receiver", "@A X.@B Y", receiver.toString()); assertEquals("Incorrect method signature", "public Z(@A X.@B Y Y.this,String str){\n}\n", method.toString()); method = (MethodDeclaration) type.bodyDeclarations().get(1); receiver = method.getReceiverType(); - assertEquals("Incorrect receiver", "@A X.@B Y.@C Z", ((QualifiedType) receiver).toString()); + assertEquals("Incorrect receiver", "@A X.@B Y.@C Z", receiver.toString()); assertEquals("Incorrect method signature", "public void foo(@A X.@B Y.@C Z this,String str){\n}\n", method.toString()); } public void testParameterizedReceiverType() throws JavaModelException { @@ -3857,8 +3857,8 @@ public void test416559() throws JavaModelException { VariableDeclaration variableDeclaration = (VariableDeclaration) lambdaExpression.parameters().get(0); IVariableBinding variableBinding = variableDeclaration.resolveBinding(); IMethodBinding methodBinding = lambdaExpression.resolveMethodBinding(); - String methodKey = ((IBinding) methodBinding).getKey(); - String variableKey = ((IBinding) variableBinding).getKey(); + String methodKey = methodBinding.getKey(); + String variableKey = variableBinding.getKey(); assertTrue(variableKey.regionMatches(0, methodKey, 0, methodKey.length())); fragments = field[1].fragments(); @@ -3868,7 +3868,7 @@ public void test416559() throws JavaModelException { variableDeclaration = (VariableDeclaration) lambdaExpression.parameters().get(0); variableBinding = variableDeclaration.resolveBinding(); - assertNotSame(variableKey.intern(), ((IBinding) variableBinding).getKey().intern()); + assertNotSame(variableKey.intern(), variableBinding.getKey().intern()); } /* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=420458 diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java index e53b8dbc720..372a57e5757 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java @@ -1327,7 +1327,7 @@ public void testBug530803_1() throws Exception { // common check for both parts: Consumer validateBinding = (IBinding binding) -> { assertTrue("Not ModuleBinding", binding instanceof IModuleBinding); - IAnnotationBinding[] annotations = ((IModuleBinding) binding).getAnnotations(); + IAnnotationBinding[] annotations = binding.getAnnotations(); assertEquals("Number of annotations", 1, annotations.length); assertEquals("Annotation type", "Deprecated", annotations[0].getAnnotationType().getName()); }; diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTModelBridgeTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTModelBridgeTests.java index bf44ae61d85..2db09a5979b 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTModelBridgeTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTModelBridgeTests.java @@ -1352,7 +1352,7 @@ public void testCreateBindings24() throws CoreException { assertBindingsEqual( "Lpack/package-info;", bindings); - IAnnotationBinding[] annotations = ((ITypeBinding) bindings[0]).getAnnotations(); + IAnnotationBinding[] annotations = bindings[0].getAnnotations(); assertBindingsEqual( "@Ljava/lang/Deprecated;", annotations); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java index 75b9eac3a8e..e842daae56f 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java @@ -13,12 +13,10 @@ *******************************************************************************/ package org.eclipse.jdt.core.tests.model; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.io.PrintStream; import java.net.URI; import java.net.URL; @@ -1684,19 +1682,11 @@ protected void copyDirectory(File source, File target) throws IOException { } } } - protected IFile createFile(String path, InputStream content) throws CoreException { - IFile file = getFile(path); - file.create(content, true, null); - try { - content.close(); - } catch (IOException e) { - e.printStackTrace(); - } - return file; - } protected IFile createFile(String path, byte[] content) throws CoreException { - return createFile(path, new ByteArrayInputStream(content)); + IFile file = getFile(path); + file.create(content, true, false, null); + return file; } protected IFile createFile(String path, String content) throws CoreException { @@ -3405,7 +3395,7 @@ protected void createSourceFiles(IJavaProject project, String[] sources) throws if (!folder.exists()) this.createFolder(folder.getFullPath()); IFile file = project.getProject().getFile(new Path(sources[i])); - file.create(new ByteArrayInputStream(sources[i+1].getBytes()), true, monitor); + file.create(sources[i+1].getBytes(), true, false, monitor); } } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java index f1dc8f06cf8..66102ee4be3 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java @@ -1678,7 +1678,7 @@ public void testBug153133() throws JavaModelException { // Need to get type members constructors for (int i = 0; i < length; i++) { assertTrue(members[i] instanceof IMember); - if (((IMember)members[i]).getElementType() == IJavaElement.TYPE) { + if (members[i].getElementType() == IJavaElement.TYPE) { IType typeMember = (IType) members[i]; String typeName = typeMember.getElementName(); IMethod[] methods = typeMember.getMethods(); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java index 25ab30a0d56..aa19554d859 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java @@ -19,7 +19,6 @@ *******************************************************************************/ package org.eclipse.jdt.core.tests.model; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -880,7 +879,7 @@ public void testClasspathCorruption() throws CoreException { +" \n"; IFile fileRsc = p1.getProject().getFile(JavaProject.CLASSPATH_FILENAME); - fileRsc.setContents(new ByteArrayInputStream(newCPContent.getBytes()), true, false, null); + fileRsc.setContents(newCPContent.getBytes(), true, false, null); /* File file = p1.getProject().getFile(JavaProject.CLASSPATH_FILENAME).getLocation().toFile(); if (file.exists()){ @@ -959,7 +958,7 @@ public void run(IProgressMonitor monitor) throws CoreException { +" \n"; IFile fileRsc = p1.getProject().getFile(JavaProject.CLASSPATH_FILENAME); - fileRsc.setContents(new ByteArrayInputStream(newCPContent.getBytes()), true, false, null); + fileRsc.setContents(newCPContent.getBytes(), true, false, null); p1.close(); assertEquals("output location should not have been refreshed", "/P1", p1.getOutputLocation().toString()); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java index e0c7c2cd661..c100561882b 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java @@ -242,7 +242,7 @@ public void testBug29832() throws Exception { new String[]{}, new String[]{"JCL_LIB"}, ""); - this.createFile("/P1/lib.jar", f.getContents()); + this.createFile("/P1/lib.jar", f.readAllBytes()); this.addLibraryEntry(p, "/P1/lib.jar", true); // create P2 @@ -358,7 +358,7 @@ public void testBug33560() throws Exception { new String[]{}, new String[]{"JCL_LIB"}, ""); - this.createFile("/P1/lib.jar", f.getContents()); + this.createFile("/P1/lib.jar", f.readAllBytes()); this.addLibraryEntry(p, "/P1/lib.jar", true); // create P2 @@ -5596,7 +5596,7 @@ public void testBug326610() throws Exception { "1.5"); this.createFolder("/P1/src/p"); - this.createFile("/P1/lib.jar", f.getContents()); + this.createFile("/P1/lib.jar", f.readAllBytes()); this.addLibraryEntry(p, "/P1/lib.jar", true); this.createFile( @@ -6168,7 +6168,7 @@ public void test479656() throws Exception { new String[]{"src"}, new String[]{"JCL_LIB"}, "bin", "1.5"); - this.createFile("/P/bug479656.jar", f.getContents()); + this.createFile("/P/bug479656.jar", f.readAllBytes()); this.addLibraryEntry(p, "/P/bug479656.jar", true); this.createFolder("/P/src/com/google/gwt/event/shared"); this.createFile( diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveElementsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveElementsTests.java index b978724491a..f422184b33b 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveElementsTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveElementsTests.java @@ -405,7 +405,7 @@ public void testCopyFieldsMultiStatus() throws CoreException { typeDest.getJavaModel().copy(fieldsSource, dests, null, null, false, null); } catch (JavaModelException jme) { assertTrue("Should be multistatus", jme.getStatus().isMultiStatus()); - assertTrue("Should be an invalid destination", ((IJavaModelStatus)jme.getStatus().getChildren()[0]).getCode()== IJavaModelStatusConstants.INVALID_DESTINATION); + assertTrue("Should be an invalid destination", jme.getStatus().getChildren()[0].getCode()== IJavaModelStatusConstants.INVALID_DESTINATION); e = true; } assertTrue("Should have been an exception", e); @@ -457,7 +457,7 @@ public void testCopyFieldsMultiStatusInDifferentProject() throws CoreException { typeDest.getJavaModel().copy(fieldsSource, dests, null, null, false, null); } catch (JavaModelException jme) { assertTrue("Should be multistatus", jme.getStatus().isMultiStatus()); - assertTrue("Should be an invalid destination", ((IJavaModelStatus)jme.getStatus().getChildren()[0]).getCode()== IJavaModelStatusConstants.INVALID_DESTINATION); + assertTrue("Should be an invalid destination", jme.getStatus().getChildren()[0].getCode()== IJavaModelStatusConstants.INVALID_DESTINATION); e = true; } assertTrue("Should have been an exception", e); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveTests.java index c47d315a3da..394245dcf6d 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveTests.java @@ -15,6 +15,7 @@ import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jdt.core.*; @@ -58,7 +59,7 @@ public void copyNegative(IJavaElement[] elements, IJavaElement[] destinations, I * and forcing. The operation should succeed, so any exceptions * encountered are thrown. */ -public IJavaElement copyPositive(IJavaElement element, IJavaElement container, IJavaElement sibling, String rename, boolean force) throws JavaModelException { +public IJavaElement copyPositive(IJavaElement element, IJavaElement container, IJavaElement sibling, String rename, boolean force) throws CoreException { // if forcing, ensure that a name collision exists if (force) { IJavaElement collision = generateHandle(element, rename, container); @@ -75,6 +76,7 @@ public IJavaElement copyPositive(IJavaElement element, IJavaElement container, I // ensure the original element still exists assertTrue("The original element must still exist", element.exists()); + element.getJavaProject().getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); waitForAutoBuild(); // generate the new element handle diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/FactoryTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/FactoryTests.java index 152b276118b..c9c0cfd0cd2 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/FactoryTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/FactoryTests.java @@ -76,7 +76,7 @@ public void testCreateCompilationUnits() throws CoreException { assertTrue("wrong object B created", objectB instanceof ICompilationUnit); assertTrue("compilation unit B does not exist", objectB.exists()); - assertEquals("should share project", ((ICompilationUnit)objectA).getJavaProject(), ((ICompilationUnit)objectB).getJavaProject()); + assertEquals("should share project", objectA.getJavaProject(), objectB.getJavaProject()); } finally { this.deleteProject("P"); } @@ -103,7 +103,7 @@ public void testCreateCompilationUnitsNotOnClasspath() throws CoreException { assertTrue("wrong object B created", objectB instanceof ICompilationUnit); assertTrue("compilation unit B should not exist", !objectB.exists()); - assertEquals("should share project", ((ICompilationUnit)objectA).getJavaProject(), ((ICompilationUnit)objectB).getJavaProject()); + assertEquals("should share project", objectA.getJavaProject(), objectB.getJavaProject()); IJavaElement objectC = JavaCore.create(fileC); assertTrue("tooling object C not created", objectC != null); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/GetSourceTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/GetSourceTests.java index 835bb984bdb..ff913f549b9 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/GetSourceTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/GetSourceTests.java @@ -13,8 +13,6 @@ *******************************************************************************/ package org.eclipse.jdt.core.tests.model; -import junit.framework.Test; - import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.IAnnotation; import org.eclipse.jdt.core.ICompilationUnit; @@ -23,11 +21,12 @@ import org.eclipse.jdt.core.ILocalVariable; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IPackageDeclaration; -import org.eclipse.jdt.core.ISourceReference; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeParameter; import org.eclipse.jdt.core.JavaModelException; +import junit.framework.Test; + public class GetSourceTests extends ModifyingResourceTests { ICompilationUnit cu; @@ -309,7 +308,7 @@ public void testImport() throws JavaModelException { public void testLocalVariable1() throws JavaModelException { ILocalVariable var = getLocalVariable("/P/p/X.java", "var1 = 2;", "var1"); - String actualSource = ((ISourceReference)var).getSource(); + String actualSource = var.getSource(); String expectedSource = "final int var1 = 2;"; assertSourceEquals("Unexpected source'", expectedSource, actualSource); } @@ -320,7 +319,7 @@ public void testLocalVariable1() throws JavaModelException { public void testLocalVariable2() throws JavaModelException { ILocalVariable var = getLocalVariable("/P/p/X.java", "var2;", "var2"); - String actualSource = ((ISourceReference)var).getSource(); + String actualSource = var.getSource(); String expectedSource = "Object var2;"; assertSourceEquals("Unexpected source'", expectedSource, actualSource); } @@ -331,7 +330,7 @@ public void testLocalVariable2() throws JavaModelException { public void testLocalVariable3() throws JavaModelException { ILocalVariable var = getLocalVariable("/P/p/X.java", "i = 0;", "i"); - String actualSource = ((ISourceReference)var).getSource(); + String actualSource = var.getSource(); String expectedSource = "int i = 0"; // semi-colon is not part of the local declaration in a for statement assertSourceEquals("Unexpected source'", expectedSource, actualSource); } @@ -342,7 +341,7 @@ public void testLocalVariable3() throws JavaModelException { public void testLocalVariable4() throws JavaModelException { ILocalVariable var = getLocalVariable("/P/p/X.java", "s) {", "s"); - String actualSource = ((ISourceReference)var).getSource(); + String actualSource = var.getSource(); String expectedSource = "String s"; assertSourceEquals("Unexpected source'", expectedSource, actualSource); } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/IndexManagerTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/IndexManagerTests.java index de6c23f1372..1335b682c8a 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/IndexManagerTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/IndexManagerTests.java @@ -13,7 +13,6 @@ *******************************************************************************/ package org.eclipse.jdt.core.tests.model; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.file.Paths; import java.util.ArrayList; @@ -184,11 +183,10 @@ private void changeFile(String path, String content) { throw new AssertionError("File expected at path " + path); } - try (ByteArrayInputStream stream = new ByteArrayInputStream(content.getBytes())) { - file.setContents(stream, IResource.FORCE, new NullProgressMonitor()); - } catch (IOException | CoreException e) { - e.printStackTrace(); - throw new AssertionError("Failed to update file " + e.getMessage()); + try { + file.setContents(content.getBytes(), IResource.FORCE, new NullProgressMonitor()); + } catch (CoreException e) { + throw new AssertionError("Failed to update file " + e.getMessage(), e); } } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Java9ElementTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Java9ElementTests.java index bcbd446eef5..485a575d14c 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Java9ElementTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/Java9ElementTests.java @@ -984,7 +984,7 @@ public void testFindModule1() throws CoreException, IOException { assertNotNull("module", modTest); assertEquals("module name", "test", modTest.getElementName()); IJavaElement root = parentChain(modTest, new int[] { COMPILATION_UNIT, PACKAGE_FRAGMENT, PACKAGE_FRAGMENT_ROOT }); - String rootPath = ((IPackageFragmentRoot) root).getPath().toString(); + String rootPath = root.getPath().toString(); assertEquals("package fragment root path", "/Test/src", rootPath); // search source module in project dependency: @@ -992,7 +992,7 @@ public void testFindModule1() throws CoreException, IOException { assertNotNull("module", modZero); assertEquals("module name", "mod.zero", modZero.getElementName()); root = parentChain(modZero, new int[] { COMPILATION_UNIT, PACKAGE_FRAGMENT, PACKAGE_FRAGMENT_ROOT }); - rootPath = ((IPackageFragmentRoot) root).getPath().toString(); + rootPath = root.getPath().toString(); assertEquals("package fragment root path", "/mod.zero/src", rootPath); // search binary module in jar dependency: @@ -1000,7 +1000,7 @@ public void testFindModule1() throws CoreException, IOException { assertNotNull("module", modOne); assertEquals("module name", "mod.one", modOne.getElementName()); root = parentChain(modOne, new int[] { CLASS_FILE, PACKAGE_FRAGMENT, PACKAGE_FRAGMENT_ROOT }); - rootPath = ((IPackageFragmentRoot) root).getPath().toString(); + rootPath = root.getPath().toString(); assertEquals("package fragment root path", "/Test/mod.one.jar", rootPath); IModuleDescription notSuchModule = javaProject.findModule("does.not.exist", null); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElement8Tests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElement8Tests.java index 851423c58ee..72f0ce94b4a 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElement8Tests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaElement8Tests.java @@ -13,12 +13,10 @@ *******************************************************************************/ package org.eclipse.jdt.core.tests.model; -import java.io.ByteArrayInputStream; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.HashMap; -import junit.framework.Test; - import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.runtime.CoreException; @@ -43,6 +41,8 @@ import org.eclipse.jdt.internal.core.LambdaMethod; import org.eclipse.jdt.internal.core.SourceMethod; +import junit.framework.Test; + @SuppressWarnings({"rawtypes", "unchecked"}) public class JavaElement8Tests extends AbstractJavaModelTests { @@ -646,7 +646,7 @@ public void testBug485080() throws Exception { buf.append(" }\n"); buf.append("}\n"); String content= buf.toString(); - file.create(new ByteArrayInputStream(content.getBytes("UTF-8")), 0, null); + file.create(content.getBytes(StandardCharsets.UTF_8), 0, null); // create a CU from that file: ICompilationUnit cu = JavaCore.createCompilationUnitFrom(file); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java index 4a02f669ddc..97e9fe2ba4f 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java @@ -14388,7 +14388,7 @@ public void testBug469320_0001() throws CoreException { try { ProjectA = createJavaProject("ProjectA", new String[] {""}, new String[] {"JCL15_LIB"}, "","1.5"); IFile f = getFile("/JavaSearchBugs/lib/common.jar"); - this.createFile("/ProjectA/common.jar", f.getContents()); + this.createFile("/ProjectA/common.jar", f.readAllBytes()); this.addLibraryEntry(ProjectA, "/ProjectA/common.jar", false); createFolder("/ProjectA/test"); createFile("/ProjectA/test/Validation.java", diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModifyingResourceTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModifyingResourceTests.java index 52fe032e3a7..5f273b68732 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModifyingResourceTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModifyingResourceTests.java @@ -13,11 +13,9 @@ *******************************************************************************/ package org.eclipse.jdt.core.tests.model; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; @@ -179,25 +177,14 @@ protected void createExternalFile(String relativePath, String contents) { } @Override -protected IFile createFile(String path, InputStream content) throws CoreException { - IFile file = getFile(path); - file.create(content, true, null); - try { - content.close(); - } catch (IOException e) { - e.printStackTrace(); - } +protected IFile createFile(String path, byte[] content) throws CoreException { + IFile file = super.createFile(path, content); if(!isIndexDisabledForTest()) { JavaModelManager.getIndexManager().waitForIndex(false, null); } return file; } -@Override -protected IFile createFile(String path, byte[] content) throws CoreException { - return createFile(path, new ByteArrayInputStream(content)); -} - @Override protected IFile createFile(String path, String content) throws CoreException { return createFile(path, content.getBytes()); @@ -228,8 +215,7 @@ protected void deleteFolder(String folderPath) throws CoreException { } protected IFile editFile(String path, String content) throws CoreException { IFile file = getFile(path); - InputStream input = new ByteArrayInputStream(content.getBytes()); - file.setContents(input, IResource.FORCE, null); + file.setContents(content.getBytes(), IResource.FORCE, null); return file; } /* diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests18.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests18.java index 982bee48042..4b9806c9939 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests18.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests18.java @@ -16,7 +16,6 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.BindingKey; -import org.eclipse.jdt.core.ICodeAssist; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.ILocalVariable; @@ -1031,7 +1030,7 @@ public void testBug408230a() throws CoreException { ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); String selectString = "barg"; - IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); + IJavaElement [] variable = unit.codeSelect(source.lastIndexOf(selectString), selectString.length()); assertEquals(1, variable.length); } finally { deleteProject("P"); @@ -1056,7 +1055,7 @@ public void testBug408230b() throws CoreException { ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); String selectString = "barg"; - IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); + IJavaElement [] variable = unit.codeSelect(source.lastIndexOf(selectString), selectString.length()); assertEquals(1, variable.length); } finally { deleteProject("P"); @@ -1081,7 +1080,7 @@ public void testBug408230c() throws CoreException { ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); String selectString = "barg"; - IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); + IJavaElement [] variable = unit.codeSelect(source.lastIndexOf(selectString), selectString.length()); assertEquals(1, variable.length); } finally { deleteProject("P"); @@ -1104,7 +1103,7 @@ public void testBug408230d() throws CoreException { ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); String selectString = "barg"; - IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); + IJavaElement [] variable = unit.codeSelect(source.lastIndexOf(selectString), selectString.length()); assertEquals(1, variable.length); } finally { deleteProject("P"); @@ -1127,7 +1126,7 @@ public void testBug408230e() throws CoreException { ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); String selectString = "aarg"; - IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); + IJavaElement [] variable = unit.codeSelect(source.lastIndexOf(selectString), selectString.length()); assertEquals(1, variable.length); } finally { deleteProject("P"); @@ -1150,7 +1149,7 @@ public void testBug408230f() throws CoreException { ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); String selectString = "aarg"; - IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); + IJavaElement [] variable = unit.codeSelect(source.lastIndexOf(selectString), selectString.length()); assertEquals(1, variable.length); } finally { deleteProject("P"); @@ -1176,7 +1175,7 @@ public void testBug408230g() throws CoreException { ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); String selectString = "aarg"; - IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); + IJavaElement [] variable = unit.codeSelect(source.lastIndexOf(selectString), selectString.length()); assertEquals(1, variable.length); } finally { deleteProject("P"); @@ -1202,7 +1201,7 @@ public void testBug408230h() throws CoreException { ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); String selectString = "aarg"; - IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); + IJavaElement [] variable = unit.codeSelect(source.lastIndexOf(selectString), selectString.length()); assertEquals(1, variable.length); } finally { deleteProject("P"); @@ -1228,7 +1227,7 @@ public void testBug408230i() throws CoreException { ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); String selectString = "aarg"; - IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); + IJavaElement [] variable = unit.codeSelect(source.lastIndexOf(selectString), selectString.length()); assertEquals(1, variable.length); } finally { deleteProject("P"); @@ -1254,7 +1253,7 @@ public void testBug408230j() throws CoreException { ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); String selectString = "aarg"; - IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); + IJavaElement [] variable = unit.codeSelect(source.lastIndexOf(selectString), selectString.length()); assertEquals(1, variable.length); } finally { deleteProject("P"); @@ -1280,7 +1279,7 @@ public void testBug408230k() throws CoreException { ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); String selectString = "aarg"; - IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); + IJavaElement [] variable = unit.codeSelect(source.lastIndexOf(selectString), selectString.length()); assertEquals(1, variable.length); } finally { deleteProject("P"); @@ -1306,7 +1305,7 @@ public void testBug408230l() throws CoreException { ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); String selectString = "aarg"; - IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); + IJavaElement [] variable = unit.codeSelect(source.lastIndexOf(selectString), selectString.length()); assertEquals(1, variable.length); } finally { deleteProject("P"); @@ -1332,7 +1331,7 @@ public void testBug408230m() throws CoreException { ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); String selectString = "aarg"; - IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); + IJavaElement [] variable = unit.codeSelect(source.lastIndexOf(selectString), selectString.length()); assertEquals(1, variable.length); } finally { deleteProject("P"); @@ -1358,7 +1357,7 @@ public void testBug408230n() throws CoreException { ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); String selectString = "aarg"; - IJavaElement [] variable = ((ICodeAssist) unit).codeSelect(source.lastIndexOf(selectString), selectString.length()); + IJavaElement [] variable = unit.codeSelect(source.lastIndexOf(selectString), selectString.length()); assertEquals(1, variable.length); } finally { deleteProject("P"); diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java index 0808618fb1d..38c83e78d9c 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java @@ -21,7 +21,6 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.IAnnotation; -import org.eclipse.jdt.core.ICodeAssist; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; @@ -362,7 +361,7 @@ public void testParamAnnotations() throws CoreException { waitForAutoBuild(); ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); - IJavaElement[] variable = ((ICodeAssist) unit).codeSelect(source.indexOf("processor"), "processor".length()); + IJavaElement[] variable = unit.codeSelect(source.indexOf("processor"), "processor".length()); assertEquals(1, variable.length); String annotationString = "@Default [in processor [in Test(String) [in X [in X.java [in p [in src [in P]]]]]]]"; @@ -432,7 +431,7 @@ public void testParamAnnotations3() throws CoreException { waitForAutoBuild(); ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); - IJavaElement[] variable = ((ICodeAssist) unit).codeSelect(source.indexOf("processor"), "processor".length()); + IJavaElement[] variable = unit.codeSelect(source.indexOf("processor"), "processor".length()); assertEquals(1, variable.length); String annotationString1 = "@Default [in processor [in Test(int, String, int) [in X [in X.java [in p [in src [in P]]]]]]]"; diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/WorkingCopyTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/WorkingCopyTests.java index c1772876bdf..e9aec2960b4 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/WorkingCopyTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/WorkingCopyTests.java @@ -655,25 +655,25 @@ public void testNonExistingCU() throws JavaModelException { try { // getBuffer() workingCopy = nonExistingCU.getWorkingCopy(null); - assertSourceEquals("Buffer should be empty", "", ((IOpenable)workingCopy).getBuffer().getContents()); + assertSourceEquals("Buffer should be empty", "", workingCopy.getBuffer().getContents()); // exists() - assertTrue("Working copy should exists", ((IJavaElement)workingCopy).exists()); + assertTrue("Working copy should exists", workingCopy.exists()); // getCorrespondingResource() - assertEquals("Corresponding resource should be null", null, ((IJavaElement)workingCopy).getCorrespondingResource()); + assertEquals("Corresponding resource should be null", null, workingCopy.getCorrespondingResource()); // getPrimaryElement() assertEquals("Unexpected orginal element", nonExistingCU, workingCopy.getPrimaryElement()); // getPath() - assertEquals("Unexpected path", new Path("/P/src/x/y/NonExisting.java"), ((IJavaElement)workingCopy).getPath()); + assertEquals("Unexpected path", new Path("/P/src/x/y/NonExisting.java"), workingCopy.getPath()); // getResource() - assertEquals("Unexpected resource", nonExistingCU.getResource(), ((IJavaElement)workingCopy).getResource()); + assertEquals("Unexpected resource", nonExistingCU.getResource(), workingCopy.getResource()); // isConsistent() - assertTrue("Working copy should be consistent", ((IOpenable)workingCopy).isConsistent()); + assertTrue("Working copy should be consistent", workingCopy.isConsistent()); // restore() boolean exception = false; @@ -685,19 +685,19 @@ public void testNonExistingCU() throws JavaModelException { assertTrue("Should not be able to restore from primary element", exception); // makeConsistent() - ((IOpenable)workingCopy).getBuffer().setContents( + workingCopy.getBuffer().setContents( "public class X {\n" + "}"); - assertTrue("Working copy should not be consistent", !((IOpenable)workingCopy).isConsistent()); - ((IOpenable)workingCopy).makeConsistent(null); - assertTrue("Working copy should be consistent", ((IOpenable)workingCopy).isConsistent()); + assertTrue("Working copy should not be consistent", !workingCopy.isConsistent()); + workingCopy.makeConsistent(null); + assertTrue("Working copy should be consistent", workingCopy.isConsistent()); // save() - ((IOpenable)workingCopy).getBuffer().setContents( + workingCopy.getBuffer().setContents( "public class Y {\n" + "}"); - ((IOpenable)workingCopy).save(null, false); - assertTrue("Working copy should be consistent after save", ((IOpenable)workingCopy).isConsistent()); + workingCopy.save(null, false); + assertTrue("Working copy should be consistent after save", workingCopy.isConsistent()); assertTrue("Primary cu should not exist", !nonExistingCU.exists()); // commitWorkingCopy() diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ImportRewriteTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ImportRewriteTest.java index 4c0c0224016..ad5baaca595 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ImportRewriteTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ImportRewriteTest.java @@ -47,7 +47,6 @@ import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; import org.eclipse.text.edits.MalformedTreeException; -import org.eclipse.text.edits.MultiTextEdit; import org.eclipse.text.edits.TextEdit; import org.osgi.service.prefs.BackingStoreException; @@ -1289,7 +1288,7 @@ public void testNoEdits() throws Exception { TextEdit edit = imports.rewriteImports(null); - assertEquals(0, ((MultiTextEdit) edit).getChildrenSize()); + assertEquals(0, edit.getChildrenSize()); } public void testAddImportWithCommentBetweenImportsAndType() throws Exception { diff --git a/org.eclipse.jdt.core.tests.performance/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.performance/META-INF/MANIFEST.MF index aba5fb51352..d981e382d0a 100644 --- a/org.eclipse.jdt.core.tests.performance/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.core.tests.performance/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.jdt.core.tests.performance -Bundle-Version: 3.12.450.qualifier +Bundle-Version: 3.12.500.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: org.eclipse.jdt.core.tests.performance, diff --git a/org.eclipse.jdt.core.tests.performance/pom.xml b/org.eclipse.jdt.core.tests.performance/pom.xml index 47cd4b866f4..b7d3fb23b47 100644 --- a/org.eclipse.jdt.core.tests.performance/pom.xml +++ b/org.eclipse.jdt.core.tests.performance/pom.xml @@ -19,7 +19,7 @@ ../tests-pom/ org.eclipse.jdt.core.tests.performance - 3.12.450-SNAPSHOT + 3.12.500-SNAPSHOT eclipse-test-plugin ${project.artifactId} diff --git a/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceModelTests.java b/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceModelTests.java index 64ba34aa999..93f7d57162b 100644 --- a/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceModelTests.java +++ b/org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceModelTests.java @@ -16,7 +16,6 @@ *******************************************************************************/ package org.eclipse.jdt.core.tests.performance; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.PrintStream; @@ -203,7 +202,7 @@ private void setUpBigProject() throws CoreException, IOException { " }\n" + "}\n" + "class TestSecondary {}\n"; - file.create(new ByteArrayInputStream(content.getBytes()), true, null); + file.create(content.getBytes(), true, false, null); } WORKING_COPY = (ICompilationUnit)JavaCore.create(file); System.out.println("("+(System.currentTimeMillis()-start)+"ms)"); diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java index 21656c23c4e..721fdb3f253 100644 --- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java +++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java @@ -4523,7 +4523,7 @@ else if (scope instanceof ClassScope) } addExpectedType(expected, scope); } else { - TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables(); + TypeVariableBinding[] typeVariables = ref.resolvedType.typeVariables(); int length = ref.typeArguments == null ? 0 : ref.typeArguments.length; if(typeVariables != null && typeVariables.length >= length) { int index = length - 1; @@ -4551,7 +4551,7 @@ else if (scope instanceof ClassScope) } addExpectedType(expected, scope); } else { - TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables(); + TypeVariableBinding[] typeVariables = ref.resolvedType.typeVariables(); if(typeVariables != null) { int iLength = arguments == null ? 0 : arguments.length; done: for (int i = 0; i < iLength; i++) { @@ -13858,7 +13858,7 @@ private boolean isValidParent(ASTNode parent, ASTNode node, Scope scope){ if(parent instanceof ParameterizedSingleTypeReference) { ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent; - TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables(); + TypeVariableBinding[] typeVariables = ref.resolvedType.typeVariables(); int length = ref.typeArguments == null ? 0 : ref.typeArguments.length; int nodeIndex = -1; for(int i = length - 1 ; i > -1 ; i--) { @@ -13882,7 +13882,7 @@ private boolean isValidParent(ASTNode parent, ASTNode node, Scope scope){ } } else if(parent instanceof ParameterizedQualifiedTypeReference) { ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent; - TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables(); + TypeVariableBinding[] typeVariables = ref.resolvedType.typeVariables(); TypeReference[][] arguments = ref.typeArguments; int iLength = arguments == null ? 0 : arguments.length; for (int i = 0; i < iLength; i++) { diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java index 4b22c26a4f6..2d8b1b12044 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DocCommentParser.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2022 IBM Corporation and others. + * Copyright (c) 2004, 2024 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -1290,6 +1290,29 @@ protected void refreshInlineTagPosition(int previousPosition) { } } + @Override + protected void addFragmentToInlineReturn() { + TagElement currTag= (TagElement) this.astStack[this.astPtr]; + List fragments= currTag.fragments(); + int size= fragments.size(); + if (size > 1) { + ASTNode lastNode= (ASTNode) fragments.get(size - 1); + if (lastNode instanceof TagElement lastTag) { + if (!lastTag.getTagName().equals(TagElement.TAG_RETURN)) { + ASTNode secondLastNode= (ASTNode) fragments.get(size - 2); + if (secondLastNode instanceof TagElement prevTag && prevTag.getTagName().equals(TagElement.TAG_RETURN)) { + fragments.remove(size - 1); + prevTag.fragments().add(lastNode); + this.inlineTagStart= prevTag.getStartPosition(); + this.inlineTagStarted= true; + prevTag.setSourceRange(prevTag.getStartPosition(), lastNode.getStartPosition() + lastNode.getLength() - prevTag.getStartPosition()); + } + } else { + this.inlineReturn= false; + } + } + } + } /* * Add stored tag elements to associated comment. */ diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameQualifiedType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameQualifiedType.java index a37aaf1c46c..44274199705 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameQualifiedType.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameQualifiedType.java @@ -172,9 +172,9 @@ final boolean subtreeMatch0(ASTMatcher matcher, Object other) { ASTNode clone0(AST target) { NameQualifiedType result = new NameQualifiedType(target); result.setSourceRange(getStartPosition(), getLength()); - result.setQualifier((Name) ((ASTNode) getQualifier()).clone(target)); + result.setQualifier((Name) getQualifier().clone(target)); result.annotations().addAll(ASTNode.copySubtrees(target, annotations())); - result.setName((SimpleName) ((ASTNode) getName()).clone(target)); + result.setName((SimpleName) getName().clone(target)); return result; } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParameterizedType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParameterizedType.java index 7646aea4565..18c58f75f55 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParameterizedType.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ParameterizedType.java @@ -144,7 +144,7 @@ final int getNodeType0() { ASTNode clone0(AST target) { ParameterizedType result = new ParameterizedType(target); result.setSourceRange(getStartPosition(), getLength()); - result.setType((Type) ((ASTNode) getType()).clone(target)); + result.setType((Type) getType().clone(target)); result.typeArguments().addAll( ASTNode.copySubtrees(target, typeArguments())); return result; diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedType.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedType.java index 4a7085ef59e..2ed73574f09 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedType.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/QualifiedType.java @@ -224,12 +224,12 @@ final int getNodeType0() { ASTNode clone0(AST target) { QualifiedType result = new QualifiedType(target); result.setSourceRange(getStartPosition(), getLength()); - result.setQualifier((Type) ((ASTNode) getQualifier()).clone(target)); + result.setQualifier((Type) getQualifier().clone(target)); if (this.ast.apiLevel >= AST.JLS8_INTERNAL) { result.annotations().addAll( ASTNode.copySubtrees(target, annotations())); } - result.setName((SimpleName) ((ASTNode) getName()).clone(target)); + result.setName((SimpleName) getName().clone(target)); return result; } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclarationStatement.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclarationStatement.java index cbc00b2b673..261f3a4be58 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclarationStatement.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeDeclarationStatement.java @@ -320,9 +320,9 @@ public ITypeBinding resolveBinding() { // forward request to the wrapped type declaration AbstractTypeDeclaration d = getDeclaration(); if (d instanceof TypeDeclaration) { - return ((TypeDeclaration) d).resolveBinding(); + return d.resolveBinding(); } else if (d instanceof AnnotationTypeDeclaration) { - return ((AnnotationTypeDeclaration) d).resolveBinding(); + return d.resolveBinding(); } else { // shouldn't happen return null; diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeParameter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeParameter.java index 28073fbe8dc..9347bd921b5 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeParameter.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/TypeParameter.java @@ -182,7 +182,7 @@ ASTNode clone0(AST target) { result.modifiers().addAll( ASTNode.copySubtrees(target, modifiers())); } - result.setName((SimpleName) ((ASTNode) getName()).clone(target)); + result.setName((SimpleName) getName().clone(target)); result.typeBounds().addAll( ASTNode.copySubtrees(target, typeBounds())); return result; diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java index a74091738b7..dd693dedcc6 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java @@ -3326,10 +3326,28 @@ public final class JavaCore extends Plugin { * @category OptionValue */ public static final String VERSION_CLDC_1_1 = "cldc1.1"; //$NON-NLS-1$ - private static List allVersions = Collections.unmodifiableList(Arrays.asList(VERSION_CLDC_1_1, VERSION_1_1, VERSION_1_2, VERSION_1_3, VERSION_1_4, VERSION_1_5, + private static final List allVersions = Collections.unmodifiableList(Arrays.asList(VERSION_CLDC_1_1, VERSION_1_1, VERSION_1_2, VERSION_1_3, VERSION_1_4, VERSION_1_5, VERSION_1_6, VERSION_1_7, VERSION_1_8, VERSION_9, VERSION_10, VERSION_11, VERSION_12, VERSION_13, VERSION_14, VERSION_15, VERSION_16, VERSION_17, VERSION_18, VERSION_19, VERSION_20, VERSION_21, VERSION_22, VERSION_23)); + /** + * Unordered set of all Java source versions not supported by compiler anymore. + * The values are from {@link JavaCore}{@code #VERSION_*}. + */ + private static final Set UNSUPPORTED_VERSIONS = CompilerOptions.UNSUPPORTED_VERSIONS; + + /** + * Ordered set (from oldest to latest) of all Java source versions supported by compiler. + * The values are from {@link JavaCore}{@code #VERSION_*}. + */ + private static final List SUPPORTED_VERSIONS; + static { + ArrayList temp = new ArrayList<>(); + temp.addAll(allVersions); + temp.removeAll(UNSUPPORTED_VERSIONS); + SUPPORTED_VERSIONS = Collections.unmodifiableList(temp); + } + /** * Returns all {@link JavaCore}{@code #VERSION_*} levels in the order of their * introduction. For e.g., {@link JavaCore#VERSION_1_8} appears before {@link JavaCore#VERSION_10} @@ -3341,6 +3359,22 @@ public static List getAllVersions() { return allVersions; } + /** + * Returns all Java source versions fully supported by Eclipse compiler in the order of their introduction. For + * example, {@link JavaCore#VERSION_1_8} appears before {@link JavaCore#VERSION_10}. + *

+ * Note, some not included older or newer Java versions might be known by Eclipse compiler internally but not + * exposed via this API because compiler does not support these anymore (or yet). + * + * @return all Java source versions fully supported by Eclipse compiler + * @see #isJavaSourceVersionSupportedByCompiler(String) + * @see #getFirstJavaSourceVersionSupportedByCompiler() + * @since 3.39 + */ + public static List getAllJavaSourceVersionsSupportedByCompiler() { + return SUPPORTED_VERSIONS; + } + /** * Returns whether the given version of Java or Java Runtime is supported * by the Java Development Toolkit. @@ -3356,6 +3390,22 @@ public static boolean isSupportedJavaVersion(String version) { return CompilerOptions.versionToJdkLevel(version, false) > 0; } + /** + * Not all known Java versions are supported by Eclipse compiler. This method answers if the given Java source + * version is fully supported. + * + * @return {@code true} if the given string represents Java language version is fully supported by Eclipse compiler + * @see #getAllJavaSourceVersionsSupportedByCompiler() + * @see #getFirstJavaSourceVersionSupportedByCompiler() + * @since 3.39 + */ + public static boolean isJavaSourceVersionSupportedByCompiler(String version) { + if(version == null || version.isBlank()) { + return false; + } + return SUPPORTED_VERSIONS.contains(version); + } + /** * Configurable option value: {@value}. * @since 2.0 @@ -6457,6 +6507,20 @@ public static void setOptions(Hashtable newOptions) { public static String latestSupportedJavaVersion() { return allVersions.get(allVersions.size() - 1); } + + /** + * First (oldest) Java source version supported by the Eclipse compiler. + * This is the first entry from {@link JavaCore#getAllJavaSourceVersionsSupportedByCompiler()}. + * + * @return first (oldest) Java source version supported by the Eclipse compiler + * @see #getAllJavaSourceVersionsSupportedByCompiler() + * @see #isJavaSourceVersionSupportedByCompiler(String) + * @since 3.39 + */ + public static String getFirstJavaSourceVersionSupportedByCompiler() { + return SUPPORTED_VERSIONS.get(0); + } + /** * Compares two given versions of the Java platform. The versions being compared must both be * one of the supported values mentioned in diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ExternalAnnotationUtil.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ExternalAnnotationUtil.java index 21a5832d179..23cf86dc419 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ExternalAnnotationUtil.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/util/ExternalAnnotationUtil.java @@ -14,7 +14,6 @@ package org.eclipse.jdt.core.util; import java.io.BufferedReader; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; @@ -716,13 +715,13 @@ private static void writeFile(IFile annotationFile, StringBuilder head, String a String line; while ((line = tailReader.readLine()) != null) head.append(line).append('\n'); - ByteArrayInputStream newContent = new ByteArrayInputStream(head.toString().getBytes(StandardCharsets.UTF_8)); + byte[] newContent = head.toString().getBytes(StandardCharsets.UTF_8); annotationFile.setContents(newContent, IResource.KEEP_HISTORY, monitor); } private static void createNewFile(IFile file, String newContent, IProgressMonitor monitor) throws CoreException { ensureExists(file.getParent(), monitor); - file.create(new ByteArrayInputStream(newContent.getBytes(StandardCharsets.UTF_8)), false, monitor); + file.create(newContent.getBytes(StandardCharsets.UTF_8), false, false, monitor); } private static void ensureExists(IContainer container, IProgressMonitor monitor) throws CoreException { diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Buffer.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Buffer.java index bd86be5da17..d8a880e1038 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Buffer.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Buffer.java @@ -14,7 +14,6 @@ *******************************************************************************/ package org.eclipse.jdt.internal.core; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.Arrays; @@ -418,15 +417,7 @@ public void save(IProgressMonitor progress, boolean force) throws JavaModelExcep } // Set file contents - ByteArrayInputStream stream = new ByteArrayInputStream(bytes); - if (this.file.exists()) { - this.file.setContents( - stream, - force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY, - null); - } else { - this.file.create(stream, force, null); - } + this.file.write(bytes, force, false, true, null); } catch (IOException e) { throw new JavaModelException(e, IJavaModelStatusConstants.IO_EXCEPTION); } catch (CoreException e) { diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CommitWorkingCopyOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CommitWorkingCopyOperation.java index 45ac17449fa..05f244c7379 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CommitWorkingCopyOperation.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CommitWorkingCopyOperation.java @@ -13,7 +13,6 @@ *******************************************************************************/ package org.eclipse.jdt.internal.core; -import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingException; import org.eclipse.core.resources.IFile; @@ -142,18 +141,7 @@ protected void executeOperation() throws JavaModelException { byte[] bytes = encoding == null ? contents.getBytes() : contents.getBytes(encoding); - ByteArrayInputStream stream = new ByteArrayInputStream(bytes); - if (resource.exists()) { - resource.setContents( - stream, - this.force ? IResource.FORCE | IResource.KEEP_HISTORY : IResource.KEEP_HISTORY, - null); - } else { - resource.create( - stream, - this.force, - this.progressMonitor); - } + resource.write(bytes, this.force, false, true, this.progressMonitor); } catch (CoreException e) { throw new JavaModelException(e); } catch (UnsupportedEncodingException e) { diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java index 0a85ca4807e..d9a4d44868e 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java @@ -159,7 +159,7 @@ protected boolean buildStructure(OpenableElementInfo info, final IProgressMonito } // underlying resource is null in the case of a working copy on a class file in a jar if (underlyingResource != null) - unitInfo.timestamp = ((IFile)underlyingResource).getModificationStamp(); + unitInfo.timestamp = underlyingResource.getModificationStamp(); // compute other problems if needed CompilationUnitDeclaration compilationUnitDeclaration = null; @@ -1377,7 +1377,7 @@ protected void toStringInfo(int tab, StringBuilder buffer, Object info, boolean */ protected void updateTimeStamp(CompilationUnit original) throws JavaModelException { long timeStamp = - ((IFile) original.getResource()).getModificationStamp(); + original.getResource().getModificationStamp(); if (timeStamp == IResource.NULL_STAMP) { throw new JavaModelException( new JavaModelStatus(IJavaModelStatusConstants.INVALID_RESOURCE)); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateCompilationUnitOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateCompilationUnitOperation.java index b4a7472bc5a..03cfdbca422 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateCompilationUnitOperation.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CreateCompilationUnitOperation.java @@ -13,9 +13,7 @@ *******************************************************************************/ package org.eclipse.jdt.internal.core; -import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.InputStream; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.CoreException; @@ -118,8 +116,8 @@ protected void executeOperation() throws JavaModelException { catch (CoreException ce) { // use no encoding } - InputStream stream = new ByteArrayInputStream(encoding == null ? this.source.getBytes() : this.source.getBytes(encoding)); - createFile(folder, unit.getElementName(), stream, this.force); + byte[] content = encoding == null ? this.source.getBytes() : this.source.getBytes(encoding); + createFile(folder, unit.getElementName(), content, this.force); this.resultElements = new IJavaElement[] {unit}; if (!Util.isExcluded(unit) && unit.getParent().exists()) { diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java index b53e0148293..53ef8be49ed 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java @@ -1903,7 +1903,7 @@ private void popUntilPrefixOf(IPath path) { while (this.currentElement != null) { IPath currentElementPath = null; if (this.currentElement instanceof IPackageFragmentRoot) { - currentElementPath = ((IPackageFragmentRoot)this.currentElement).getPath(); + currentElementPath = this.currentElement.getPath(); } else { IResource currentElementResource = this.currentElement.resource(); if (currentElementResource != null) { diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java index 0d8bd6fa4e5..4dfa2f4942f 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElement.java @@ -431,7 +431,7 @@ protected IJavaElement getSourceElementAt(int position) throws JavaModelExceptio SourceRefElement candidate = null; do { // check name range - range = ((IField)child).getNameRange(); + range = child.getNameRange(); if (position <= range.getOffset() + range.getLength()) { candidate = child; } else { diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java index 82b0eb82d26..32f6f9f5019 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModel.java @@ -18,7 +18,6 @@ import java.util.ArrayList; import java.util.Map; -import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -201,9 +200,8 @@ public JavaModel getJavaModel() { public IJavaProject getJavaProject(IResource resource) { switch(resource.getType()){ case IResource.FOLDER: - return new JavaProject(((IFolder)resource).getProject(), this); case IResource.FILE: - return new JavaProject(((IFile)resource).getProject(), this); + return new JavaProject(resource.getProject(), this); case IResource.PROJECT: return new JavaProject((IProject)resource, this); default: diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java index 02845a52b4a..dfdcdb71af6 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java @@ -1666,7 +1666,7 @@ public boolean isActive() { public String toString() { StringBuilder buffer = new StringBuilder(); buffer.append("Info for "); //$NON-NLS-1$ - buffer.append(((JavaElement)this.workingCopy).toStringWithAncestors()); + buffer.append(this.workingCopy.toStringWithAncestors()); buffer.append("\nUse count = "); //$NON-NLS-1$ buffer.append(this.useCount); buffer.append("\nProblem requestor:\n "); //$NON-NLS-1$ diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java index 1979ce86f89..149a9b465fd 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelOperation.java @@ -15,7 +15,6 @@ import static org.eclipse.jdt.internal.core.JavaModelManager.trace; -import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -275,7 +274,7 @@ protected void copyResources(IResource[] resources, IPath container) throws Java /** * Convenience method to create a file */ - protected void createFile(IContainer folder, String name, InputStream contents, boolean forceFlag) throws JavaModelException { + protected void createFile(IContainer folder, String name, byte[] contents, boolean forceFlag) throws JavaModelException { IFile file= folder.getFile(new Path(name)); try { file.create( diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java index 8c344b0ec43..3ac1de85994 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java @@ -710,7 +710,7 @@ public void computePackageFragmentRoots( String rootID = ((ClasspathEntry)resolvedEntry).rootID(); if (rootIDs.contains(rootID)) return; - if(excludeTestCode && ((ClasspathEntry)resolvedEntry).isTest()) { + if(excludeTestCode && resolvedEntry.isTest()) { return; } @@ -3552,26 +3552,19 @@ public void setRawClasspath( * @see JavaProject#getSharedProperty(String key) */ public void setSharedProperty(String key, String value) throws CoreException { - IFile rscFile = this.project.getFile(key); - byte[] bytes = null; - try { - bytes = value.getBytes(org.eclipse.jdt.internal.compiler.util.Util.UTF_8); // .classpath always encoded with UTF-8 - } catch (UnsupportedEncodingException e) { - Util.log(e, "Could not write .classpath with UTF-8 encoding "); //$NON-NLS-1$ - // fallback to default - bytes = value.getBytes(); - } - InputStream inputStream = new ByteArrayInputStream(bytes); + byte[] bytes = value.getBytes(StandardCharsets.UTF_8); // .classpath always encoded with UTF-8 // update the resource content - if (rscFile.exists()) { - if (rscFile.isReadOnly()) { + try { + rscFile.write(bytes, true, false, false, null); + } catch (CoreException e) { + if (rscFile.exists() && rscFile.isReadOnly()) { // provide opportunity to checkout read-only .classpath file (23984) - ResourcesPlugin.getWorkspace().validateEdit(new IFile[]{rscFile}, IWorkspace.VALIDATE_PROMPT); + ResourcesPlugin.getWorkspace().validateEdit(new IFile[] { rscFile }, IWorkspace.VALIDATE_PROMPT); + rscFile.write(bytes, true, false, false, null); + } else { + throw e; } - rscFile.setContents(inputStream, IResource.FORCE, null); - } else { - rscFile.create(inputStream, IResource.FORCE, null); } } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModularClassFile.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModularClassFile.java index 4b8a07d599c..ea255ebd238 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModularClassFile.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ModularClassFile.java @@ -63,7 +63,7 @@ protected boolean buildStructure(OpenableElementInfo info, IProgressMonitor pm, BinaryModule module = new BinaryModule(this, moduleInfo); newElements.put(module, moduleInfo); info.setChildren(new IJavaElement[] {module}); - ((ClassFileInfo) info).setModule(module); + info.setModule(module); ((PackageFragmentRootInfo) getPackageFragmentRoot().getElementInfo()).setModule(module); return true; } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java index 5749425a292..3a891d3eaf5 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java @@ -438,7 +438,7 @@ public char[][] fullInclusionPatternChars() { public String getElementName() { IResource res = resource(); if (res instanceof IFolder) - return ((IFolder) res).getName(); + return res.getName(); return ""; //$NON-NLS-1$ } /** diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java index aca70d7c5f0..0ebe3b538e8 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java @@ -981,7 +981,7 @@ protected IType resolveTypeByLocation(char[] packageName, char[] typeName, int a IType type= null; // TODO (david) post 3.0 should remove isOpen check, and investigate reusing ICompilationUnit#getElementAt. may need to optimize #getElementAt to remove recursions - if (this.openable instanceof CompilationUnit && ((CompilationUnit)this.openable).isOpen()) { + if (this.openable instanceof CompilationUnit && this.openable.isOpen()) { CompilationUnit wc = (CompilationUnit) this.openable; try { if(((packageName == null || packageName.length == 0) && wc.getPackageDeclarations().length == 0) || diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java index 0f739005059..4ca89596caf 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java @@ -1005,25 +1005,9 @@ protected char[] writeClassFile(ClassFile classFile, SourceFile compilationUnit, } protected void writeClassFileContents(ClassFile classFile, IFile file, String qualifiedFileName, boolean isTopLevelType, SourceFile compilationUnit) throws CoreException { -// InputStream input = new SequenceInputStream( -// new ByteArrayInputStream(classFile.header, 0, classFile.headerOffset), -// new ByteArrayInputStream(classFile.contents, 0, classFile.contentsOffset)); - InputStream input = new ByteArrayInputStream(classFile.getBytes()); - if (file.exists()) { - // Deal with shared output folders... last one wins... no collision cases detected - if (JavaBuilder.DEBUG) { - trace("Writing changed class file " + file.getName());//$NON-NLS-1$ - } - if (!file.isDerived()) { - file.setDerived(true, null); - } - file.setContents(input, true, false, null); - } else { - // Default implementation just writes out the bytes for the new class file... - if (JavaBuilder.DEBUG) { - trace("Writing new class file " + file.getName());//$NON-NLS-1$ - } - file.create(input, IResource.FORCE | IResource.DERIVED, null); + if (JavaBuilder.DEBUG) { + trace("Writing changed class file " + file.getName());//$NON-NLS-1$ } + file.write(classFile.getBytes(), true, true, false, null); } } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java index 36e4be775a3..d48ceaff3be 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/IncrementalImageBuilder.java @@ -29,7 +29,6 @@ import org.eclipse.jdt.internal.core.util.Messages; import org.eclipse.jdt.internal.core.util.Util; -import java.io.*; import java.net.URI; import java.util.*; import java.util.Map.Entry; @@ -877,12 +876,12 @@ protected void writeClassFileContents(ClassFile classfile, IFile file, String qu // If structural changes occurred then add dependent source files byte[] bytes = classfile.getBytes(); if (file.exists()) { - if (writeClassFileCheck(file, qualifiedFileName, bytes) || compilationUnit.updateClassFile) { // see 46093 + if (classFileChanged(file, qualifiedFileName, bytes) || compilationUnit.updateClassFile) { // see 46093 if (JavaBuilder.DEBUG) System.out.println("Writing changed class file " + file.getName());//$NON-NLS-1$ if (!file.isDerived()) file.setDerived(true, null); - file.setContents(new ByteArrayInputStream(bytes), true, false, null); + file.setContents(bytes, true, false, null); } else if (JavaBuilder.DEBUG) { System.out.println("Skipped over unchanged class file " + file.getName());//$NON-NLS-1$ } @@ -892,7 +891,7 @@ protected void writeClassFileContents(ClassFile classfile, IFile file, String qu if (JavaBuilder.DEBUG) System.out.println("Writing new class file " + file.getName());//$NON-NLS-1$ try { - file.create(new ByteArrayInputStream(bytes), IResource.FORCE | IResource.DERIVED, null); + file.create(bytes, IResource.FORCE | IResource.DERIVED, null); } catch (CoreException e) { if (e.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) { IStatus status = e.getStatus(); @@ -917,7 +916,7 @@ protected void writeClassFileContents(ClassFile classfile, IFile file, String qu collision.delete(true, false, null); boolean success = false; try { - file.create(new ByteArrayInputStream(bytes), IResource.FORCE | IResource.DERIVED, null); + file.create(bytes, IResource.FORCE | IResource.DERIVED, null); success = true; } catch (CoreException ignored) { // ignore the second exception @@ -933,13 +932,11 @@ protected void writeClassFileContents(ClassFile classfile, IFile file, String qu } } -protected boolean writeClassFileCheck(IFile file, String fileName, byte[] newBytes) throws CoreException { +protected boolean classFileChanged(IFile file, String fileName, byte[] newBytes) throws CoreException { try { byte[] oldBytes = Util.getResourceContentsAsByteArray(file); - notEqual : if (newBytes.length == oldBytes.length) { - for (int i = newBytes.length; --i >= 0;) - if (newBytes[i] != oldBytes[i]) break notEqual; - return false; // bytes are identical so skip them + if (Arrays.equals(oldBytes, newBytes)) { + return false; } URI location = file.getLocationURI(); if (location == null) return false; // unable to determine location of this class file diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DOMFinder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DOMFinder.java index 250860f4e0b..c0ef0f1b18f 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DOMFinder.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/DOMFinder.java @@ -79,7 +79,7 @@ public ASTNode search() throws JavaModelException { ISourceRange range = null; if (this.element instanceof IMember && !(this.element instanceof IInitializer) && !(this.element instanceof LambdaMethod) && !(this.element instanceof org.eclipse.jdt.internal.core.LambdaExpression)) - range = ((IMember) this.element).getNameRange(); + range = this.element.getNameRange(); else if (this.element instanceof ITypeParameter || this.element instanceof ILocalVariable) range = this.element.getNameRange(); else diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java index c4304e6bab0..44b66c504a5 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java @@ -1954,7 +1954,7 @@ private String[] bootstrapArgumentsDescription(IBootstrapMethodsEntry entry, ICo } break; case IConstantPoolConstant.CONSTANT_MethodType: - arguments[i] = new String(((ConstantPoolEntry2) constantPoolEntry).getMethodDescriptor()); + arguments[i] = new String(constantPoolEntry.getMethodDescriptor()); break; case IConstantPoolConstant.CONSTANT_Class: arguments[i] = new String(constantPoolEntry.getClassInfoName()); diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java index 299d1e0a168..c32c62f8694 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/JavaSearchScope.java @@ -597,7 +597,7 @@ public void processDelta(IJavaElementDelta delta, int eventType) { path = ((IJavaProject)element).getProject().getFullPath().toString(); break; case IJavaElement.PACKAGE_FRAGMENT_ROOT: - path = ((IPackageFragmentRoot)element).getPath().toString(); + path = element.getPath().toString(); break; default: return;