Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Arthanareeswaran2017-09-18 15:37:49 +0000
committerJay Arthanareeswaran2017-09-18 18:19:28 +0000
commit01d653b8154c601f5850f7a0d488fa3349909127 (patch)
tree26f434f5dee3b12ada67c8632c0b26da33e10715
parentc798229d351d6daa2232cff6c15750336659223e (diff)
downloadeclipse.jdt.core-01d653b8154c601f5850f7a0d488fa3349909127.tar.gz
eclipse.jdt.core-01d653b8154c601f5850f7a0d488fa3349909127.tar.xz
eclipse.jdt.core-01d653b8154c601f5850f7a0d488fa3349909127.zip
Bug 517841: [9] Support Java 9 APT models
Change-Id: I6b61e6ab32b905357b5256cd875eb8337822f3c6 Signed-off-by: Jay Arthanareeswaran <jarthana@in.ibm.com>
-rw-r--r--org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jarbin206825 -> 207081 bytes
-rw-r--r--org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jarbin216111 -> 232966 bytes
-rw-r--r--org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/AnnotationProcessorTests/Bug340635Proc.java10
-rw-r--r--org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/base/XMLConverter.java2
-rw-r--r--org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/inherited/ArgsConstructorProcessor.java17
-rw-r--r--org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java8ElementProcessor.java6
-rw-r--r--org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java9ElementProcessor.java752
-rw-r--r--org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/AllTests.java3
-rw-r--r--org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchTestUtils.java123
-rw-r--r--org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java8ElementsTests.java43
-rw-r--r--org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java9ElementsTests.java444
-rw-r--r--org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/AnnotationDiscoveryVisitor.java20
-rw-r--r--org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchAnnotationProcessorManager.java22
-rw-r--r--org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java11
-rw-r--r--org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementImpl.java8
-rw-r--r--org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementsImpl.java121
-rw-r--r--org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/Factory.java52
-rw-r--r--org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java378
-rw-r--r--org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/NoTypeImpl.java8
-rw-r--r--org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/PackageElementImpl.java22
-rw-r--r--org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypeElementImpl.java5
-rw-r--r--org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/AllTests.java3
-rw-r--r--org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerToolJava9Tests.java2
-rw-r--r--org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java3
-rw-r--r--org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java77
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java9
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ModuleDeclaration.java12
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java6
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java9
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java13
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceModuleBinding.java76
34 files changed, 2120 insertions, 148 deletions
diff --git a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar
index 856d5d047d..69a7439122 100644
--- a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar
+++ b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors.jar
Binary files differ
diff --git a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
index e312f51cb8..4fc9a5e2e9 100644
--- a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
+++ b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
Binary files differ
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/AnnotationProcessorTests/Bug340635Proc.java b/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/AnnotationProcessorTests/Bug340635Proc.java
index ca60bf979f..47ff563fdc 100644
--- a/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/AnnotationProcessorTests/Bug340635Proc.java
+++ b/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/AnnotationProcessorTests/Bug340635Proc.java
@@ -1,10 +1,14 @@
/*******************************************************************************
- * Copyright (c) 2015 IBM Corporation and others.
+ * Copyright (c) 2015, 2017 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
- *
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
* Contributors:
* Kevin Pollet - SERLI - (kevin.pollet@serli.com) - initial API and implementation
*******************************************************************************/
@@ -66,7 +70,7 @@ public class Bug340635Proc extends AbstractProcessor {
private class GenericTypeVisitor extends SimpleTypeVisitor6<DeclaredType, Void> {
private final Types types;
-
+ @Deprecated
public GenericTypeVisitor(Types types) {
this.types = types;
}
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/base/XMLConverter.java b/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/base/XMLConverter.java
index cb5763507e..37df722348 100644
--- a/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/base/XMLConverter.java
+++ b/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/base/XMLConverter.java
@@ -50,7 +50,7 @@ import org.w3c.dom.Node;
public class XMLConverter extends ElementScanner6<Void, Node> implements IXMLNames {
private final Document _doc;
-
+ @Deprecated
private XMLConverter(Document doc) {
_doc = doc;
}
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/inherited/ArgsConstructorProcessor.java b/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/inherited/ArgsConstructorProcessor.java
index e6e8e4692b..b8aa884386 100644
--- a/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/inherited/ArgsConstructorProcessor.java
+++ b/org.eclipse.jdt.compiler.apt.tests/processors/org/eclipse/jdt/compiler/apt/tests/processors/inherited/ArgsConstructorProcessor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011 IBM Corporation and others.
+ * Copyright (c) 2011, 2017 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
@@ -16,14 +16,20 @@ import java.util.Map.Entry;
import java.util.Set;
import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
-import javax.annotation.processing.*;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVisitor;
import javax.lang.model.util.SimpleTypeVisitor6;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic.Kind;
@@ -155,6 +161,7 @@ public class ArgsConstructorProcessor extends BaseProcessor {
}
private final TypeVisitor<Boolean, List<TypeMirror>> argsVisitor = new SimpleTypeVisitor6<Boolean, List<TypeMirror>>() {
+ @Override
public Boolean visitExecutable(ExecutableType t,
List<TypeMirror> annotatedTypes) {
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java8ElementProcessor.java b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java8ElementProcessor.java
index b2040c89b0..078e88f6f5 100644
--- a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java8ElementProcessor.java
+++ b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java8ElementProcessor.java
@@ -169,7 +169,7 @@ public class Java8ElementProcessor extends BaseProcessor {
testRepeatedAnnotations25();
testTypeAnnotations26();
testTypeAnnotations27();
- testPackageAnnotations();
+ //testPackageAnnotations();
testBug520540();
testEnumConstArguments();
}
@@ -986,6 +986,8 @@ public class Java8ElementProcessor extends BaseProcessor {
}
}
+ // Disabled for now. Javac includes the CLASS element of the package-info in the root element if there's one.
+ // But ECJ includes the Package element.
public void testPackageAnnotations() {
if ( roundNo++ == 0) {
this.reportSuccessAlready = false;
@@ -1001,6 +1003,8 @@ public class Java8ElementProcessor extends BaseProcessor {
for (Element element : roundEnv.getRootElements()) {
if (element.getKind() == ElementKind.PACKAGE) {
packageEl = (PackageElement) element;
+ } else {
+ System.out.println(element);
}
}
assertNotNull("Package element should not be null", packageEl);
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java9ElementProcessor.java b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java9ElementProcessor.java
index 6750b61f7f..6f0d9224bf 100644
--- a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java9ElementProcessor.java
+++ b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/Java9ElementProcessor.java
@@ -15,25 +15,625 @@
package org.eclipse.jdt.compiler.apt.tests.processors.elements;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
+import javax.annotation.processing.Messager;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
-import javax.annotation.processing.SupportedSourceVersion;
-import javax.lang.model.SourceVersion;
+import javax.lang.model.AnnotatedConstruct;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.ModuleElement.Directive;
+import javax.lang.model.element.ModuleElement.DirectiveKind;
+import javax.lang.model.element.ModuleElement.ExportsDirective;
+import javax.lang.model.element.ModuleElement.ProvidesDirective;
+import javax.lang.model.element.ModuleElement.RequiresDirective;
+import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.NoType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
-@SupportedAnnotationTypes("*")
-@SupportedSourceVersion(SourceVersion.RELEASE_8) // Not at compliance 9 yet
-public class Java9ElementProcessor extends Java8ElementProcessor {
+import org.eclipse.jdt.compiler.apt.tests.processors.base.BaseProcessor;
- int roundNo = 0;
+/**
+ * A processor that explores the java 9 specific elements and validates the lambda and
+ * type annotated elements. To enable this processor, add
+ * -Aorg.eclipse.jdt.compiler.apt.tests.processors.elements.Java9ElementProcessor to the command line.
+ * @since 3.13 BETA_JAVA9
+ */
+@SupportedAnnotationTypes("*")
+public class Java9ElementProcessor extends BaseProcessor {
boolean reportSuccessAlready = true;
+ RoundEnvironment roundEnv = null;
+ Messager _messager = null;
+ @Override
+ public synchronized void init(ProcessingEnvironment processingEnv) {
+ super.init(processingEnv);
+ _typeUtils = processingEnv.getTypeUtils();
+ _messager = processingEnv.getMessager();
+ }
+ // Always return false from this processor, because it supports "*".
+ // The return value does not signify success or failure!
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ if (roundEnv.processingOver()) {
+ return false;
+ }
+
+ this.roundEnv = roundEnv;
+ Map<String, String> options = processingEnv.getOptions();
+ if (!options.containsKey(this.getClass().getName())) {
+ // Disable this processor unless we are intentionally performing the test.
+ return false;
+ } else {
+ try {
+ if (!invokeTestMethods(options)) {
+ testAll();
+ }
+ if (this.reportSuccessAlready) {
+ super.reportSuccess();
+ }
+ } catch (AssertionFailedError e) {
+ super.reportError(getExceptionStackTrace(e));
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ return false;
+ }
+
+ private boolean invokeTestMethods(Map<String, String> options) throws Throwable {
+ Method testMethod = null;
+ Set<String> keys = options.keySet();
+ boolean testsFound = false;
+ for (String option : keys) {
+ if (option.startsWith("test")) {
+ try {
+ testMethod = this.getClass().getDeclaredMethod(option, new Class[0]);
+ if (testMethod != null) {
+ testsFound = true;
+ testMethod.invoke(this, new Object[0]);
+ }
+ } catch (InvocationTargetException e) {
+ throw e.getCause();
+ } catch (Exception e) {
+ super.reportError(getExceptionStackTrace(e));
+ }
+ }
+ }
+ return testsFound;
+ }
+
+ public void testAll() throws AssertionFailedError {
+ testModuleAnnotation1();
+ testModuleElement1();
+ testModuleElement2();
+ testModuleElement3();
+ testModuleElement4();
+ testModuleElement5();
+ testModuleElement6();
+ testModuleElement7();
+ testModuleJavaBase1();
+ testModuleJavaBase2();
+ testModuleJavaBase3();
+ testModuleJavaBase4();
+ testModuleJavaBase5();
+ testModuleTypeMirror1();
+ testModuleTypeMirror2();
+ testModuleJavaSql1();
+ testSourceModule1();
+ testSourceModule2();
+ testRootElements1();
+ testRootElements2();
+ testUnnamedModule1();
+ testUnnamedModule2();
+ testUnnamedModule3();
+ testUnnamedModule4();
+ testUnnamedModule5();
+ }
+
+ private Element getRoot(Element elem) {
+ Element enclosingElement = elem.getEnclosingElement();
+ while (enclosingElement != null) {
+ if (enclosingElement instanceof ModuleElement) {
+ return enclosingElement;
+ }
+ enclosingElement = enclosingElement.getEnclosingElement();
+ }
+ return enclosingElement;
+ }
+
+ public void testRootElements1() {
+ Set<? extends Element> rootElements = this.roundEnv.getRootElements();
+ int typeCount = 0;
+ int moduleCount = 0;
+ List<String> types = new ArrayList<>();
+ List<String> modules = new ArrayList<>();
+ for (Element element : rootElements) {
+ Element root = getRoot(element);
+ if (element instanceof ModuleElement) {
+ ModuleElement mod = (ModuleElement) element;
+ moduleCount++;
+ modules.add(mod.getQualifiedName().toString());
+ assertNull("module should not have an enclosing element", root);
+ } else {
+ if (element instanceof TypeElement) {
+ typeCount++;
+ types.add(((TypeElement) element).getQualifiedName().toString());
+ }
+ assertTrue("Should be a module element", (root instanceof ModuleElement));
+ assertFalse("should be a named module", ((ModuleElement) root).isUnnamed());
+ }
+ }
+ Collections.sort(types, (x, y) -> x.compareTo(y));
+ Collections.sort(modules, (x, y) -> x.compareTo(y));
+ assertEquals("incorrect no of modules in root elements", 2, moduleCount);
+ assertEquals("incorrect modules among root elements", "[mod.a, mod.b]", modules.toString());
+ assertEquals("incorrect no of types in root elements", 5, typeCount);
+ assertEquals("incorrect types among root elements",
+ "[abc.A, abc.internal.A, abc.internal.TypeInAModule, abc.internal.pqr.A, pqr.ext.B]",
+ types.toString());
+ }
+ // Test the types part of root elements get the modules right
+ public void testRootElements2() {
+ Set<? extends Element> rootElements = this.roundEnv.getRootElements();
+ TypeElement type = null;
+ ModuleElement modFromRoot = null;
+ for (Element element : rootElements) {
+ if (element instanceof TypeElement && ((TypeElement) element).getSimpleName().toString().equals("TypeInAModule")) {
+ type = (TypeElement) element;
+ }
+ if (element instanceof ModuleElement && ((ModuleElement) element).getQualifiedName().toString().equals("mod.a")) {
+ modFromRoot = (ModuleElement) element;
+ }
+ }
+ assertNotNull("type should not be null", type);
+ assertNotNull("module from root elements should not be null", modFromRoot);
+ ModuleElement module = _elementUtils.getModuleOf(type);
+ assertNotNull("type's module should not be null", module);
+ assertEquals("modules should be equals", module, modFromRoot);
+ }
+ /*
+ * Test module element can be retrieved and
+ * annotations on module declarations can be retrieved
+ */
+ public void testModuleAnnotation1() {
+ CharSequence name = "mod.a";
+ ModuleElement mod = _elementUtils.getModuleElement(name);
+ assertNotNull("Module element should not be null", mod);
+ List<? extends AnnotationMirror> annotationMirrors = mod.getAnnotationMirrors();
+ assertNotNull("Should not be null", annotationMirrors);
+ verifyAnnotations(mod, new String[]{"@java.lang.Deprecated()"});
+ List<? extends Element> enclosedElements = mod.getEnclosedElements();
+ PackageElement pack = null;
+ for (Element element : enclosedElements) {
+ if (element instanceof PackageElement) {
+ pack = (PackageElement) element;
+ break;
+ }
+ }
+ assertNotNull("Package not found", pack);
+ Element elem = pack.getEnclosingElement();
+ assertNotNull("Parent not found", elem);
+ assertTrue("Parent should be a module", (elem instanceof ModuleElement));
+ assertEquals("Incorrect module element", "mod.a", ((ModuleElement) elem).getQualifiedName().toString());
+ }
+ /*
+ * Test module element can be retrieved and attributed are
+ * verified against declaration
+ */
+ public void testModuleElement1() {
+ CharSequence name = "mod.a";
+ ModuleElement mod = _elementUtils.getModuleElement(name);
+ assertEquals("incorrect name", "mod.a", mod.getQualifiedName().toString());
+ assertEquals("incorrect name", "mod.a", mod.getQualifiedName().toString());
+ List<? extends Element> enclosedElements = mod.getEnclosedElements();
+ PackageElement pack = null;
+ for (Element element : enclosedElements) {
+ if (element instanceof PackageElement && ((PackageElement) element).getQualifiedName().toString().equals("abc.internal")) {
+ pack = (PackageElement) element;
+ break;
+ }
+ }
+ assertNotNull("Package not found", pack);
+ Element elem = pack.getEnclosingElement();
+ assertNotNull("Parent not found", elem);
+ assertTrue("Parent should be a module", (elem instanceof ModuleElement));
+ assertEquals("Incorrect module element", "mod.a", ((ModuleElement) elem).getQualifiedName().toString());
+ }
+ /*
+ * Test type elements can be retrieved from Elements API with and without
+ * the context of the module the type is in.
+ */
+ public void testModuleElement2() {
+ CharSequence name = "mod.a";
+ ModuleElement mod = _elementUtils.getModuleElement(name);
+ TypeElement typeElement = _elementUtils.getTypeElement(mod, "abc.internal.TypeInAModule");
+ assertNotNull("Type should not be null", typeElement);
+ typeElement = _elementUtils.getTypeElement("abc.internal.TypeInAModule");
+ assertNotNull("Type should not be null", typeElement);
+ ModuleElement m = _elementUtils.getModuleOf(typeElement);
+ assertEquals("modules should be same", mod, m);
+ ModuleElement mElement = _elementUtils.getModuleOf(typeElement);
+ assertNotNull("module should not be null", mElement);
+ assertEquals("Incorrect module element", "mod.a", mElement.getQualifiedName().toString());
+ }
+ /*
+ * Test binary modules from JRT system can be loaded and its attributes
+ * as expected
+ */
+ public void testModuleElement3() {
+ Set<? extends ModuleElement> allModuleElements = _elementUtils.getAllModuleElements();
+ ModuleElement base = null;
+ ModuleElement compiler = null;
+ for (ModuleElement moduleElement : allModuleElements) {
+ if (moduleElement.getQualifiedName().toString().equals("java.base")) {
+ base = moduleElement;
+ }
+ if (moduleElement.getQualifiedName().toString().equals("java.compiler")) {
+ compiler = moduleElement;
+ }
+ }
+ assertNotNull("java.base module null", base);
+ assertNotNull("java.compiler module null", compiler);
+ assertNull("Enclosing element should be null", base.getEnclosingElement());
+ assertEquals("Incorrect element kind", ElementKind.MODULE, base.getKind());
+ assertFalse("Should be named", base.isUnnamed());
+ assertFalse("Should not be open", base.isOpen());
+
+ }
+ /*
+ * Test packages can be retrieved with the Elements API with and without
+ * the context of its module.
+ */
+ public void testModuleElement4() {
+ CharSequence name = "mod.a";
+ ModuleElement mod = _elementUtils.getModuleElement(name);
+ PackageElement pElement = _elementUtils.getPackageElement("abc.internal");
+ assertNotNull("Package should not be null", pElement);
+ pElement = _elementUtils.getPackageElement(mod, "abc.internal");
+ assertNotNull("Package should not be null", pElement);
+ ModuleElement mElement = _elementUtils.getModuleOf(pElement);
+ assertNotNull("module should not be null", mElement);
+ assertEquals("Incorrect module element", "mod.a", mElement.getQualifiedName().toString());
+ assertEquals("Modules should be same", mod, mElement);
+ }
+ /*
+ * Test packages can be retrieved with Elements API and they contain
+ * the right module element.
+ */
+ public void testModuleElement5() {
+ CharSequence name = "mod.a";
+ ModuleElement mod = _elementUtils.getModuleElement(name);
+ Set<? extends PackageElement> allPackageElements = _elementUtils.getAllPackageElements("abc.internal.pqr");
+ assertEquals("Incorrect no of packages", 1, allPackageElements.size());
+ PackageElement pElement = null;
+ for (PackageElement packageElement : allPackageElements) {
+ pElement = packageElement;
+ }
+ assertNotNull("Package should not be null", pElement);
+ ModuleElement mElement = _elementUtils.getModuleOf(pElement);
+ assertNotNull("module should not be null", mElement);
+ assertEquals("Incorrect module element", "mod.a", mElement.getQualifiedName().toString());
+ assertEquals("Modules should be same", mod, mElement);
+ allPackageElements = _elementUtils.getAllPackageElements("abc");
+ assertEquals("Incorrect no of packages", 2, allPackageElements.size());
+ List<ModuleElement> mods = new ArrayList<>();
+ for (PackageElement packageElement : allPackageElements) {
+ mElement = _elementUtils.getModuleOf(packageElement);
+ mods.add(mElement);
+ }
+ assertEquals("incorrect no of modules", 2, mods.size());
+ mods.remove(mod);
+ mod = _elementUtils.getModuleElement("mod.b");
+ assertNotNull("mod b should not be null", mod);
+ mods.remove(mod);
+ assertEquals("incorrect no of modules", 0, mods.size());
+ }
+ /*
+ * Test type elements can be loaded and contain the correct module
+ * elements
+ */
+ public void testModuleElement6() {
+ CharSequence name = "mod.a";
+ ModuleElement mod = _elementUtils.getModuleElement(name);
+ Set<? extends TypeElement> typeElements = _elementUtils.getAllTypeElements("abc.internal.A");
+ assertNotNull("Type should not be null", typeElements);
+ assertEquals("Incorrect no of types", 1, typeElements.size());
+ TypeElement tElement = null;
+ for (TypeElement typeElement : typeElements) {
+ tElement = typeElement;
+ }
+ assertNotNull("Package should not be null", tElement);
+ ModuleElement mElement = _elementUtils.getModuleOf(tElement);
+ assertNotNull("module should not be null", mElement);
+ assertEquals("Incorrect module element", "mod.a", mElement.getQualifiedName().toString());
+ assertEquals("Modules should be same", mod, mElement);
+ }
+ /*
+ * Test that a module not part of the root modules can NOT be retrieved.
+ */
+ public void testModuleElement7() {
+ // test that a random module from system unrelated to the module we are compiling is not loaded by the compiler
+ Set<? extends ModuleElement> allModuleElements = _elementUtils.getAllModuleElements();
+ ModuleElement mod = null;
+ for (ModuleElement moduleElement : allModuleElements) {
+ if (moduleElement.getQualifiedName().toString().equals("java.desktop")) {
+ mod = moduleElement;
+ }
+ }
+ assertNull("module java.desktop should not be found", mod);
+ }
+ /*
+ * Test java.base module can be loaded and verify its exports attributes
+ */
+ public void testModuleJavaBase1() {
+ Set<? extends ModuleElement> allModuleElements = _elementUtils.getAllModuleElements();
+ ModuleElement base = null;
+ for (ModuleElement moduleElement : allModuleElements) {
+ if (moduleElement.getQualifiedName().toString().equals("java.base")) {
+ base = moduleElement;
+ }
+ }
+ assertNotNull("java.base module null", base);
+ List<? extends Directive> directives = base.getDirectives();
+ List<Directive> filterDirective = filterDirective(directives, DirectiveKind.EXPORTS);
+ assertEquals("incorrect no of exports", 108 , filterDirective.size());
+ ExportsDirective pack = null;
+ for (Directive directive : filterDirective) {
+ ModuleElement.ExportsDirective exports = (ExportsDirective) directive;
+ if (exports.getPackage().getQualifiedName().toString().equals("sun.reflect.annotation")) {
+ pack = exports;
+ break;
+ }
+ }
+ assertNotNull("Package export not found", pack);
+ List<? extends ModuleElement> targetModules = pack.getTargetModules();
+ assertEquals("incorrect no of targets", 1, targetModules.size());
+ ModuleElement mod = targetModules.get(0);
+ assertEquals("incorrect module element", "jdk.compiler", mod.getQualifiedName().toString());
+ }
+ /*
+ * Test java.base module can be loaded and verify its requires attributes
+ */
+ public void testModuleJavaBase2() {
+ Set<? extends ModuleElement> allModuleElements = _elementUtils.getAllModuleElements();
+ ModuleElement base = null;
+ for (ModuleElement moduleElement : allModuleElements) {
+ if (moduleElement.getQualifiedName().toString().equals("java.base")) {
+ base = moduleElement;
+ }
+ }
+ assertNotNull("java.base module null", base);
+ List<? extends Directive> directives = base.getDirectives();
+ List<Directive> filterDirective = filterDirective(directives, DirectiveKind.REQUIRES);
+ assertEquals("Incorrect no of requires", 0, filterDirective.size());
+ }
+ /*
+ * Test java.base module can be loaded and verify its 'opens' attributes
+ */
+ public void testModuleJavaBase3() {
+ Set<? extends ModuleElement> allModuleElements = _elementUtils.getAllModuleElements();
+ ModuleElement base = null;
+ for (ModuleElement moduleElement : allModuleElements) {
+ if (moduleElement.getQualifiedName().toString().equals("java.base")) {
+ base = moduleElement;
+ }
+ }
+ assertNotNull("java.base module null", base);
+ List<? extends Directive> directives = base.getDirectives();
+ List<Directive> filterDirective = filterDirective(directives, DirectiveKind.OPENS);
+ assertEquals("incorrect no of opens", 0 , filterDirective.size());
+ }
+ /*
+ * Test java.base module can be loaded and verify its 'uses' attributes
+ */
+ public void testModuleJavaBase4() {
+ Set<? extends ModuleElement> allModuleElements = _elementUtils.getAllModuleElements();
+ ModuleElement base = null;
+ for (ModuleElement moduleElement : allModuleElements) {
+ if (moduleElement.getQualifiedName().toString().equals("java.base")) {
+ base = moduleElement;
+ }
+ }
+ assertNotNull("java.base module null", base);
+ List<? extends Directive> directives = base.getDirectives();
+ List<Directive> filterDirective = filterDirective(directives, DirectiveKind.USES);
+ assertEquals("incorrect no of uses", 34 , filterDirective.size());
+ }
+ /*
+ * Test java.base module can be loaded and verify its 'provides' attributes
+ */
+ public void testModuleJavaBase5() {
+ Set<? extends ModuleElement> allModuleElements = _elementUtils.getAllModuleElements();
+ ModuleElement base = null;
+ for (ModuleElement moduleElement : allModuleElements) {
+ if (moduleElement.getQualifiedName().toString().equals("java.base")) {
+ base = moduleElement;
+ }
+ }
+ assertNotNull("java.base module null", base);
+ List<? extends Directive> directives = base.getDirectives();
+ List<Directive> filterDirective = filterDirective(directives, DirectiveKind.PROVIDES);
+ assertEquals("incorrect no of provides", 1 , filterDirective.size());
+ ProvidesDirective provides = (ProvidesDirective) filterDirective.get(0);
+ assertEquals("incorrect service name", "java.nio.file.spi.FileSystemProvider", provides.getService().getQualifiedName().toString());
+ List<? extends TypeElement> implementations = provides.getImplementations();
+ assertEquals("incorrect no of implementations", 1 , implementations.size());
+ TypeElement typeElement = implementations.get(0);
+ assertEquals("incorrect implementation name", "jdk.internal.jrtfs.JrtFileSystemProvider", typeElement.getQualifiedName().toString());
+ }
+ public void testModuleTypeMirror1() {
+ ModuleElement base = _elementUtils.getModuleElement("java.base");
+ assertNotNull("java.base module null", base);
+ TypeMirror asType = base.asType();
+ assertNotNull("module type should not be null", asType);
+ assertEquals("incorrect type kind", TypeKind.MODULE, asType.getKind());
+ assertEquals("must be a NoType", (asType instanceof NoType));
+ }
+ public void testModuleTypeMirror2() {
+ ModuleElement base = _elementUtils.getModuleElement("mod.a");
+ assertNotNull("mod.a module null", base);
+ TypeMirror asType = base.asType();
+ assertNotNull("module type should not be null", asType);
+ verifyAnnotations(asType, new String[]{});
+ }
+ /*
+ * Test java.sql module can be loaded and verify its requires attributes
+ */
+ public void testModuleJavaSql1() {
+ Set<? extends ModuleElement> allModuleElements = _elementUtils.getAllModuleElements();
+ ModuleElement base = null;
+ for (ModuleElement moduleElement : allModuleElements) {
+ if (moduleElement.getQualifiedName().toString().equals("java.sql")) {
+ base = moduleElement;
+ break;
+ }
+ }
+ assertNotNull("java.sql module null", base);
+ List<? extends Directive> directives = base.getDirectives();
+ List<Directive> filterDirective = filterDirective(directives, DirectiveKind.REQUIRES);
+ assertEquals("Incorrect no of requires", 3, filterDirective.size());
+ RequiresDirective req = null;
+ for (Directive directive : filterDirective) {
+ if (((RequiresDirective) directive).getDependency().getQualifiedName().toString().equals("java.logging")) {
+ req = (RequiresDirective) directive;
+ break;
+ }
+ }
+ assertNotNull("dependency on java.logging not found", req);
+ assertTrue("dependency should be transitive", req.isTransitive());
+ }
+ /*
+ * Test a source module can be retrieved and verify its requires attributes
+ */
+ public void testSourceModule1() {
+ ModuleElement mod = _elementUtils.getModuleElement("mod.a");
+ assertNotNull("mod.a module null", mod);
+ List<? extends Directive> directives = mod.getDirectives();
+ List<Directive> filterDirective = filterDirective(directives, DirectiveKind.REQUIRES);
+ assertEquals("Incorrect no of requires", 3, filterDirective.size());
+ RequiresDirective reqCompiler = null;
+ RequiresDirective reqSql = null;
+ for (Directive directive : filterDirective) {
+ if (((RequiresDirective) directive).getDependency().getQualifiedName().toString().equals("java.compiler")) {
+ reqCompiler = (RequiresDirective) directive;
+ }
+ if (((RequiresDirective) directive).getDependency().getQualifiedName().toString().equals("java.sql")) {
+ reqSql = (RequiresDirective) directive;
+ }
+ }
+ assertNotNull("dependency on java.sql not found", reqSql);
+ assertNotNull("dependency on java.sql not found", reqCompiler);
+ assertTrue("dependency should be transitive", reqSql.isTransitive());
+ assertTrue("dependency should be transitive", reqCompiler.isTransitive());
+ }
+ /*
+ * Test a source module can be retrieved and verify its requires attributes
+ */
+ public void testSourceModule2() {
+ ModuleElement mod = _elementUtils.getModuleElement("mod.b");
+ assertNotNull("mod.b module null", mod);
+ List<? extends Directive> directives = mod.getDirectives();
+ List<Directive> filterDirective = filterDirective(directives, DirectiveKind.REQUIRES);
+ assertEquals("Incorrect no of requires", 2, filterDirective.size());
+ RequiresDirective reqCompiler = null;
+ RequiresDirective reqSql = null;
+ RequiresDirective reqA = null;
+ for (Directive directive : filterDirective) {
+ if (((RequiresDirective) directive).getDependency().getQualifiedName().toString().equals("java.compiler")) {
+ reqCompiler = (RequiresDirective) directive;
+ }
+ if (((RequiresDirective) directive).getDependency().getQualifiedName().toString().equals("java.sql")) {
+ reqSql = (RequiresDirective) directive;
+ }
+ if (((RequiresDirective) directive).getDependency().getQualifiedName().toString().equals("mod.a")) {
+ reqA = (RequiresDirective) directive;
+ }
+ }
+ assertNull("dependency on java.sql should not be visible", reqSql);
+ assertNull("dependency on java.compiler should not be visible", reqCompiler);
+ assertNotNull("dependency on mod.a not found", reqA);
+ assertFalse("dependency should not be transitive", reqA.isTransitive());
+ }
+ public void testUnnamedModule1() {
+ Set<? extends Element> rootElements = this.roundEnv.getRootElements();
+ ModuleElement mod = null;
+ for (Element element : rootElements) {
+ if (element instanceof TypeElement) {
+ mod = _elementUtils.getModuleOf(element);
+ break;
+ }
+ }
+ assertNotNull("module should not be null", mod);
+ assertTrue("module should be unnamed", mod.isUnnamed());
+ List<? extends Element> enclosedElements = mod.getEnclosedElements();
+ List<? extends Directive> directives = mod.getDirectives();
+ assertEquals("incorrect no of directives", 0, directives.size());
+ List<Element> filterElements = filterElements(enclosedElements, ElementKind.PACKAGE);
+ assertEquals("incorrect no of packages", 3, filterElements.size());
+ // FIXME: Note Javac fails here as well
+// PackageElement packageOf = _elementUtils.getPackageOf(mod);
+// assertNotNull("package should not be null", packageOf);
+ }
+ public void testUnnamedModule2() {
+ Set<? extends PackageElement> allPackageElements = _elementUtils.getAllPackageElements("targets.model9.p");
+ assertEquals("incorrect no of packages", 1, allPackageElements.size());
+ TypeElement typeElement =_elementUtils.getTypeElement("targets.model9.p.A");
+ assertNotNull("Type should not be null", typeElement);
+ ModuleElement m = _elementUtils.getModuleOf(typeElement);
+ assertEquals("module should be unnamed", "", m.getQualifiedName().toString());
+ }
+ public void testUnnamedModule3() {
+ Set<? extends Element> rootElements = this.roundEnv.getRootElements();
+ ModuleElement moduleElement = _elementUtils.getModuleElement("");
+ assertNotNull("module should not be null", moduleElement);
+ ModuleElement mod = null;
+ for (Element element : rootElements) {
+ if (element instanceof TypeElement) {
+ mod = (ModuleElement) element.getEnclosingElement().getEnclosingElement();
+ break;
+ }
+ }
+ assertEquals("modules should be equal", mod, moduleElement);
+ assertNotNull("module should not be null", mod);
+ List<Element> filterElements = filterElements(mod.getEnclosedElements(), ElementKind.PACKAGE);
+ assertEquals("incorrect no of packages", 1, filterElements.size());
+ }
+ public void testUnnamedModule4() {
+ ModuleElement moduleElement = _elementUtils.getModuleElement("");
+ assertNotNull("module should not be null", moduleElement);
+ List<Element> filterElements = filterElements(moduleElement.getEnclosedElements(), ElementKind.PACKAGE);
+ PackageElement pack = (PackageElement) filterElements.get(0);
+ assertEquals("incorect package", "targets.model9a.internal", pack.getQualifiedName().toString());
+ List<? extends Element> enclosedElements = pack.getEnclosedElements();
+ assertEquals("incorrect no of types", 2, enclosedElements.size());
+ }
+ public void testUnnamedModule5() {
+ ModuleElement moduleElement = _elementUtils.getModuleElement("");
+ assertNotNull("module should not be null", moduleElement);
+ List<Element> filterElements = filterElements(moduleElement.getEnclosedElements(), ElementKind.PACKAGE);
+ PackageElement pack = (PackageElement) filterElements.get(0);
+ assertEquals("incorect package", "targets.model9x", pack.getQualifiedName().toString());
+ List<? extends Element> enclosedElements = pack.getEnclosedElements();
+ assertEquals("incorrect no of types", 1, enclosedElements.size());
+ }
public void testBug521723() {
// private int foo1(int i) { return i; }
// default int foo2(int i) {return foo(i); }
@@ -86,4 +686,144 @@ public class Java9ElementProcessor extends Java8ElementProcessor {
}
assertTrue("modifiers still present: " + list.toString(), list.isEmpty());
}
+ protected <E extends Element> List<Element> filterElements(Iterable<? extends E> list, ElementKind kind) {
+ List<Element> elements = new ArrayList<>();
+ for (Element e : list) {
+ if (e.getKind() == kind)
+ elements.add(e);
+ }
+ return elements;
+ }
+ protected <D extends Directive> List<Directive> filterDirective(Iterable<? extends Directive> list, DirectiveKind kind) {
+ List<Directive> directives = new ArrayList<>();
+ for (Directive d : list) {
+ if (d.getKind() == kind)
+ directives.add(d);
+ }
+ return directives;
+ }
+
+ @Override
+ public void reportError(String msg) {
+ throw new AssertionFailedError(msg);
+ }
+ private String getExceptionStackTrace(Throwable t) {
+ StringBuffer buf = new StringBuffer(t.getMessage());
+ StackTraceElement[] traces = t.getStackTrace();
+ for (int i = 0; i < traces.length; i++) {
+ StackTraceElement trace = traces[i];
+ buf.append("\n\tat " + trace);
+ if (i == 12)
+ break; // Don't dump all stacks
+ }
+ return buf.toString();
+ }
+ public void assertModifiers(Set<Modifier> modifiers, String[] expected) {
+ assertEquals("Incorrect no of modifiers", modifiers.size(), expected.length);
+ Set<String> actual = new HashSet<String>(expected.length);
+ for (Modifier modifier : modifiers) {
+ actual.add(modifier.toString());
+ }
+ for(int i = 0, length = expected.length; i < length; i++) {
+ boolean result = actual.remove(expected[i]);
+ if (!result) reportError("Modifier not present :" + expected[i]);
+ }
+ if (!actual.isEmpty()) {
+ reportError("Unexpected modifiers present:" + actual.toString());
+ }
+ }
+ public void assertTrue(String msg, boolean value) {
+ if (!value) reportError(msg);
+ }
+ public void assertFalse(String msg, boolean value) {
+ if (value) reportError(msg);
+ }
+ public void assertSame(String msg, Object obj1, Object obj2) {
+ if (obj1 != obj2) {
+ reportError(msg + ", should be " + obj1.toString() + " but " + obj2.toString());
+ }
+ }
+ public void assertNotSame(String msg, Object obj1, Object obj2) {
+ if (obj1 == obj2) {
+ reportError(msg + ", " + obj1.toString() + " should not be same as " + obj2.toString());
+ }
+ }
+ public void assertNotNull(String msg, Object obj) {
+ if (obj == null) {
+ reportError(msg);
+ }
+ }
+ public void assertNull(String msg, Object obj) {
+ if (obj != null) {
+ reportError(msg);
+ }
+ }
+ public void assertEquals(String message, Object expected, Object actual) {
+ if (equalsRegardingNull(expected, actual)) {
+ return;
+ } else {
+ reportError(message + ", expected " + expected.toString() + " but was " + actual.toString());
+ }
+ }
+
+ public void assertEquals(String message, Object expected, Object alternateExpected, Object actual) {
+ if (equalsRegardingNull(expected, actual) || equalsRegardingNull(alternateExpected, actual)) {
+ return;
+ } else {
+ reportError(message + ", expected " + expected.toString() + " but was " + actual.toString());
+ }
+ }
+
+ static boolean equalsRegardingNull(Object expected, Object actual) {
+ if (expected == null) {
+ return actual == null;
+ }
+ return expected.equals(actual);
+ }
+
+ public void assertEquals(String msg, int expected, int actual) {
+ if (expected != actual) {
+ StringBuffer buf = new StringBuffer();
+ buf.append(msg);
+ buf.append(", expected " + expected + " but was " + actual);
+ reportError(buf.toString());
+ }
+ }
+ public void assertEquals(Object expected, Object actual) {
+ if (expected != actual) {
+
+ }
+ }
+ private void verifyAnnotations(AnnotatedConstruct construct, String[] annots) {
+ List<? extends AnnotationMirror> annotations = construct.getAnnotationMirrors();
+ assertEquals("Incorrect no of annotations", annots.length, annotations.size());
+ for(int i = 0, length = annots.length; i < length; i++) {
+ AnnotationMirror mirror = annotations.get(i);
+ assertEquals("Invalid annotation value", annots[i], getAnnotationString(mirror));
+ }
+ }
+
+ private String getAnnotationString(AnnotationMirror annot) {
+ DeclaredType annotType = annot.getAnnotationType();
+ TypeElement type = (TypeElement) annotType.asElement();
+ StringBuffer buf = new StringBuffer("@" + type.getQualifiedName());
+ Map<? extends ExecutableElement, ? extends AnnotationValue> values = annot.getElementValues();
+ Set<? extends ExecutableElement> keys = values.keySet();
+ buf.append('(');
+ for (ExecutableElement executableElement : keys) { // @Marker3()
+ buf.append(executableElement.getSimpleName());
+ buf.append('=');
+ AnnotationValue value = values.get(executableElement);
+ buf.append(value.getValue());
+ }
+ buf.append(')');
+ return buf.toString();
+ }
+ private class AssertionFailedError extends Error {
+ private static final long serialVersionUID = 1L;
+
+ public AssertionFailedError(String msg) {
+ super(msg);
+ }
+ }
}
diff --git a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/AllTests.java b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/AllTests.java
index c897d8345b..80c1046aa3 100644
--- a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/AllTests.java
+++ b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/AllTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2014 IBM, BEA Systems, Inc. and others
+ * Copyright (c) 2006, 2017 IBM, BEA Systems, Inc. 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
@@ -31,6 +31,7 @@ public class AllTests extends TestCase {
suite.addTestSuite(ModelUtilTests.class);
suite.addTestSuite(NegativeTests.class);
suite.addTestSuite(Java8ElementsTests.class);
+ suite.addTestSuite(Java9ElementsTests.class);
suite.addTestSuite(AnnotationProcessorTests.class);
return suite;
}
diff --git a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchTestUtils.java b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchTestUtils.java
index 099cb11166..7bed895965 100644
--- a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchTestUtils.java
+++ b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/BatchTestUtils.java
@@ -1,9 +1,13 @@
/*******************************************************************************
- * Copyright (c) 2007, 2015 BEA Systems, Inc.
+ * Copyright (c) 2007, 2017 BEA Systems, Inc.
* 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
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
*
* Contributors:
* wharley@bea.com - initial API and implementation
@@ -13,9 +17,6 @@
package org.eclipse.jdt.compiler.apt.tests;
-import org.eclipse.core.runtime.FileLocator;
-import org.eclipse.core.runtime.Platform;
-
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
@@ -42,6 +43,9 @@ import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Platform;
+
/**
* Helper class to support compilation and results checking for tests running in batch mode.
* @since 3.3
@@ -98,6 +102,11 @@ public class BatchTestUtils {
System.err.println("Compilation failed: " + errorOutput);
junit.framework.TestCase.assertTrue("Compilation failed : " + errorOutput, false);
}
+ try {
+ manager.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
}
public static void compileTree(JavaCompiler compiler, List<String> options, File targetFolder) {
@@ -113,6 +122,66 @@ public class BatchTestUtils {
compileTree(compiler, options, targetFolder, useJLS8Processors, null);
}
+ public static void compileInModuleMode(JavaCompiler compiler, List<String> options, String processor,
+ File targetFolder, DiagnosticListener<? super JavaFileObject> listener, boolean multiModule) {
+ StandardJavaFileManager manager = compiler.getStandardFileManager(null, Locale.getDefault(), Charset.defaultCharset());
+ Iterable<? extends File> location = manager.getLocation(StandardLocation.CLASS_PATH);
+ // create new list containing inputfile
+ List<File> files = new ArrayList<File>();
+ findFilesUnder(targetFolder, files);
+ Iterable<? extends JavaFileObject> units = manager.getJavaFileObjectsFromFiles(files);
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter printWriter = new PrintWriter(stringWriter);
+
+ List<String> copyOptions = new ArrayList<>();
+ copyOptions.add("-processor");
+ copyOptions.add(processor);
+ copyOptions.add("-A" + processor);
+ copyOptions.add("-d");
+ copyOptions.add(_tmpBinFolderName);
+ copyOptions.add("-s");
+ copyOptions.add(_tmpGenFolderName);
+ addModuleProcessorPath(copyOptions, getSrcFolderName(), multiModule);
+ copyOptions.add("-XprintRounds");
+ CompilationTask task = compiler.getTask(printWriter, manager, listener, copyOptions, null, units);
+ Boolean result = task.call();
+
+ if (!result.booleanValue()) {
+ String errorOutput = stringWriter.getBuffer().toString();
+ System.err.println("Compilation failed: " + errorOutput);
+ junit.framework.TestCase.assertTrue("Compilation failed : " + errorOutput, false);
+ }
+ List<String> classes = new ArrayList<>();
+ try {
+ System.clearProperty(processor);
+ copyOptions = new ArrayList<>();
+ copyOptions.addAll(options);
+ copyOptions.add("-cp");
+ copyOptions.add(_jls8ProcessorJarPath + File.pathSeparator + _tmpGenFolderName);
+ copyOptions.add("--processor-module-path");
+ copyOptions.add(_jls8ProcessorJarPath);
+ copyOptions.add("--module-path");
+ copyOptions.add(_tmpBinFolderName);
+ classes.add("java.base/java.lang.Object"); // This is required to make sure BTB for Object is fully populated.
+ findClassesUnderModules(Paths.get(_tmpBinFolderName), classes);
+ manager.setLocation(StandardLocation.CLASS_PATH, location);
+ task = compiler.getTask(printWriter, manager, listener, copyOptions, classes, null);
+ result = task.call();
+ if (!result.booleanValue()) {
+ String errorOutput = stringWriter.getBuffer().toString();
+ System.err.println("Compilation failed: " + errorOutput);
+ junit.framework.TestCase.assertTrue("Compilation failed : " + errorOutput, false);
+ }
+ } catch (IOException e) {
+ // print the stack just in case.
+ e.printStackTrace();
+ }
+ try {
+ manager.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
public static void compileTree(JavaCompiler compiler, List<String> options,
File targetFolder, boolean useJLS8Processors,
DiagnosticListener<? super JavaFileObject> listener) {
@@ -139,6 +208,11 @@ public class BatchTestUtils {
System.err.println("Compilation failed: " + errorOutput);
junit.framework.TestCase.assertTrue("Compilation failed : " + errorOutput, false);
}
+ try {
+ manager.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
}
/*
* First compiles the given files without processor, then processes them
@@ -180,7 +254,7 @@ public class BatchTestUtils {
copyOptions.add("-processorpath");
copyOptions.add(_jls8ProcessorJarPath);
classes.add("java.lang.Object"); // This is required to make sure BTB for Object is fully populated.
- findClassesUnder(Paths.get(_tmpBinFolderName), null, classes);
+ findClassesUnder(Paths.get(_tmpBinFolderName), null, classes, null);
manager.setLocation(StandardLocation.CLASS_PATH, location);
task = compiler.getTask(printWriter, manager, listener, copyOptions, classes, null);
result = task.call();
@@ -241,7 +315,11 @@ public class BatchTestUtils {
StringWriter writer = new StringWriter();
CompilationTask task = compiler.getTask(writer, manager, diagnosticListener, options, null, units);
Boolean result = task.call();
-
+ try {
+ manager.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
return result.booleanValue();
}
@@ -265,18 +343,31 @@ public class BatchTestUtils {
}
}
- protected static void findClassesUnder(Path root, Path folder, List<String> classes) throws IOException {
+ protected static void findClassesUnderModules(Path modulePath, List<String> classes) throws IOException {
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(modulePath)) {
+ for (Path entry : stream) {
+ if (Files.isDirectory(entry)) {
+ findClassesUnder(entry, entry, classes, entry.getFileName().toString());
+ }
+ }
+ }
+ }
+ protected static void findClassesUnder(Path root, Path folder, List<String> classes, String moduleName) throws IOException {
if (folder == null)
folder = root;
try (DirectoryStream<Path> stream = Files.newDirectoryStream(folder)) {
for (Path entry : stream) {
if (Files.isDirectory(entry)) {
- findClassesUnder(root, entry, classes);
+ findClassesUnder(root, entry, classes, moduleName);
} else {
- if (entry.getFileName().toString().endsWith(".class")) {
+ String fileName = entry.getFileName().toString();
+ if (fileName.endsWith(".class") && !fileName.startsWith("module-info")) {
String className = root.relativize(entry).toString();
className = className.substring(0, className.indexOf(".class"));
className = className.replace(File.separatorChar, '.');
+ if (moduleName != null) {
+ className = moduleName + "/" + className;
+ }
classes.add(className);
}
}
@@ -372,6 +463,16 @@ public class BatchTestUtils {
options.add("-processorpath");
options.add(path);
}
+ private static void addModuleProcessorPath(List<String> options, String srcFolderName, boolean multiModule) {
+ options.add("--processor-module-path");
+ options.add(_jls8ProcessorJarPath);
+ options.add("--module-path");
+ options.add(_jls8ProcessorJarPath);
+ if (multiModule) {
+ options.add("--module-source-path");
+ options.add(srcFolderName);
+ }
+ }
public static void tearDown() {
new File(_processorJarPath).deleteOnExit();
@@ -446,6 +547,10 @@ public class BatchTestUtils {
contents = TestUtils.convertToIndependentLineDelimiter(contents);
srcBytes = contents.getBytes();
}
+ writeFile(dest, srcBytes);
+ }
+
+ public static void writeFile(File dest, byte[] srcBytes) throws IOException {
File destFolder = dest.getParentFile();
if (!destFolder.exists()) {
diff --git a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java8ElementsTests.java b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java8ElementsTests.java
index 96396308b8..b2b88767b5 100644
--- a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java8ElementsTests.java
+++ b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java8ElementsTests.java
@@ -20,12 +20,12 @@ import javax.lang.model.SourceVersion;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
+import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
+
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
-import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
-
public class Java8ElementsTests extends TestCase {
private static final String JAVA8_ANNOTATION_PROC = "org.eclipse.jdt.compiler.apt.tests.processors.elements.Java8ElementProcessor";
@@ -60,7 +60,9 @@ public class Java8ElementsTests extends TestCase {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
internalTest(compiler, JAVA8_ANNOTATION_PROC, "testTypeAnnotations");
}
- public void _testTypeAnnotationsWithJavac() throws Exception {
+ public void testTypeAnnotationsWithJavac() throws Exception {
+ if (!canRunJava9())
+ return;
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
internalTest(compiler, JAVA8_ANNOTATION_PROC, "testTypeAnnotations");
}
@@ -76,7 +78,9 @@ public class Java8ElementsTests extends TestCase {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
internalTest(compiler, JAVA8_ANNOTATION_PROC, "testTypeAnnotations2");
}
- public void _testTypeAnnotations2WithJavac() throws Exception {
+ public void testTypeAnnotations2WithJavac() throws Exception {
+ if (!canRunJava9())
+ return;
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
internalTest(compiler, JAVA8_ANNOTATION_PROC, "testTypeAnnotations2");
}
@@ -84,7 +88,9 @@ public class Java8ElementsTests extends TestCase {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
internalTest(compiler, JAVA8_ANNOTATION_PROC, "testTypeAnnotations3");
}
- public void _testTypeAnnotations3WithJavac() throws Exception {
+ public void testTypeAnnotations3WithJavac() throws Exception {
+ if (!canRunJava9())
+ return;
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
internalTest(compiler, JAVA8_ANNOTATION_PROC, "testTypeAnnotations3");
}
@@ -92,7 +98,9 @@ public class Java8ElementsTests extends TestCase {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
internalTest(compiler, JAVA8_ANNOTATION_PROC, "testTypeAnnotations4");
}
- public void _testTypeAnnotations4WithJavac() throws Exception {
+ public void testTypeAnnotations4WithJavac() throws Exception {
+ if (!canRunJava9())
+ return;
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
internalTest(compiler, JAVA8_ANNOTATION_PROC, "testTypeAnnotations4");
}
@@ -100,7 +108,9 @@ public class Java8ElementsTests extends TestCase {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
internalTest(compiler, JAVA8_ANNOTATION_PROC, "testTypeAnnotations5");
}
- public void _testTypeAnnotations5WithJavac() throws Exception {
+ public void testTypeAnnotations5WithJavac() throws Exception {
+ if (!canRunJava9())
+ return;
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
internalTest(compiler, JAVA8_ANNOTATION_PROC, "testTypeAnnotations5");
}
@@ -108,7 +118,9 @@ public class Java8ElementsTests extends TestCase {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
internalTest(compiler, JAVA8_ANNOTATION_PROC, "testTypeAnnotations6");
}
- public void _testTypeAnnotations6WithJavac() throws Exception { // Disabled for now. Javac 8b108 drops annotations arrays preceding varargs.
+ public void testTypeAnnotations6WithJavac() throws Exception { // Disabled for now. Javac 8b108 drops annotations arrays preceding varargs.
+ if (!canRunJava9())
+ return;
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
internalTest(compiler, JAVA8_ANNOTATION_PROC, "testTypeAnnotations6");
}
@@ -148,7 +160,9 @@ public class Java8ElementsTests extends TestCase {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
internalTest(compiler, JAVA8_ANNOTATION_PROC, "testTypeAnnotations11");
}
- public void _testTypeAnnotations11WithJavac() throws Exception {
+ public void testTypeAnnotations11WithJavac() throws Exception {
+ if (!canRunJava9())
+ return;
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
internalTest(compiler, JAVA8_ANNOTATION_PROC, "testTypeAnnotations11");
}
@@ -301,7 +315,8 @@ public class Java8ElementsTests extends TestCase {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
internalTest(compiler, JAVA8_ANNOTATION_PROC, "testPackageAnnotations", null, "filer8");
}
- public void testPackageAnnotationsWithJavac() throws Exception {
+ // See Java8ElementProcessor.testPackageAnnotations()
+ public void _testPackageAnnotationsWithJavac() throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
internalTest(compiler, JAVA8_ANNOTATION_PROC, "testPackageAnnotations", null, "filer8");
}
@@ -418,6 +433,14 @@ public class Java8ElementsTests extends TestCase {
}
return true;
}
+ public boolean canRunJava9() {
+ try {
+ SourceVersion.valueOf("RELEASE_9");
+ } catch(IllegalArgumentException iae) {
+ return false;
+ }
+ return true;
+ }
@Override
protected void tearDown() throws Exception {
super.tearDown();
diff --git a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java9ElementsTests.java b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java9ElementsTests.java
index d55a48a9ef..a3e2659e04 100644
--- a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java9ElementsTests.java
+++ b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/Java9ElementsTests.java
@@ -24,33 +24,356 @@ import javax.lang.model.SourceVersion;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
+import junit.framework.TestCase;
+
public class Java9ElementsTests extends TestCase {
+ private static final String MODULE_PROC = "org.eclipse.jdt.compiler.apt.tests.processors.elements.Java9ElementProcessor";
+
+ public void testRootElements1Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testRootElements1", null);
+ }
+ public void testRootElements1() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testRootElements1", null);
+ }
+
+ public void testRootElements2Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testRootElements2", null);
+ }
+ public void testRootElements2() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testRootElements2", null);
+ }
+
+ public void testAnnotations1Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testModuleAnnotation1", null);
+ }
+ public void testAnnotations1() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testModuleAnnotation1", null);
+ }
+
+ public void testModuleElement1Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testModuleElement1", null);
+ }
+ public void testModuleElement1() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testModuleElement1", null);
+ }
+
+ public void testModuleElement2Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testModuleElement2", null);
+ }
+ public void testModuleElement2() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testModuleElement2", null);
+ }
+
+ public void testModuleElement3Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testModuleElement3", null);
+ }
+ public void testModuleElement3() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testModuleElement3", null);
+ }
+ public void testModuleElement4Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testModuleElement4", null);
+ }
+ public void testModuleElement4() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testModuleElement4", null);
+ }
+
+ public void testModuleElement5Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testModuleElement5", null);
+ }
+ public void testModuleElement5() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testModuleElement5", null);
+ }
+
+ public void testModuleElement6Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testModuleElement6", null);
+ }
+ public void testModuleElement6() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testModuleElement6", null);
+ }
+
+ public void testModuleElement7Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testModuleElement7", null);
+ }
+ public void testModuleElement7() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testModuleElement7", null);
+ }
+
+ public void testModuleJavaBase1Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testModuleJavaBase1", null);
+ }
+ public void testModuleJavaBase1() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testModuleJavaBase1", null);
+ }
+
+
+ public void testModuleJavaBase2Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testModuleJavaBase2", null);
+ }
+ public void testModuleJavaBase2() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testModuleJavaBase2", null);
+ }
+
- private static final String JAVA9_ANNOTATION_PROC = "org.eclipse.jdt.compiler.apt.tests.processors.elements.Java9ElementProcessor";
+ public void testModuleJavaBase3Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testModuleJavaBase3", null);
+ }
+ public void testModuleJavaBase3() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testModuleJavaBase3", null);
+ }
- public static Test suite() {
- return new TestSuite(Java9ElementsTests.class);
+ public void testModuleJavaBase4Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testModuleJavaBase4", null);
+ }
+ public void testModuleJavaBase4() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testModuleJavaBase4", null);
}
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- BatchTestUtils.init();
+ public void testModuleJavaBase5Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testModuleJavaBase5", null);
+ }
+ public void testModuleJavaBase5() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testModuleJavaBase5", null);
+ }
+
+ public void testModuleTypeMirror1Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testModuleTypeMirror1", null);
+ }
+ public void testModuleTypeMirror1() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testModuleTypeMirror1", null);
}
+ public void testModuleTypeMirror2Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testModuleTypeMirror2", null);
+ }
+ public void testModuleTypeMirror2() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testModuleTypeMirror2", null);
+ }
+
+ public void testModuleJavaSql1Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testModuleJavaSql1", null);
+ }
+ public void testModuleJavaSql1() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testModuleJavaSql1", null);
+ }
+
+ public void testSourceModule1Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testSourceModule1", null);
+ }
+ public void testSourceModule1() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testSourceModule1", null);
+ }
+
+ public void testSourceModule2Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest2(compiler, MODULE_PROC, "testSourceModule2", null);
+ }
+ public void testSourceModule2() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest2(compiler, MODULE_PROC, "testSourceModule2", null);
+ }
+ public void testUnnamedModule1Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest(compiler, MODULE_PROC, "testUnnamedModule1", null, "model9");
+ }
+ public void testUnnamedModule1() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest(compiler, MODULE_PROC, "testUnnamedModule1", null, "model9");
+ }
+ public void testUnnamedModule2Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest(compiler, MODULE_PROC, "testUnnamedModule2", null, "model9");
+ }
+ public void testUnnamedModule2() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest(compiler, MODULE_PROC, "testUnnamedModule2", null, "model9");
+ }
+ public void testUnnamedModule3Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest(compiler, MODULE_PROC, "testUnnamedModule3", null, "model9a");
+ }
+ public void testUnnamedModule3() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest(compiler, MODULE_PROC, "testUnnamedModule3", null, "model9a");
+ }
+ public void testUnnamedModule4Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest(compiler, MODULE_PROC, "testUnnamedModule4", null, "model9a");
+ }
+ public void testUnnamedModule4() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest(compiler, MODULE_PROC, "testUnnamedModule4", null, "model9a");
+ }
+ public void testUnnamedModule5Javac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ if (compiler == null) {
+ System.out.println("No system java compiler available");
+ return;
+ }
+ internalTest(compiler, MODULE_PROC, "testUnnamedModule5", null, new String[] {
+ "targets/model9x/X.java",
+ "package targets.model9x;\n" +
+ "public class X {\n" +
+ " X(final int j) {\n" +
+ " j = 4;\n" +
+ " }\n" +
+ "}\n"
+ });
+ }
+ public void testUnnamedModule5() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTest(compiler, MODULE_PROC, "testUnnamedModule5", null, new String[] {
+ "targets/model9x/X.java",
+ "package targets.model9x;\n" +
+ "public class X {\n" +
+ " X(final int j) {\n" +
+ " j = 4;\n" +
+ " }\n" +
+ "}\n"
+ });
+ }
public void testBug521723() throws IOException {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
- internalTestWithBinary(compiler, JAVA9_ANNOTATION_PROC, "9", "testBug521723", null, "bug521723");
+ internalTestWithBinary(compiler, MODULE_PROC, "9", "testBug521723", null, "bug521723");
}
public void testBug521723Javac() throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- internalTestWithBinary(compiler, JAVA9_ANNOTATION_PROC, "9", "testBug521723", null, "bug521723");
+ internalTestWithBinary(compiler, MODULE_PROC, "9", "testBug521723", null, "bug521723");
}
protected void internalTestWithBinary(JavaCompiler compiler, String processor, String compliance, String testMethod, String testClass, String resourceArea) throws IOException {
@@ -84,6 +407,86 @@ public class Java9ElementsTests extends TestCase {
// if not, it will set it to an error value.
assertEquals("succeeded", System.getProperty(processor));
}
+ private void internalTest(JavaCompiler compiler, String processor, String testMethod, String testClass, String[] source) throws IOException {
+ if (!canRunJava9()) {
+ return;
+ }
+ if ((source.length % 2) != 0) return;
+
+ File targetFolder = TestUtils.concatPath(BatchTestUtils.getSrcFolderName());
+ for(int i = 0; i < source.length;) {
+ File targetFile = TestUtils.concatPath(BatchTestUtils.getSrcFolderName(), source[i++]);
+ BatchTestUtils.writeFile(targetFile, source[i++].getBytes());
+ }
+
+ List<String> options = new ArrayList<String>();
+ options.add("-processor");
+ options.add(MODULE_PROC);
+ options.add("-A" + processor);
+ options.add("-A" + testMethod);
+ if (compiler instanceof EclipseCompiler) {
+ options.add("-9");
+ }
+ BatchTestUtils.compileTreeWithErrors(compiler, options, targetFolder, null, true, true);
+
+ // If it succeeded, the processor will have set this property to "succeeded";
+ // if not, it will set it to an error value.
+ assertEquals("succeeded", System.getProperty(processor));
+ }
+ private void internalTest(JavaCompiler compiler, String processor, String testMethod, String testClass, String resourceArea) throws IOException {
+ internalTest(compiler, processor, testMethod, testClass, resourceArea, false);
+ }
+ private void internalTest(JavaCompiler compiler, String processor, String testMethod, String testClass, String resourceArea, boolean continueWithErrors) throws IOException {
+ if (!canRunJava9()) {
+ return;
+ }
+ System.clearProperty(processor);
+ File targetFolder = TestUtils.concatPath(BatchTestUtils.getSrcFolderName(), "targets", resourceArea);
+ if (testClass == null || testClass.equals("")) {
+ BatchTestUtils.copyResources("targets/" + resourceArea, targetFolder);
+ } else {
+ BatchTestUtils.copyResource("targets/" + resourceArea + "/" + testClass, targetFolder);
+ }
+
+
+ List<String> options = new ArrayList<String>();
+ options.add("-A" + processor);
+ options.add("-A" + testMethod);
+ if (compiler instanceof EclipseCompiler) {
+ options.add("-9");
+ }
+ if (continueWithErrors) {
+ BatchTestUtils.compileTreeWithErrors(compiler, options, targetFolder, null, true, true);
+ } else {
+ BatchTestUtils.compileTree(compiler, options, targetFolder, true);
+ }
+
+ // If it succeeded, the processor will have set this property to "succeeded";
+ // if not, it will set it to an error value.
+ assertEquals("succeeded", System.getProperty(processor));
+ }
+ /*
+ * Tests are run in multi-module mode
+ */
+ private void internalTest2(JavaCompiler compiler, String processor, String testMethod, String testClass) throws IOException {
+ if (!canRunJava9()) {
+ return;
+ }
+ System.clearProperty(MODULE_PROC);
+ File srcRoot = TestUtils.concatPath(BatchTestUtils.getSrcFolderName());
+ BatchTestUtils.copyResources("mod_locations/modules", srcRoot);
+
+ List<String> options = new ArrayList<String>();
+ options.add("-processor");
+ options.add(MODULE_PROC);
+ options.add("-A" + MODULE_PROC);
+ options.add("-A" + testMethod);
+ if (compiler instanceof EclipseCompiler) {
+ options.add("-9");
+ }
+ BatchTestUtils.compileInModuleMode(compiler, options, MODULE_PROC, srcRoot, null, true);
+ assertEquals("succeeded", System.getProperty(MODULE_PROC));
+ }
public boolean canRunJava9() {
try {
SourceVersion.valueOf("RELEASE_9");
@@ -92,8 +495,21 @@ public class Java9ElementsTests extends TestCase {
}
return true;
}
+ /* (non-Javadoc)
+ * @see junit.framework.TestCase#setUp()
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ BatchTestUtils.init();
+ }
+
+ /* (non-Javadoc)
+ * @see junit.framework.TestCase#tearDown()
+ */
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
-}
+
+} \ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/AnnotationDiscoveryVisitor.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/AnnotationDiscoveryVisitor.java
index 6ff1af5ada..12d1b12501 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/AnnotationDiscoveryVisitor.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/AnnotationDiscoveryVisitor.java
@@ -1,10 +1,14 @@
/*******************************************************************************
- * Copyright (c) 2006, 2015 IBM Corporation and others.
+ * Copyright (c) 2006, 2017 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
- *
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
@@ -23,6 +27,7 @@ import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
@@ -35,6 +40,7 @@ import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
@@ -221,6 +227,16 @@ public class AnnotationDiscoveryVisitor extends ASTVisitor {
}
return true;
}
+ @Override
+ public boolean visit(ModuleDeclaration module, CompilationUnitScope scope) {
+ ModuleBinding binding = module.binding;
+ if (binding == null) {
+ return false;
+ }
+ module.resolveTypeDirectives(scope);
+ // The above call also resolvesAnnotations
+ return true;
+ }
private void resolveAnnotations(BlockScope scope, Annotation[] annotations, Binding currentBinding) {
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchAnnotationProcessorManager.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchAnnotationProcessorManager.java
index 2b195ff904..61903f9aae 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchAnnotationProcessorManager.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/BatchAnnotationProcessorManager.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2016 IBM Corporation and others.
+ * Copyright (c) 2005, 2017 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
@@ -14,6 +14,7 @@
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.apt.dispatch;
+import java.io.File;
import java.io.IOException;
import java.net.URLClassLoader;
import java.util.ArrayList;
@@ -23,6 +24,9 @@ import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import javax.annotation.processing.Processor;
+import javax.lang.model.SourceVersion;
+import javax.tools.JavaFileManager;
+import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import org.eclipse.jdt.internal.compiler.batch.Main;
@@ -74,7 +78,21 @@ public class BatchAnnotationProcessorManager extends BaseAnnotationProcessorMana
}
BatchProcessingEnvImpl processingEnv = new BatchProcessingEnvImpl(this, (Main) batchCompiler, commandLineArguments);
_processingEnv = processingEnv;
- _procLoader = processingEnv.getFileManager().getClassLoader(StandardLocation.ANNOTATION_PROCESSOR_PATH);
+ JavaFileManager fileManager = processingEnv.getFileManager();
+ if (fileManager instanceof StandardJavaFileManager) {
+ Iterable<? extends File> location = null;
+ if (SourceVersion.latest().compareTo(SourceVersion.RELEASE_8) > 0) {
+ location = ((StandardJavaFileManager) fileManager).getLocation(StandardLocation.ANNOTATION_PROCESSOR_MODULE_PATH);
+ }
+ if (location != null) {
+ _procLoader = fileManager.getClassLoader(StandardLocation.ANNOTATION_PROCESSOR_MODULE_PATH);
+ } else {
+ _procLoader = fileManager.getClassLoader(StandardLocation.ANNOTATION_PROCESSOR_PATH);
+ }
+ } else {
+ // Fall back to old code
+ _procLoader = fileManager.getClassLoader(StandardLocation.ANNOTATION_PROCESSOR_PATH);
+ }
parseCommandLine(commandLineArguments);
_round = 0;
}
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java
index 169a6ca35a..77fa4df7c7 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/dispatch/RoundEnvImpl.java
@@ -1,10 +1,14 @@
/*******************************************************************************
- * Copyright (c) 2005, 2015 IBM Corporation and others.
+ * Copyright (c) 2005, 2017 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
*
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
* Contributors:
* IBM Corporation - initial API and implementation
* IBM Corporation - Fix for bug 328575
@@ -210,6 +214,11 @@ public class RoundEnvImpl implements RoundEnvironment
if (_rootElements == null) {
Set<Element> elements = new HashSet<>(_units.length);
for (CompilationUnitDeclaration unit : _units) {
+ if (unit.moduleDeclaration != null && unit.moduleDeclaration.binding != null) {
+ Element m = _factory.newElement(unit.moduleDeclaration.binding);
+ elements.add(m);
+ continue;
+ }
if (null == unit.scope || null == unit.scope.topLevelTypes)
continue;
for (SourceTypeBinding binding : unit.scope.topLevelTypes) {
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementImpl.java
index c82b8add9a..b2e7c4c40a 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2014 IBM Corporation and others.
+ * Copyright (c) 2005, 2017 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
@@ -79,6 +79,7 @@ public abstract class ElementImpl
return _env.getFactory().getAnnotationMirrors(getPackedAnnotationBindings());
}
+ @Override
public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
A [] annotations = _env.getFactory().getAnnotationsByType(Factory.getUnpackedAnnotationBindings(getPackedAnnotationBindings()), annotationType);
if (annotations.length != 0 || this.getKind() != ElementKind.CLASS || annotationType.getAnnotation(Inherited.class) == null)
@@ -137,9 +138,10 @@ public abstract class ElementImpl
/**
* @return the package containing this element. The package of a PackageElement is itself.
- * @see javax.lang.model.util.Elements#getPackageOf(javax.lang.model.element.Element)
*/
- abstract /* package */ PackageElement getPackage();
+ PackageElement getPackage() {
+ return null;
+ }
/**
* Subclassed by VariableElementImpl, TypeElementImpl, and ExecutableElementImpl.
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementsImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementsImpl.java
index 5191ad1d39..9026c4d594 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementsImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ElementsImpl.java
@@ -31,11 +31,13 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import javax.lang.model.AnnotatedConstruct;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.Name;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
@@ -54,12 +56,14 @@ import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodVerifier;
+import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
+import org.eclipse.jdt.internal.compiler.util.HashtableOfModule;
/**
* Utilities for working with language elements.
@@ -559,14 +563,14 @@ public class ElementsImpl implements Elements {
public PackageElement getPackageElement(CharSequence name) {
LookupEnvironment le = _env.getLookupEnvironment(); // FIXME(SHMOD): does this lookup need to be module-aware?
if (name.length() == 0) {
- return new PackageElementImpl(_env, le.defaultPackage);
+ return (PackageElement) _env.getFactory().newElement(le.defaultPackage);
}
char[] packageName = name.toString().toCharArray();
PackageBinding packageBinding = le.createPackage(CharOperation.splitOn('.', packageName));
if (packageBinding == null) {
return null;
}
- return new PackageElementImpl(_env, packageBinding);
+ return (PackageElement) _env.getFactory().newElement(packageBinding);
}
@Override
@@ -614,9 +618,27 @@ public class ElementsImpl implements Elements {
*/
@Override
public TypeElement getTypeElement(CharSequence name) {
- LookupEnvironment le = _env.getLookupEnvironment();
final char[][] compoundName = CharOperation.splitOn('.', name.toString().toCharArray());
- ReferenceBinding binding = le.getType(compoundName);
+ Set<? extends ModuleElement> allModuleElements = getAllModuleElements();
+ for (ModuleElement moduleElement : allModuleElements) {
+ TypeElement t = getTypeElement(compoundName, ((ModuleElementImpl) moduleElement).binding);
+ if (t != null) {
+ return t;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public TypeElement getTypeElement(ModuleElement module, CharSequence name) {
+ ModuleBinding mBinding = ((ModuleElementImpl) module).binding;
+ final char[][] compoundName = CharOperation.splitOn('.', name.toString().toCharArray());
+ return getTypeElement(compoundName, mBinding);
+ }
+
+ private TypeElement getTypeElement(final char[][] compoundName, ModuleBinding mBinding) {
+ LookupEnvironment le = mBinding == null ? _env.getLookupEnvironment() : mBinding.environment;
+ ReferenceBinding binding = mBinding == null ? le.getType(compoundName) : le.getType(compoundName, mBinding);
// If we didn't find the binding, maybe it's a nested type;
// try finding the top-level type and then working downwards.
if (null == binding) {
@@ -706,6 +728,7 @@ public class ElementsImpl implements Elements {
}
}
+ @Override
public boolean isFunctionalInterface(TypeElement type) {
if (type != null && type.getKind() == ElementKind.INTERFACE) {
ReferenceBinding binding = (ReferenceBinding)((TypeElementImpl) type)._binding;
@@ -716,4 +739,94 @@ public class ElementsImpl implements Elements {
return false;
}
+ @Override
+ public
+ PackageElement getPackageElement(ModuleElement module, CharSequence name) {
+ ModuleBinding mBinding = ((ModuleElementImpl) module).binding;
+ final char[][] compoundName = CharOperation.splitOn('.', name.toString().toCharArray());
+ PackageBinding p = null;
+ if (mBinding != null) {
+
+ int length = compoundName.length;
+ if (length > 1) {
+ char[][] parent = new char[compoundName.length - 1][];
+ System.arraycopy(compoundName, 0, parent, 0, length - 1);
+ p = mBinding.getPackage(parent, compoundName[length - 1]);
+ } else {
+ p = mBinding.getTopLevelPackage(compoundName[0]);
+ }
+ } else {
+ p = _env.getLookupEnvironment().createPackage(compoundName);
+ }
+ if (p == null || !p.isValidBinding())
+ return null;
+ return (PackageElement) _env.getFactory().newElement(p);
+ }
+
+ @Override
+ public ModuleElement getModuleElement(CharSequence name) {
+ LookupEnvironment lookup = _env.getLookupEnvironment();
+ ModuleBinding binding = lookup.getModule(name.length() == 0 ? ModuleBinding.UNNAMED : name.toString().toCharArray());
+ //TODO: Surely there has to be a better way than calling toString().toCharArray()?
+ if (binding == null) {
+ return null;
+ }
+ return new ModuleElementImpl(_env, binding);
+ }
+
+ @Override
+ public Set<? extends ModuleElement> getAllModuleElements() {
+ LookupEnvironment lookup = _env.getLookupEnvironment();
+ HashtableOfModule knownModules = lookup.knownModules;
+ ModuleBinding[] modules = knownModules.valueTable;
+ if (modules == null || modules.length == 0) {
+ return Collections.emptySet();
+ }
+ Set<ModuleElement> mods = new HashSet<>(modules.length);
+ for (ModuleBinding moduleBinding : modules) {
+ if (moduleBinding == null)
+ continue;
+ ModuleElement element = (ModuleElement) _env.getFactory().newElement(moduleBinding);
+ mods.add(element);
+ }
+ mods.add((ModuleElement) _env.getFactory().newElement(lookup.UnNamedModule));
+ return mods;
+ }
+
+ @Override
+ public Origin getOrigin(Element e) {
+ return Origin.EXPLICIT;
+ }
+
+ @Override
+ public Origin getOrigin(AnnotatedConstruct c, AnnotationMirror a) {
+ return Origin.EXPLICIT;
+ }
+
+ @Override
+ public Origin getOrigin(ModuleElement m, ModuleElement.Directive directive) {
+ return Origin.EXPLICIT;
+ }
+
+ @Override
+ public boolean isBridge(ExecutableElement e) {
+ MethodBinding methodBinding = (MethodBinding) ((ExecutableElementImpl) e)._binding;
+ return methodBinding.isBridge();
+ }
+
+ @Override
+ public ModuleElement getModuleOf(Element elem) {
+ if (elem instanceof ModuleElement) {
+ return (ModuleElement) elem;
+ }
+ Element parent = elem.getEnclosingElement();
+ while (parent != null) {
+ if (parent instanceof ModuleElement) {
+ return (ModuleElement) parent;
+ }
+ parent = parent.getEnclosingElement();
+ }
+ return null;
+ }
+
}
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/Factory.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/Factory.java
index 70ac259038..59ad683f9a 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/Factory.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/Factory.java
@@ -1,10 +1,14 @@
/*******************************************************************************
- * Copyright (c) 2007, 2016 BEA Systems, Inc. and others
+ * Copyright (c) 2007, 2017 BEA Systems, Inc. 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
- *
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
* Contributors:
* wharley@bea.com - initial API and implementation
* IBM Corporation - fix for 342598
@@ -45,9 +49,11 @@ import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.ElementValuePair;
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SplitPackageBinding;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
@@ -319,6 +325,11 @@ public class Factory {
ClassFileConstants.AccStrictfp
});
break;
+ case MODULE :
+ decodeModifiers(result, modifiers, new int[] {
+ ClassFileConstants.ACC_OPEN,
+ ClassFileConstants.ACC_TRANSITIVE
+ });
default:
break;
}
@@ -348,7 +359,7 @@ public class Factory {
return new ErrorTypeElement(this._env, referenceBinding);
}
if (CharOperation.equals(referenceBinding.sourceName, TypeConstants.PACKAGE_INFO_NAME)) {
- return new PackageElementImpl(_env, referenceBinding.fPackage);
+ return newPackageElement(referenceBinding.fPackage);
}
return new TypeElementImpl(_env, referenceBinding, kindHint);
case Binding.METHOD:
@@ -357,10 +368,12 @@ public class Factory {
case Binding.PARAMETERIZED_TYPE:
return new TypeElementImpl(_env, ((ParameterizedTypeBinding)binding).genericType(), kindHint);
case Binding.PACKAGE:
- return new PackageElementImpl(_env, (PackageBinding)binding);
+ return newPackageElement((PackageBinding)binding);
case Binding.TYPE_PARAMETER:
return new TypeParameterElementImpl(_env, (TypeVariableBinding)binding);
// TODO: fill in the rest of these
+ case Binding.MODULE:
+ return new ModuleElementImpl(_env, (ModuleBinding) binding);
case Binding.IMPORT:
case Binding.ARRAY_TYPE:
case Binding.BASE_TYPE:
@@ -380,6 +393,9 @@ public class Factory {
*/
public PackageElement newPackageElement(PackageBinding binding)
{
+ if (binding instanceof SplitPackageBinding && binding.enclosingModule != null) {
+ binding = ((SplitPackageBinding) binding).getIncarnation(binding.enclosingModule);
+ }
return new PackageElementImpl(_env, binding);
}
@@ -396,6 +412,8 @@ public class Factory {
return NoTypeImpl.NO_TYPE_VOID;
case PACKAGE:
return NoTypeImpl.NO_TYPE_PACKAGE;
+ case MODULE:
+ return new NoTypeImpl(kind);
default:
throw new IllegalArgumentException();
}
@@ -487,6 +505,8 @@ public class Factory {
case Binding.TYPE_PARAMETER:
return new TypeVariableImpl(_env, (TypeVariableBinding) binding);
+ case Binding.MODULE:
+ return getNoType(TypeKind.MODULE);
}
return null;
}
@@ -571,9 +591,9 @@ public class Factory {
case 'c':
return Character.valueOf((char) b); // narrowing.
case 'd':
- return new Double(b); // widening.
+ return Double.valueOf(b); // widening.
case 'f':
- return new Float(b); // widening.
+ return Float.valueOf(b); // widening.
case 'i':
return Integer.valueOf(b); // widening.
case 'l':
@@ -599,9 +619,9 @@ public class Factory {
case 'c':
return Character.valueOf((char) s); // narrowing.
case 'd':
- return new Double(s); // widening.
+ return Double.valueOf(s); // widening.
case 'f':
- return new Float(s); // widening.
+ return Float.valueOf(s); // widening.
case 'i':
return Integer.valueOf(s); // widening.
case 'l':
@@ -627,9 +647,9 @@ public class Factory {
case 'c':
return value; // exact match
case 'd':
- return new Double(c); // widening.
+ return Double.valueOf(c); // widening.
case 'f':
- return new Float(c); // widening.
+ return Float.valueOf(c); // widening.
case 'i':
return Integer.valueOf(c); // widening.
case 'l':
@@ -656,9 +676,9 @@ public class Factory {
case 'c':
return Character.valueOf((char) i); // narrowing
case 'd':
- return new Double(i); // widening.
+ return Double.valueOf(i); // widening.
case 'f':
- return new Float(i); // widening.
+ return Float.valueOf(i); // widening.
case 'i':
return value; // exact match
case 'l':
@@ -682,9 +702,9 @@ public class Factory {
// completely wrong.
return avoidReflectException ? getMatchingDummyValue(expectedType) : value;
case 'd':
- return new Double(l); // widening.
+ return Double.valueOf(l); // widening.
case 'f':
- return new Float(l); // widening.
+ return Float.valueOf(l); // widening.
case 'l':
return value; // exact match.
@@ -707,7 +727,7 @@ public class Factory {
// completely wrong.
return avoidReflectException ? getMatchingDummyValue(expectedType) : value;
case 'd':
- return new Double(f); // widening.
+ return Double.valueOf(f); // widening.
case 'f':
return value; // exact match.
default:
@@ -877,6 +897,6 @@ public class Factory {
}
}
}
- return (AnnotationBinding[]) unpackedAnnotations.toArray(new AnnotationBinding [unpackedAnnotations.size()]);
+ return unpackedAnnotations.toArray(new AnnotationBinding [unpackedAnnotations.size()]);
}
}
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java
new file mode 100644
index 0000000000..5ceca21668
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/ModuleElementImpl.java
@@ -0,0 +1,378 @@
+/*******************************************************************************
+ * Copyright (c) 2017 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
+ *
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.apt.model;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ElementVisitor;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+
+import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
+import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
+import org.eclipse.jdt.internal.compiler.lookup.SplitPackageBinding;
+import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
+
+public class ModuleElementImpl extends ElementImpl implements ModuleElement {
+
+ ModuleBinding binding;
+ private List<Directive> directives;
+ private static List<Directive> EMPTY_DIRECTIVES = Collections.emptyList();
+
+ /**
+ * In general, clients should call
+ * {@link Factory#newDeclaredType(ReferenceBinding)} or
+ * {@link Factory#newElement(org.eclipse.jdt.internal.compiler.lookup.Binding)}
+ * to create new instances.
+ */
+ ModuleElementImpl(BaseProcessingEnvImpl env, ModuleBinding binding) {
+ super(env, binding);
+ this.binding = binding;
+ }
+
+ private PackageBinding getModulesPackageBinding(PackageBinding binding) {
+ if (binding instanceof SplitPackageBinding) {
+ return ((SplitPackageBinding) binding).getIncarnation(this.binding);
+ }
+ return binding;
+ }
+
+ @Override
+ public ElementKind getKind() {
+ return ElementKind.MODULE;
+ }
+
+ @Override
+ public Set<Modifier> getModifiers() {
+ int modifiers = this.binding.tagBits; // TODO: This is wrong, this should be "modifiers"
+ return Factory.getModifiers(modifiers, getKind(), false);
+ }
+
+ @Override
+ public Name getQualifiedName() {
+ return new NameImpl(this.binding.moduleName);
+ }
+
+ @Override
+ public Name getSimpleName() {
+ return new NameImpl(this.binding.moduleName);
+ }
+
+ @Override
+ public List<? extends Element> getEnclosedElements() {
+ ModuleBinding module = this.binding;
+ PackageBinding[] packs = module.declaredPackages.valueTable;
+ Set<PackageBinding> unique = new HashSet<>();
+ for (PackageBinding p : packs) {
+ if (p == null)
+ continue;
+ if (!p.hasCompilationUnit(true))
+ continue;
+ unique.add(getModulesPackageBinding(p));
+ }
+ if (module.isUnnamed()) {
+ PackageBinding def = module.environment.defaultPackage;
+ // FIXME: Does it have any impact for unnamed modules - default package combo?
+ if (def != null && def.hasCompilationUnit(true)) {
+ unique.add(def);
+ }
+ } else {
+ packs = this.binding.getExports();
+ for (PackageBinding pBinding : packs) {
+ unique.add(getModulesPackageBinding(pBinding));
+ }
+ packs = this.binding.getOpens();
+ for (PackageBinding pBinding : packs) {
+ unique.add(getModulesPackageBinding(pBinding));
+ }
+ }
+ List<Element> enclosed = new ArrayList<>(unique.size());
+ for (PackageBinding p : unique) {
+ PackageElement pElement = (PackageElement) _env.getFactory().newElement(p);
+ enclosed.add(pElement);
+ }
+ return Collections.unmodifiableList(enclosed);
+ }
+
+ @Override
+ public boolean isOpen() {
+ return (this.binding.modifiers & ClassFileConstants.ACC_OPEN) != 0;
+ }
+
+ @Override
+ public boolean isUnnamed() {
+ return this.binding.moduleName.length == 0;
+ }
+
+ @Override
+ public Element getEnclosingElement() {
+ // As of today, modules have no enclosing element
+ return null;
+ }
+
+ @Override
+ public List<? extends Directive> getDirectives() {
+ if (isUnnamed()) {
+ return EMPTY_DIRECTIVES;
+ }
+ if (this.directives == null)
+ this.directives = new ArrayList<>();
+
+ PackageBinding[] packs = this.binding.getExports();
+ for (PackageBinding exp : packs) {
+ exp = getModulesPackageBinding(exp);
+ this.directives.add(new ExportsDirectiveImpl(exp));
+ }
+ Set<ModuleBinding> transitive = new HashSet<>();
+ for (ModuleBinding mBinding : this.binding.getRequiresTransitive()) {
+ transitive.add(mBinding);
+ }
+ ModuleBinding[] required = this.binding.getRequires();
+ for (ModuleBinding mBinding : required) {
+ if (transitive.contains(mBinding)) {
+ this.directives.add(new RequiresDirectiveImpl(mBinding, true));
+ } else {
+ this.directives.add(new RequiresDirectiveImpl(mBinding, false));
+ }
+ }
+
+ TypeBinding[] tBindings = this.binding.getUses();
+ for (TypeBinding tBinding : tBindings) {
+ this.directives.add(new UsesDirectiveImpl(tBinding));
+ }
+ tBindings = this.binding.getServices();
+ for (TypeBinding tBinding : tBindings) {
+ this.directives.add(new ProvidesDirectiveImpl(tBinding));
+ }
+ packs = this.binding.getOpens();
+ for (PackageBinding exp : packs) {
+ exp = getModulesPackageBinding(exp);
+ this.directives.add(new OpensDirectiveImpl(exp));
+ }
+ return this.directives;
+ }
+
+ @Override
+ public <R, P> R accept(ElementVisitor<R, P> visitor, P param) {
+ return visitor.visitModule(this, param);
+ }
+ @Override
+ protected AnnotationBinding[] getAnnotationBindings() {
+ return ((ModuleBinding) _binding).getAnnotations();
+ }
+
+ abstract class PackageDirectiveImpl {
+ PackageBinding binding;
+ List<ModuleElement> targets;
+
+ PackageDirectiveImpl(PackageBinding pBinding) {
+ this.binding = pBinding;
+ }
+
+ public PackageElement getPackage() {
+ return _env.getFactory().newPackageElement(binding);
+ }
+
+ public List<? extends ModuleElement> getTargetModules(String[] restrictions) {
+ if(this.targets != null) {
+ return targets;
+ }
+ if (restrictions.length == 0) {
+ return (this.targets = null);
+ }
+ List<ModuleElement> targets = new ArrayList<>(restrictions.length);
+ for (String string : restrictions) {
+ ModuleBinding target = ModuleElementImpl.this.binding.environment.getModule(string.toCharArray());
+ if (target != null) {
+ ModuleElement element = ((ModuleElement) _env.getFactory().newElement(target));
+ targets.add(element);
+ }
+ }
+ return (this.targets = Collections.unmodifiableList(targets));
+ }
+ }
+
+ class ExportsDirectiveImpl extends PackageDirectiveImpl implements ModuleElement.ExportsDirective {
+
+ ExportsDirectiveImpl(PackageBinding pBinding) {
+ super(pBinding);
+ }
+
+ @Override
+ public <R, P> R accept(DirectiveVisitor<R, P> visitor, P param) {
+ return visitor.visit(this);
+ }
+
+ @Override
+ public javax.lang.model.element.ModuleElement.DirectiveKind getKind() {
+ return DirectiveKind.EXPORTS;
+ }
+
+ @Override
+ public PackageElement getPackage() {
+ return _env.getFactory().newPackageElement(binding);
+ }
+ @Override
+ public List<? extends ModuleElement> getTargetModules() {
+ if(this.targets != null) {
+ return targets;
+ }
+ return getTargetModules(ModuleElementImpl.this.binding.getExportRestrictions(this.binding));
+ }
+
+ }
+
+ class RequiresDirectiveImpl implements ModuleElement.RequiresDirective {
+ ModuleBinding dependency;
+ boolean transitive;
+
+ RequiresDirectiveImpl(ModuleBinding dependency, boolean transitive) {
+ this.dependency = dependency;
+ this.transitive = transitive;
+ }
+
+ @Override
+ public <R, P> R accept(DirectiveVisitor<R, P> visitor, P param) {
+ return visitor.visit(this);
+ }
+
+ @Override
+ public javax.lang.model.element.ModuleElement.DirectiveKind getKind() {
+ return DirectiveKind.REQUIRES;
+ }
+
+ @Override
+ public ModuleElement getDependency() {
+ return (ModuleElement) _env.getFactory().newElement(dependency, ElementKind.MODULE);
+ }
+
+ @Override
+ public boolean isStatic() {
+ // TODO: Yet to see this in ModuleBinding. Check again.
+ return false;
+ }
+
+ @Override
+ public boolean isTransitive() {
+ return this.transitive;
+ }
+ }
+
+ class OpensDirectiveImpl extends PackageDirectiveImpl implements ModuleElement.OpensDirective {
+
+ OpensDirectiveImpl(PackageBinding pBinding) {
+ super(pBinding);
+ }
+
+ @Override
+ public <R, P> R accept(DirectiveVisitor<R, P> visitor, P param) {
+ return visitor.visit(this);
+ }
+
+ @Override
+ public javax.lang.model.element.ModuleElement.DirectiveKind getKind() {
+ return DirectiveKind.OPENS;
+ }
+ @Override
+ public List<? extends ModuleElement> getTargetModules() {
+ if(this.targets != null) {
+ return targets;
+ }
+ return getTargetModules(ModuleElementImpl.this.binding.getOpenRestrictions(this.binding));
+ }
+ }
+
+ class UsesDirectiveImpl implements ModuleElement.UsesDirective {
+ TypeBinding binding = null;
+
+ UsesDirectiveImpl(TypeBinding binding) {
+ this.binding = binding;
+ }
+
+ @Override
+ public <R, P> R accept(DirectiveVisitor<R, P> visitor, P param) {
+ return visitor.visit(this);
+ }
+
+ @Override
+ public DirectiveKind getKind() {
+ return DirectiveKind.USES;
+ }
+
+ @Override
+ public TypeElement getService() {
+ return (TypeElement) _env.getFactory().newElement(binding);
+ }
+
+ }
+
+ class ProvidesDirectiveImpl implements ModuleElement.ProvidesDirective {
+
+ TypeBinding service;
+ public List<? extends TypeElement> implementations;
+
+ ProvidesDirectiveImpl(TypeBinding service) {
+ this.service = service;
+ }
+
+ @Override
+ public <R, P> R accept(DirectiveVisitor<R, P> visitor, P param) {
+ return visitor.visit(this);
+ }
+
+ @Override
+ public DirectiveKind getKind() {
+ return DirectiveKind.PROVIDES;
+ }
+
+ @Override
+ public List<? extends TypeElement> getImplementations() {
+ if (this.implementations != null)
+ return this.implementations;
+
+ TypeBinding[] implementations2 = ModuleElementImpl.this.binding.getImplementations(this.service);
+ if (implementations2.length == 0) {
+ return (this.implementations = Collections.emptyList());
+ }
+
+ List<TypeElement> list = new ArrayList<>(implementations2.length);
+ Factory factory = _env.getFactory();
+ for (TypeBinding type: implementations2) {
+ TypeElement element = (TypeElement) factory.newElement(type);
+ list.add(element);
+ }
+ return Collections.unmodifiableList(list);
+ }
+
+ @Override
+ public TypeElement getService() {
+ return (TypeElement) _env.getFactory().newElement(this.service);
+ }
+ }
+}
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/NoTypeImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/NoTypeImpl.java
index 2efe713c07..adc49321fb 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/NoTypeImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/NoTypeImpl.java
@@ -35,7 +35,7 @@ public class NoTypeImpl implements NoType, NullType
public static final NoType NO_TYPE_PACKAGE = new NoTypeImpl(TypeKind.PACKAGE);
public static final NullType NULL_TYPE = new NoTypeImpl(TypeKind.NULL);
- private NoTypeImpl(TypeKind kind) {
+ public NoTypeImpl(TypeKind kind) {
_kind = kind;
}
@@ -57,6 +57,7 @@ public class NoTypeImpl implements NoType, NullType
return _kind;
}
+ @Override
public String toString()
{
switch (_kind) {
@@ -69,17 +70,22 @@ public class NoTypeImpl implements NoType, NullType
return "void"; //$NON-NLS-1$
case PACKAGE:
return "package"; //$NON-NLS-1$
+ case MODULE:
+ return "module"; //$NON-NLS-1$
}
}
+ @Override
public List<? extends AnnotationMirror> getAnnotationMirrors() {
return Factory.EMPTY_ANNOTATION_MIRRORS;
}
+ @Override
public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
return null;
}
+ @Override
@SuppressWarnings("unchecked")
public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
return (A[]) Array.newInstance(annotationType, 0);
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/PackageElementImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/PackageElementImpl.java
index 99faca3fba..3d0d58b368 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/PackageElementImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/PackageElementImpl.java
@@ -34,6 +34,7 @@ import org.eclipse.jdt.internal.compiler.batch.FileSystem;
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
@@ -73,7 +74,7 @@ public class PackageElementImpl extends ElementImpl implements PackageElement {
char[][][] typeNames = null;
INameEnvironment nameEnvironment = binding.environment.nameEnvironment;
if (nameEnvironment instanceof FileSystem) {
- typeNames = ((FileSystem) nameEnvironment).findTypeNames(binding.compoundName, new String[] { null });
+ typeNames = ((FileSystem) nameEnvironment).findTypeNames(binding.compoundName);
}
HashSet<Element> set = new HashSet<>();
Set<ReferenceBinding> types = new HashSet<>();
@@ -87,11 +88,13 @@ public class PackageElementImpl extends ElementImpl implements PackageElement {
}
}
}
- ReferenceBinding[] knownTypes = binding.knownTypes.valueTable;
- for (ReferenceBinding referenceBinding : knownTypes) {
- if (referenceBinding != null && referenceBinding.isValidBinding() && referenceBinding.enclosingType() == null) {
- if (!types.contains(referenceBinding)) {
- set.add(_env.getFactory().newElement(referenceBinding));
+ if (binding.knownTypes != null) {
+ ReferenceBinding[] knownTypes = binding.knownTypes.valueTable;
+ for (ReferenceBinding referenceBinding : knownTypes) {
+ if (referenceBinding != null && referenceBinding.isValidBinding() && referenceBinding.enclosingType() == null) {
+ if (!types.contains(referenceBinding)) {
+ set.add(_env.getFactory().newElement(referenceBinding));
+ }
}
}
}
@@ -102,8 +105,11 @@ public class PackageElementImpl extends ElementImpl implements PackageElement {
@Override
public Element getEnclosingElement() {
- // packages have no enclosing element
- return null;
+ PackageBinding pBinding = (PackageBinding) _binding;
+ ModuleBinding module = pBinding.enclosingModule;
+ if (module == null)
+ return null;
+ return new ModuleElementImpl(_env, module);
}
@Override
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypeElementImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypeElementImpl.java
index 5b9961b49e..cf44e9bcf3 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypeElementImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypeElementImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2015 IBM Corporation and others.
+ * Copyright (c) 2005, 2017 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
@@ -41,7 +41,6 @@ import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
-import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
@@ -263,7 +262,7 @@ public class TypeElementImpl extends ElementImpl implements TypeElement {
PackageElement getPackage()
{
ReferenceBinding binding = (ReferenceBinding)_binding;
- return _env.getFactory().newPackageElement((PackageBinding)binding.fPackage);
+ return _env.getFactory().newPackageElement(binding.fPackage);
}
@Override
diff --git a/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/AllTests.java b/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/AllTests.java
index a2eb0102f8..7713e6ef1d 100644
--- a/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/AllTests.java
+++ b/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/AllTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2008 IBM Corporation and others.
+ * Copyright (c) 2006, 2017 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
@@ -22,6 +22,7 @@ public class AllTests extends TestCase {
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite(CompilerToolTests.class);
+ suite.addTestSuite(CompilerToolJava9Tests.class);
suite.addTest(CompilerInvocationTests.suite());
return suite;
}
diff --git a/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerToolJava9Tests.java b/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerToolJava9Tests.java
index 64ca57c69e..90b8652835 100644
--- a/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerToolJava9Tests.java
+++ b/org.eclipse.jdt.compiler.tool.tests/src/org/eclipse/jdt/compiler/tool/tests/CompilerToolJava9Tests.java
@@ -59,6 +59,8 @@ public class CompilerToolJava9Tests extends TestCase {
@Override
protected void setUp() throws Exception {
this.isJREBelow9 = SourceVersion.latest().compareTo(SourceVersion.RELEASE_8) <= 0;
+ if (isJREBelow9)
+ return;
this.compilers = new JavaCompiler[2];
this.compilerNames = new String[2];
ServiceLoader<JavaCompiler> javaCompilerLoader = ServiceLoader.load(JavaCompiler.class);
diff --git a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java
index 74d59e83f9..97b00272f1 100644
--- a/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java
+++ b/org.eclipse.jdt.compiler.tool/src/org/eclipse/jdt/internal/compiler/tool/EclipseCompilerImpl.java
@@ -419,10 +419,7 @@ public class EclipseCompilerImpl extends Main {
location = StandardLocation.CLASS_OUTPUT;
} else {
// TODO: Still possible to end up with a non-null module name without JDK 9 in build path
- System.out.println("module name:" + new String(modName)); //$NON-NLS-1$
- System.out.println("CU:" + new String(unitResult.compilationUnit.getFileName())); //$NON-NLS-1$
location = this.fileManager.getLocationForModule(StandardLocation.CLASS_OUTPUT, new String(modName));
- System.out.println("Location from getLocationForModule(): " + location); //$NON-NLS-1$
}
JavaFileObject javaFileForOutput =
this.fileManager.getJavaFileForOutput(
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
index be8bbb7683..53ea550d9a 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java
@@ -53,7 +53,6 @@ import org.eclipse.jdt.internal.compiler.util.JRTUtil;
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
import org.eclipse.jdt.internal.compiler.util.Util;
-@SuppressWarnings({ "rawtypes", "unchecked" })
public class FileSystem implements IModuleAwareNameEnvironment, SuffixConstants {
// Keep the type as ArrayList and not List as there are clients that are already written to expect ArrayList.
@@ -143,11 +142,11 @@ public class FileSystem implements IModuleAwareNameEnvironment, SuffixConstants
* @param classpaths the given classpath entries
* @return the normalized classpath entries
*/
- public static ArrayList normalize(ArrayList classpaths) {
- ArrayList normalizedClasspath = new ArrayList();
- HashSet cache = new HashSet();
- for (Iterator iterator = classpaths.iterator(); iterator.hasNext(); ) {
- FileSystem.Classpath classpath = (FileSystem.Classpath) iterator.next();
+ public static ArrayList<Classpath> normalize(ArrayList<Classpath> classpaths) {
+ ArrayList<Classpath> normalizedClasspath = new ArrayList<>();
+ HashSet<Classpath> cache = new HashSet<>();
+ for (Iterator<Classpath> iterator = classpaths.iterator(); iterator.hasNext(); ) {
+ FileSystem.Classpath classpath = iterator.next();
if (!cache.contains(classpath)) {
normalizedClasspath.add(classpath);
cache.add(classpath);
@@ -161,7 +160,7 @@ public class FileSystem implements IModuleAwareNameEnvironment, SuffixConstants
// Used only in single-module mode when the module descriptor is
// provided via command line.
protected IModule module;
- Set knownFileNames;
+ Set<String> knownFileNames;
protected boolean annotationsFromClasspath; // should annotation files be read from the classpath (vs. explicit separate path)?
private static HashMap<File, Classpath> JRT_CLASSPATH_CACHE = null;
@@ -220,15 +219,15 @@ protected FileSystem(Classpath[] paths, String[] initialFileNames, boolean annot
public static Classpath getClasspath(String classpathName, String encoding, AccessRuleSet accessRuleSet) {
return getClasspath(classpathName, encoding, false, accessRuleSet, null, null);
}
-public static Classpath getClasspath(String classpathName, String encoding, AccessRuleSet accessRuleSet, Map options) {
+public static Classpath getClasspath(String classpathName, String encoding, AccessRuleSet accessRuleSet, Map<String, String> options) {
return getClasspath(classpathName, encoding, false, accessRuleSet, null, options);
}
-public static Classpath getJrtClasspath(String jdkHome, String encoding, AccessRuleSet accessRuleSet, Map options) {
+public static Classpath getJrtClasspath(String jdkHome, String encoding, AccessRuleSet accessRuleSet, Map<String, String> options) {
return new ClasspathJrt(new File(convertPathSeparators(jdkHome)), true, accessRuleSet, null);
}
public static Classpath getClasspath(String classpathName, String encoding,
boolean isSourceOnly, AccessRuleSet accessRuleSet,
- String destinationPath, Map options) {
+ String destinationPath, Map<String, String> options) {
Classpath result = null;
File file = new File(convertPathSeparators(classpathName));
if (file.isDirectory()) {
@@ -281,10 +280,10 @@ public static Classpath getClasspath(String classpathName, String encoding,
}
private void initializeKnownFileNames(String[] initialFileNames) {
if (initialFileNames == null) {
- this.knownFileNames = new HashSet(0);
+ this.knownFileNames = new HashSet<>(0);
return;
}
- this.knownFileNames = new HashSet(initialFileNames.length * 2);
+ this.knownFileNames = new HashSet<>(initialFileNames.length * 2);
for (int i = initialFileNames.length; --i >= 0;) {
File compilationUnitFile = new File(initialFileNames[i]);
char[] fileName = null;
@@ -455,48 +454,42 @@ public NameEnvironmentAnswer findType(char[][] compoundName, char[] moduleName)
moduleName);
return null;
}
-public char[][][] findTypeNames(char[][] packageName, String[] moduleNames) {
+public char[][][] findTypeNames(char[][] packageName) {
char[][][] result = null;
if (packageName != null) {
String qualifiedPackageName = new String(CharOperation.concatWith(packageName, '/'));
String qualifiedPackageName2 = File.separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName.replace('/', File.separatorChar);
if (qualifiedPackageName == qualifiedPackageName2) {
for (int i = 0, length = this.classpaths.length; i < length; i++) {
- for (String moduleName : moduleNames) {
- if (moduleName != null && !this.classpaths[i].servesModule(moduleName.toCharArray())) continue;
- char[][][] answers = this.classpaths[i].findTypeNames(qualifiedPackageName, moduleName);
- if (answers != null) {
- // concat with previous answers
- if (result == null) {
- result = answers;
- } else {
- int resultLength = result.length;
- int answersLength = answers.length;
- System.arraycopy(result, 0, (result = new char[answersLength + resultLength][][]), 0, resultLength);
- System.arraycopy(answers, 0, result, resultLength, answersLength);
- }
+ char[][][] answers = this.classpaths[i].findTypeNames(qualifiedPackageName, null);
+ if (answers != null) {
+ // concat with previous answers
+ if (result == null) {
+ result = answers;
+ } else {
+ int resultLength = result.length;
+ int answersLength = answers.length;
+ System.arraycopy(result, 0, (result = new char[answersLength + resultLength][][]), 0, resultLength);
+ System.arraycopy(answers, 0, result, resultLength, answersLength);
}
}
}
} else {
for (int i = 0, length = this.classpaths.length; i < length; i++) {
Classpath p = this.classpaths[i];
- for (String moduleName : moduleNames) {
- if (moduleName != null && !p.servesModule(moduleName.toCharArray())) continue;
- char[][][] answers = (p instanceof ClasspathJar)
- ? p.findTypeNames(qualifiedPackageName, moduleName)
- : p.findTypeNames(qualifiedPackageName2, moduleName);
- if (answers != null) {
- // concat with previous answers
- if (result == null) {
- result = answers;
- } else {
- int resultLength = result.length;
- int answersLength = answers.length;
- System.arraycopy(result, 0, (result = new char[answersLength + resultLength][][]), 0, resultLength);
- System.arraycopy(answers, 0, result, resultLength, answersLength);
- }
- }
+ char[][][] answers = !(p instanceof ClasspathDirectory) ? p.findTypeNames(qualifiedPackageName, null)
+ : p.findTypeNames(qualifiedPackageName2, null);
+ if (answers != null) {
+ // concat with previous answers
+ if (result == null) {
+ result = answers;
+ } else {
+ int resultLength = result.length;
+ int answersLength = answers.length;
+ System.arraycopy(result, 0, (result = new char[answersLength + resultLength][][]), 0,
+ resultLength);
+ System.arraycopy(answers, 0, result, resultLength, answersLength);
+ }
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java
index b77408d7af..445cc71d5f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java
@@ -1,10 +1,14 @@
/*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2017 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
*
+ * This is an implementation of an early-draft specification developed under the Java
+ * Community Process (JCP) and is made available for testing and evaluation purposes
+ * only. The code is not compatible with any specification of the JCP.
+ *
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
@@ -584,6 +588,9 @@ public abstract class ASTVisitor {
public boolean visit(Clinit clinit, ClassScope scope) {
return true; // do nothing by default, keep traversing
}
+ public boolean visit(ModuleDeclaration module, CompilationUnitScope scope) {
+ return true;
+ }
public boolean visit(
CompilationUnitDeclaration compilationUnitDeclaration,
CompilationUnitScope scope) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
index 5170e45524..d42e057215 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java
@@ -783,6 +783,10 @@ public abstract class ASTNode implements TypeConstants, TypeIds {
ModuleBinding module = (ModuleBinding)recipient;
if ((module.tagBits & TagBits.AnnotationResolved) != 0) return annotations;
module.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
+ if (length > 0) {
+ annotations = new AnnotationBinding[length];
+ module.setAnnotations(annotations, scope);
+ }
break;
default :
return annotations;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
index cdc72064b6..0a1dfa4261 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
@@ -782,6 +782,9 @@ public void traverse(ASTVisitor visitor, CompilationUnitScope unitScope, boolean
this.types[i].traverse(visitor, this.scope);
}
}
+ if (this.isModuleInfo() && this.moduleDeclaration != null) {
+ this.moduleDeclaration.traverse(visitor, this.scope);
+ }
}
visitor.endVisit(this, this.scope);
} catch (AbortCompilationUnit e) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ModuleDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ModuleDeclaration.java
index 9d9a667a50..c9987b35a0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ModuleDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ModuleDeclaration.java
@@ -23,6 +23,7 @@ import java.util.Set;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
@@ -60,7 +61,7 @@ public class ModuleDeclaration extends ASTNode {
public int bodyStart;
public int bodyEnd; // doesn't include the trailing comment if any.
public int modifiersSourceStart;
- BlockScope scope;
+ public BlockScope scope;
public char[][] tokens;
public char[] moduleName;
public long[] sourcePositions;
@@ -68,6 +69,7 @@ public class ModuleDeclaration extends ASTNode {
boolean ignoreFurtherInvestigation;
boolean hasResolvedModuleDirectives;
boolean hasResolvedPackageDirectives;
+ boolean hasResolvedTypeDirectives;
CompilationResult compilationResult;
public ModuleDeclaration(CompilationResult compilationResult, char[][] tokens, long[] positions) {
@@ -224,6 +226,10 @@ public class ModuleDeclaration extends ASTNode {
this.ignoreFurtherInvestigation = true;
return;
}
+ if (this.hasResolvedTypeDirectives)
+ return;
+
+ this.hasResolvedTypeDirectives = true;
ASTNode.resolveAnnotations(this.scope, this.annotations, this.binding);
Set<TypeBinding> allTypes = new HashSet<TypeBinding>();
@@ -313,6 +319,10 @@ public class ModuleDeclaration extends ASTNode {
}
}
+ public void traverse(ASTVisitor visitor, CompilationUnitScope unitScope) {
+ visitor.visit(this, unitScope);
+ }
+
public StringBuffer printHeader(int indent, StringBuffer output) {
if (this.annotations != null) {
for (int i = 0; i < this.annotations.length; i++) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java
index 2d3eef175f..5b6a9bcc23 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotationBinding.java
@@ -157,6 +157,8 @@ private static AnnotationBinding buildTargetAnnotation(long bits, LookupEnvironm
if (arraysize > 0) {
ReferenceBinding elementType = env.getResolvedType(TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE, null);
int index = 0;
+ if ((bits & TagBits.AnnotationForTypeUse) != 0)
+ value[index++] = elementType.getField(TypeConstants.TYPE_USE_TARGET, true);
if ((bits & TagBits.AnnotationForAnnotationType) != 0)
value[index++] = elementType.getField(TypeConstants.UPPER_ANNOTATION_TYPE, true);
if ((bits & TagBits.AnnotationForConstructor) != 0)
@@ -169,8 +171,6 @@ private static AnnotationBinding buildTargetAnnotation(long bits, LookupEnvironm
value[index++] = elementType.getField(TypeConstants.UPPER_PACKAGE, true);
if ((bits & TagBits.AnnotationForParameter) != 0)
value[index++] = elementType.getField(TypeConstants.UPPER_PARAMETER, true);
- if ((bits & TagBits.AnnotationForTypeUse) != 0)
- value[index++] = elementType.getField(TypeConstants.TYPE_USE_TARGET, true);
if ((bits & TagBits.AnnotationForTypeParameter) != 0)
value[index++] = elementType.getField(TypeConstants.TYPE_PARAMETER_TARGET, true);
if ((bits & TagBits.AnnotationForType) != 0)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
index 23db9de1fb..792c7b90f5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
@@ -1316,9 +1316,11 @@ public class ClassScope extends Scope {
}
}
}
- if ((superType.tagBits & TagBits.BeginHierarchyCheck) == 0)
+ if ((superType.tagBits & TagBits.BeginHierarchyCheck) == 0) {
// ensure if this is a source superclass that it has already been checked
- ((SourceTypeBinding) superType).scope.connectTypeHierarchyWithoutMembers();
+ if (superType.isValidBinding() && !superType.isUnresolvedType())
+ ((SourceTypeBinding) superType).scope.connectTypeHierarchyWithoutMembers();
+ }
if ((superType.tagBits & TagBits.HierarchyHasProblems) != 0)
sourceType.tagBits |= TagBits.HierarchyHasProblems;
return false;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
index c95e3f15a6..22e32e42c4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -773,6 +773,11 @@ private PackageBinding computePackageFrom(char[][] constantPoolName, boolean isM
packageBinding = parent.addPackage(packageBinding, this.module, true);
}
}
+ if (packageBinding instanceof SplitPackageBinding) {
+ PackageBinding incarnation = ((SplitPackageBinding) packageBinding).getIncarnation(this.module);
+ if (incarnation != null)
+ packageBinding = incarnation;
+ }
return packageBinding;
}
@@ -1621,8 +1626,8 @@ public ReferenceBinding getType(char[][] compoundName, ModuleBinding mod) {
referenceBinding = (ReferenceBinding) BinaryTypeBinding.resolveType(referenceBinding, this, false /* no raw conversion for now */);
// compoundName refers to a nested type incorrectly (for example, package1.A$B)
- if (referenceBinding.isNestedType())
- return new ProblemReferenceBinding(compoundName, referenceBinding, InternalNameProvided);
+// if (referenceBinding.isNestedType())
+// return new ProblemReferenceBinding(compoundName, referenceBinding, InternalNameProvided);
return referenceBinding;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
index 9f2dc4b061..39cb8b0b11 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java
@@ -116,8 +116,13 @@ public class ModuleBinding extends Binding implements IUpdatableModule {
private Set<ModuleBinding> transitiveRequires;
private boolean isPackageLookupActive = false; // to prevent cyclic lookup caused by synthetic reads edges on behalf of auto-modules.
- /** Packages declared in this module (indexed by qualified name). */
- HashtableOfPackage declaredPackages; // TODO(SHMOD): measure if this is worth the memory. LE->PackageBinding basically hold the same information
+ /**
+ * Packages declared in this module (indexed by qualified name).
+ * We consider a package as declared in a module,
+ * if a compilation unit associated with the module
+ * declares the package or a subpackage thereof.
+ */
+ public HashtableOfPackage declaredPackages;
/** Constructor for the unnamed module. */
private ModuleBinding(LookupEnvironment env) {
@@ -469,7 +474,7 @@ public class ModuleBinding extends Binding implements IUpdatableModule {
* When asked via the unnamed module or an automatic module all other named modules are considered visible.
* </p>
*/
- PackageBinding getTopLevelPackage(char[] name) {
+ public PackageBinding getTopLevelPackage(char[] name) {
// check caches:
PackageBinding binding = this.declaredPackages.get(name);
if (binding != null)
@@ -593,7 +598,7 @@ public class ModuleBinding extends Binding implements IUpdatableModule {
* read by the current module.
* Accessibility (via package exports) is <strong>not</strong> checked.
*/
- PackageBinding getPackage(char[][] parentPackageName, char[] packageName) {
+ public PackageBinding getPackage(char[][] parentPackageName, char[] packageName) {
// Returns a package binding if there exists such a package in the context of this module and it is observable
// A package is observable if it is declared in this module or it is exported by some required module
if (parentPackageName == null || parentPackageName.length == 0) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceModuleBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceModuleBinding.java
index 693c968392..5f79a77f29 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceModuleBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceModuleBinding.java
@@ -19,9 +19,16 @@ import java.util.HashMap;
import java.util.function.IntFunction;
import java.util.stream.Stream;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
+import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
+
public class SourceModuleBinding extends ModuleBinding {
final public CompilationUnitScope scope; // TODO(SHMOD): consider cleanup at end of compile
+ private SimpleLookupTable storedAnnotations = null;
/**
* Construct a named module from source.
@@ -90,4 +97,73 @@ public class SourceModuleBinding extends ModuleBinding {
this.scope.referenceContext.moduleDeclaration.resolveModuleDirectives(this.scope);
return super.getAllRequiredModules();
}
+ public long getAnnotationTagBits() {
+ //TODO: This code is untested as we don't yet get a scope in ModuleBinding
+ if ((this.tagBits & TagBits.AnnotationResolved) == 0 && this.scope != null) {
+ ModuleDeclaration module = this.scope.referenceContext.moduleDeclaration;
+ ASTNode.resolveAnnotations(module.scope, module.annotations, this);
+ if ((this.tagBits & TagBits.AnnotationDeprecated) != 0) {
+ this.modifiers |= ClassFileConstants.AccDeprecated;
+ this.tagBits |= TagBits.DeprecatedAnnotationResolved;
+ }
+ this.tagBits |= TagBits.AnnotationResolved;
+ }
+ return this.tagBits;
+ }
+ public AnnotationBinding[] getAnnotations() {
+ return retrieveAnnotations(this);
+ }
+ public AnnotationHolder retrieveAnnotationHolder(Binding binding, boolean forceInitialization) {
+ SimpleLookupTable store = storedAnnotations(forceInitialization);
+ return store == null ? null : (AnnotationHolder) store.get(binding);
+ }
+
+ AnnotationBinding[] retrieveAnnotations(Binding binding) {
+ AnnotationHolder holder = retrieveAnnotationHolder(binding, true);
+ return holder == null ? Binding.NO_ANNOTATIONS : holder.getAnnotations();
+ }
+
+ public void setAnnotations(AnnotationBinding[] annotations) {
+ storeAnnotations(this, annotations);
+ }
+ void storeAnnotationHolder(Binding binding, AnnotationHolder holder) {
+ if (holder == null) {
+ SimpleLookupTable store = storedAnnotations(false);
+ if (store != null)
+ store.removeKey(binding);
+ } else {
+ SimpleLookupTable store = storedAnnotations(true);
+ if (store != null)
+ store.put(binding, holder);
+ }
+ }
+
+ void storeAnnotations(Binding binding, AnnotationBinding[] annotations) {
+ AnnotationHolder holder = null;
+ if (annotations == null || annotations.length == 0) {
+ SimpleLookupTable store = storedAnnotations(false);
+ if (store != null)
+ holder = (AnnotationHolder) store.get(binding);
+ if (holder == null) return; // nothing to delete
+ } else {
+ SimpleLookupTable store = storedAnnotations(true);
+ if (store == null) return; // not supported
+ holder = (AnnotationHolder) store.get(binding);
+ if (holder == null)
+ holder = new AnnotationHolder();
+ }
+ storeAnnotationHolder(binding, holder.setAnnotations(annotations));
+ }
+
+ SimpleLookupTable storedAnnotations(boolean forceInitialize) {
+ if (forceInitialize && this.storedAnnotations == null && this.scope != null) { // scope null when no annotation cached, and type got processed fully (159631)
+ this.scope.referenceCompilationUnit().compilationResult.hasAnnotations = true;
+ final CompilerOptions globalOptions = this.scope.environment().globalOptions;
+ if (!globalOptions.storeAnnotations)
+ return null; // not supported during this compile
+ this.storedAnnotations = new SimpleLookupTable(3);
+ }
+ return this.storedAnnotations;
+ }
+
}

Back to the top