diff options
author | Manoj Palat | 2018-01-30 04:09:05 +0000 |
---|---|---|
committer | Manoj Palat | 2018-01-30 04:09:05 +0000 |
commit | 6e48e7452f9d3fd547df120347e72a0e2b28b562 (patch) | |
tree | d192990dc6cae2d1066318bfbb712c193a2b69f1 | |
parent | 21dead5c2ccc76f477296be263e2847665e76e45 (diff) | |
download | eclipse.jdt.core-6e48e7452f9d3fd547df120347e72a0e2b28b562.tar.gz eclipse.jdt.core-6e48e7452f9d3fd547df120347e72a0e2b28b562.tar.xz eclipse.jdt.core-6e48e7452f9d3fd547df120347e72a0e2b28b562.zip |
Fix for bug 518794 [9] [dom ast] API problems with module bindings -I20180201-0200I20180131-2000I20180130-2000
package binding part comment 13
Change-Id: I2a8a194fc9937fd76a8a6771b39c7315e69d8884
4 files changed, 328 insertions, 4 deletions
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 381ff432e4..846746e995 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016, 2017 IBM Corporation and others. + * Copyright (c) 2016, 2018 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -1046,7 +1046,7 @@ public class ASTConverter9Test extends ConverterTestSetup { assertTrue("Not PackageBinding", binding instanceof IPackageBinding); IPackageBinding packageBinding = (IPackageBinding) binding; IJavaElement element = packageBinding.getJavaElement(); - assertTrue("element null", element != null); + assertTrue("element non null", element == null); } } catch (NullPointerException e) { e.printStackTrace(); @@ -1121,5 +1121,196 @@ public class ASTConverter9Test extends ConverterTestSetup { deleteProject("second"); } } + // + public void testBug518794_001() throws Exception { + try { + + IJavaProject project1 = createJavaProject("ConverterTests9", new String[] {"src"}, new String[] {jcl9lib}, "bin", "9"); + project1.open(null); + addClasspathEntry(project1, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String fileContent = + "module first {\n" + + " requires second;\n" + + " exports pack1 to test;\n" + + " opens pack1 to test;\n" + + " provides pack22.I22 with pack1.X12, pack1.X11;\n" + + "}"; + createFile("/ConverterTests9/src/module-info.java", fileContent); + createFolder("/ConverterTests9/src/pack1"); + createFile("/ConverterTests9/src/pack1/X11.java", + "package pack1;\n" + + "public class X11 implements pack22.I22{}\n"); + createFile("/ConverterTests9/src/pack1/X12.java", + "package pack1;\n" + + "public class X12 implements pack22.I22{}\n"); + + IJavaProject project2 = createJavaProject("second", new String[] {"src"}, new String[] {jcl9lib}, "bin", "9"); + project2.open(null); + addClasspathEntry(project2, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String secondFile = + "module second {\n" + + " exports pack22 to first;\n" + + "}"; + createFile("/second/src/module-info.java", secondFile); + createFolder("/second/src/pack22"); + createFile("/second/src/pack22/I22.java", + "package pack22;\n" + + "public interface I22 {}\n"); + + addClasspathEntry(project1, JavaCore.newProjectEntry(project2.getPath())); + project1.close(); // sync + project2.close(); + project2.open(null); + project1.open(null); + + ICompilationUnit sourceUnit1 = getCompilationUnit("ConverterTests9" , "src", "", "module-info.java"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + ASTNode unit1 = runConversion(AST_INTERNAL_JLS9, sourceUnit1, true); + assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, unit1.getNodeType()); + ModuleDeclaration moduleDecl1 = ((CompilationUnit) unit1).getModule(); + checkSourceRange(moduleDecl1, fileContent, fileContent); + + IModuleBinding moduleBinding = moduleDecl1.resolveBinding(); + assertTrue("Module Binding null", moduleBinding != null); + String name = moduleBinding.getName(); + assertTrue("Module Name null", name != null); + assertTrue("Wrong Module Name", name.equals("first")); + + ITypeBinding[] services = moduleBinding.getServices(); + assertTrue("services null", services != null); + assertTrue("Incorrect number of services", services.length == 1); + for (ITypeBinding s : services) { + assertTrue("Incorrect service", s.getQualifiedName().equals("pack22.I22")); + ITypeBinding[] implementations = moduleBinding.getImplementations(s); + assertTrue("implementations null", implementations != null); + assertTrue("Incorrect number of implementations", implementations.length == 2); + assertTrue("Incorrect implementation", implementations[0].getQualifiedName().equals("pack1.X12")); + assertTrue("Incorrect implementation", implementations[1].getQualifiedName().equals("pack1.X11")); + } + } + finally { + deleteProject("ConverterTests9"); + deleteProject("second"); + } + } + public void testBug518794_002() throws Exception { + try { + + IJavaProject project1 = createJavaProject("ConverterTests9", new String[] {"src"}, new String[] {jcl9lib}, "bin", "9"); + project1.open(null); + addClasspathEntry(project1, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String fileContent = + "module first {\n" + + " requires second;\n" + + " exports pack1 to test;\n" + + " opens pack1 to test;\n" + + " provides pack22.I22 with pack3.Z, pack1.X11;\n" + + "}"; + createFile("/ConverterTests9/src/module-info.java", fileContent); + createFolder("/ConverterTests9/src/pack1"); + createFile("/ConverterTests9/src/pack1/X11.java", + "package pack1;\n" + + "public class X11 implements pack22.I22{}\n"); + createFile("/ConverterTests9/src/pack1/X12.java", + "package pack1;\n" + + "public class X12 implements pack22.I22{}\n"); + createFolder("/ConverterTests9/src/pack3"); + createFile("/ConverterTests9/src/pack3/Z.java", + "package pack3;\n" + + "public class Z implements pack22.I22{}\n"); + + IJavaProject project2 = createJavaProject("second", new String[] {"src"}, new String[] {jcl9lib}, "bin", "9"); + project2.open(null); + addClasspathEntry(project2, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH"))); + String secondFile = + "module second {\n" + + " exports pack22 to first;\n" + + "}"; + createFile("/second/src/module-info.java", secondFile); + createFolder("/second/src/pack22"); + createFile("/second/src/pack22/I22.java", + "package pack22;\n" + + "public interface I22 {}\n"); + + addClasspathEntry(project1, JavaCore.newProjectEntry(project2.getPath())); + project1.close(); // sync + project2.close(); + project2.open(null); + project1.open(null); + + ICompilationUnit sourceUnit1 = getCompilationUnit("ConverterTests9" , "src", "", "module-info.java"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + ASTNode unit1 = runConversion(AST_INTERNAL_JLS9, sourceUnit1, true); + assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, unit1.getNodeType()); + ModuleDeclaration moduleDecl1 = ((CompilationUnit) unit1).getModule(); + checkSourceRange(moduleDecl1, fileContent, fileContent); + + IModuleBinding moduleBinding = moduleDecl1.resolveBinding(); + assertTrue("Module Binding null", moduleBinding != null); + String name = moduleBinding.getName(); + assertTrue("Module Name null", name != null); + assertTrue("Wrong Module Name", name.equals("first")); + + ITypeBinding[] services = moduleBinding.getServices(); + assertTrue("services null", services != null); + assertTrue("Incorrect number of services", services.length == 1); + for (ITypeBinding s : services) { + assertTrue("Incorrect service", s.getQualifiedName().equals("pack22.I22")); + ITypeBinding[] implementations = moduleBinding.getImplementations(s); + assertTrue("implementations null", implementations != null); + assertTrue("Incorrect number of implementations", implementations.length == 2); + assertTrue("Incorrect implementation", implementations[0].getQualifiedName().equals("pack3.Z")); + assertTrue("Incorrect implementation", implementations[1].getQualifiedName().equals("pack1.X11")); + } + } + finally { + deleteProject("ConverterTests9"); + deleteProject("second"); + } + } + public void testBug518794_003() throws Exception { + try { + + IJavaProject project1 = createJavaProject("ConverterTests9", new String[] {"src"}, new String[] {jcl9lib}, "bin", "9"); + project1.open(null); + String fileContent = + "module first {\n" + + "}"; + createFile("/ConverterTests9/src/module-info.java", fileContent); + createFolder("/ConverterTests9/src/pack"); + createFile("/ConverterTests9/src/pack/X.java", + "package pack;\n" + + "import java.MyObject;\n" + + "public class X{}"); + + project1.close(); // sync + project1.open(null); + + ICompilationUnit sourceUnit1 = getCompilationUnit("ConverterTests9" , "src", "pack", "X.java"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + ASTNode unit1 = runConversion(AST_INTERNAL_JLS9, sourceUnit1, true); + assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, unit1.getNodeType()); + CompilationUnit cu = (CompilationUnit) unit1; + ImportDeclaration importDeclaration = (ImportDeclaration) cu.imports().get(0); + QualifiedName qName = (QualifiedName) importDeclaration.getName(); + Name name = qName.getQualifier(); + IBinding binding = name.resolveBinding(); + if (binding != null) { + assertTrue("Not PackageBinding", binding instanceof IPackageBinding); + IPackageBinding packageBinding = (IPackageBinding) binding; + assertTrue("Not Recovered Package Binding", packageBinding.isRecovered()); + IJavaElement element = packageBinding.getJavaElement(); + assertTrue("element non null", element == null); + IModuleBinding moduleBinding = packageBinding.getModule(); + assertTrue("moduleBinding non null", moduleBinding == null); + String packageName = packageBinding.getName(); + assertTrue("package name incorrect", packageName.equals("java")); + String key = packageBinding.getKey(); + assertTrue("package name incorrect", key.startsWith("Recovered")); + } + } catch (NullPointerException e) { + e.printStackTrace(); + assertFalse("Failed", true); + } finally { + deleteProject("ConverterTests9"); + } + } // Add new tests here } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java index 910521aba8..69539fb2e2 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java @@ -318,14 +318,15 @@ class DefaultBindingResolver extends BindingResolver { @Override synchronized IPackageBinding getPackageBinding(org.eclipse.jdt.internal.compiler.lookup.PackageBinding packageBinding) { - if (packageBinding == null || packageBinding instanceof ProblemPackageBinding) { + if (packageBinding == null) { return null; } IPackageBinding binding = (IPackageBinding) this.bindingTables.compilerBindingsToASTBindings.get(packageBinding); if (binding != null) { return binding; } - binding = new PackageBinding(packageBinding, this); + binding = packageBinding instanceof ProblemPackageBinding ? new RecoveredPackageBinding(packageBinding, this) : + new PackageBinding(packageBinding, this); this.bindingTables.compilerBindingsToASTBindings.put(packageBinding, binding); return binding; } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IBinding.java index 2bead95eb3..9dba25ad89 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IBinding.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/IBinding.java @@ -225,6 +225,7 @@ public interface IBinding { * <li>the constructor of an anonymous class</li> * <li>member value pairs</li> * <li>synthetic bindings</li> + * <li>problem package bindings (since Java 9)</li> * </ul> * For all other kind of type, method, variable, annotation and package bindings, * this method returns non-<code>null</code>. diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredPackageBinding.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredPackageBinding.java new file mode 100644 index 0000000000..2a6b4bc1d5 --- /dev/null +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredPackageBinding.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright (c) 2018 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.dom; + +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.compiler.CharOperation; +import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding; +import org.eclipse.jdt.internal.compiler.lookup.PackageBinding; +import org.eclipse.jdt.internal.compiler.util.Util; + +/** + * This class represents the recovered binding for a package + */ +class RecoveredPackageBinding implements IPackageBinding { + + private static final String[] NO_NAME_COMPONENTS = CharOperation.NO_STRINGS; + private static final String UNNAMED = Util.EMPTY_STRING; + private static final char PACKAGE_NAME_SEPARATOR = '.'; + + private PackageBinding binding; + private BindingResolver resolver; + private String name = null; + private String[] components = null; + + RecoveredPackageBinding(org.eclipse.jdt.internal.compiler.lookup.PackageBinding binding, BindingResolver resolver) { + this.binding = binding; + this.resolver = resolver; + } + + @Override + public IAnnotationBinding[] getAnnotations() { + return AnnotationBinding.NoAnnotations; + } + + @Override + public int getKind() { + return IBinding.PACKAGE; + } + + @Override + public int getModifiers() { + return Modifier.NONE; + } + + @Override + public boolean isDeprecated() { + return false; + } + + @Override + public boolean isRecovered() { + return true; + } + + @Override + public boolean isSynthetic() { + return false; + } + + @Override + public IJavaElement getJavaElement() { + return null; + } + + @Override + public String getKey() { + StringBuffer buffer = new StringBuffer(); + buffer.append("Recovered#"); //$NON-NLS-1$ + buffer.append(this.binding.computeUniqueKey()); + return buffer.toString(); + } + + @Override + public boolean isEqualTo(IBinding other) { + if (!other.isRecovered() || other.getKind() != IBinding.PACKAGE) return false; + return getKey().equals(other.getKey()); + } + + @Override + public String getName() { + if (this.name == null) { + computeNameAndComponents(); + } + return this.name; + } + + @Override + public boolean isUnnamed() { + return false; + } + + @Override + public String[] getNameComponents() { + if (this.components == null) { + computeNameAndComponents(); + } + return this.components; + } + @Override + public IModuleBinding getModule() { + ModuleBinding moduleBinding = this.binding.enclosingModule; + return moduleBinding != null ? this.resolver.getModuleBinding(moduleBinding) : null; + } + private void computeNameAndComponents() { + char[][] compoundName = this.binding.compoundName; + if (compoundName == CharOperation.NO_CHAR_CHAR || compoundName == null) { + this.name = UNNAMED; + this.components = NO_NAME_COMPONENTS; + } else { + int length = compoundName.length; + this.components = new String[length]; + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < length - 1; i++) { + this.components[i] = new String(compoundName[i]); + buffer.append(compoundName[i]).append(PACKAGE_NAME_SEPARATOR); + } + this.components[length - 1] = new String(compoundName[length - 1]); + buffer.append(compoundName[length - 1]); + this.name = buffer.toString(); + } + } + +} |