Fix for Bug 516731: [9] DOM AST for (restricted) keywords in
ModuleDeclaration - open modifier changes
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java
index b7af7ac..b5b62e4 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter9Test.java
@@ -160,17 +160,18 @@
+ "}";
this.workingCopies[0] = getWorkingCopy(
"/Converter9/src/module-info.java", content);
-
+
CompilationUnit unit = (CompilationUnit) runConversion(AST_INTERNAL_JLS9, this.workingCopies[0], false/*no bindings*/);
ModuleDeclaration moduleDecl = unit.getModule();
-
+
+ assertFalse(moduleDecl.isOpen());
checkSourceRange(moduleDecl, content, content);
List<ModuleStatement> stmts = moduleDecl.moduleStatements();
assertTrue(stmts.size() > 0);
-
+
RequiresStatement req = (RequiresStatement) stmts.get(0);
checkSourceRange(req, "requires second;", content);
-
+
ExportsStatement exp = (ExportsStatement) stmts.get(1);
checkSourceRange(exp, "exports pack11 to third, fourth;", content);
checkSourceRange(exp.getName(), "pack11", content);
@@ -214,7 +215,7 @@
assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
CompilationUnit unit = (CompilationUnit) node;
ModuleDeclaration moduleDecl = unit.getModule();
-
+ assertFalse(moduleDecl.isOpen());
checkSourceRange(moduleDecl, content, content);
List<ModuleStatement> stmts = moduleDecl.moduleStatements();
assertTrue(stmts.size() > 0);
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingModuleDeclarationTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingModuleDeclarationTest.java
index 240e0d2..3885227 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingModuleDeclarationTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ASTRewritingModuleDeclarationTest.java
@@ -250,9 +250,60 @@
buf.append(" requires static transient module3;\n");
buf.append(" requires transient addedme;\n");
buf.append("}");
- assertEqualString(preview, buf.toString());
+ assertEqualString(preview, buf.toString());
} finally {
if (javaProject != null) deleteProject(javaProject);
}
}
+ public void testBug516731_0001_since_9() throws Exception {
+ IJavaProject javaProject = null;
+ try {
+ javaProject = createProject("P_9", JavaCore.VERSION_9);
+ IPackageFragmentRoot currentSourceFolder = getPackageFragmentRoot("P_9", "src");
+ IPackageFragment pack1= currentSourceFolder.getPackageFragment(Util.EMPTY_STRING);
+ StringBuffer buf= new StringBuffer();
+ buf.append("module first {\n");
+ buf.append(" requires existing;\n");
+ buf.append("}");
+ ICompilationUnit cu= pack1.createCompilationUnit("module-info.java", buf.toString(), false, null);
+ CompilationUnit astRoot= createAST(cu);
+ ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST());
+ ModuleDeclaration moduleDecl = astRoot.getModule();
+ rewrite.set(moduleDecl, ModuleDeclaration.OPEN_PROPERTY, Boolean.TRUE, null);
+ String preview= evaluateRewrite(cu, rewrite);
+ buf= new StringBuffer();
+ buf.append("open module first {\n");
+ buf.append(" requires existing;\n");
+ buf.append("}");
+ assertEqualString(preview, buf.toString());
+ } finally {
+ if (javaProject != null) deleteProject(javaProject);
+ }
+ }
+ public void testBug516731_0002_since_9() throws Exception {
+ IJavaProject javaProject = null;
+ try {
+ javaProject = createProject("P_9", JavaCore.VERSION_9);
+ IPackageFragmentRoot currentSourceFolder = getPackageFragmentRoot("P_9", "src");
+ IPackageFragment pack1= currentSourceFolder.getPackageFragment(Util.EMPTY_STRING);
+ StringBuffer buf= new StringBuffer();
+ buf.append("open module first {\n");
+ buf.append(" requires existing;\n");
+ buf.append("}");
+ ICompilationUnit cu= pack1.createCompilationUnit("module-info.java", buf.toString(), false, null);
+ CompilationUnit astRoot= createAST(cu);
+ ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST());
+ ModuleDeclaration moduleDecl = astRoot.getModule();
+ rewrite.set(moduleDecl, ModuleDeclaration.OPEN_PROPERTY, Boolean.FALSE, null);
+ String preview= evaluateRewrite(cu, rewrite);
+ buf= new StringBuffer();
+ buf.append("module first {\n");
+ buf.append(" requires existing;\n");
+ buf.append("}");
+ assertEqualString(preview, buf.toString());
+ } finally {
+ if (javaProject != null) deleteProject(javaProject);
+ }
+ }
+
}
\ No newline at end of file
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 7a2ff12..c474942 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
@@ -157,7 +157,7 @@
output.append(CharOperation.charToString(this.moduleName));
return output;
}
- private boolean isOpen() {
+ public boolean isOpen() {
return (this.modifiers & ClassFileConstants.ACC_OPEN) != 0;
}
public StringBuffer printBody(int indent, StringBuffer output) {
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
index ca150ed..c8b2568 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java
@@ -3302,7 +3302,8 @@
ModuleDeclaration moduleDecl = this.ast.newModuleDeclaration();
// TODO
//convert(moduleDeclaration.javadoc, moduleDecl);
- setModifiers(moduleDecl, moduleDeclaration);
+ setAnnotations(moduleDecl, moduleDeclaration); // only annotations
+ moduleDecl.setOpen(moduleDeclaration.isOpen());
Name moduleName = getName(moduleDeclaration, CharOperation.splitOn('.', moduleDeclaration.moduleName), moduleDeclaration.sourcePositions);
moduleDecl.setName(moduleName);
moduleDecl.setSourceRange(moduleDeclaration.declarationSourceStart, moduleDeclaration.declarationSourceEnd - moduleDeclaration.declarationSourceStart + 1);
@@ -5287,9 +5288,9 @@
}
}
- protected void setModifiers(ModuleDeclaration moduleDecl, org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration moduleDeclaration) {
+ protected void setAnnotations(ModuleDeclaration moduleDecl, org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration moduleDeclaration) {
this.scanner.resetTo(moduleDeclaration.declarationSourceStart, moduleDeclaration.sourceStart);
- this.setModifiers(moduleDecl.modifiers(), moduleDeclaration.annotations, moduleDeclaration.sourceStart);
+ this.setModifiers(moduleDecl.annotations(), moduleDeclaration.annotations, moduleDeclaration.sourceStart);
}
/**
* @param variableDecl
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java
index 6eaac1d..73f39bb 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java
@@ -1591,7 +1591,8 @@
}
ModuleDeclaration o = (ModuleDeclaration) other;
return (safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
- && safeSubtreeListMatch(node.modifiers(), o.modifiers())
+ && safeSubtreeListMatch(node.annotations(), o.annotations())
+ && node.isOpen() == o.isOpen()
&& safeSubtreeMatch(node.getName(), o.getName())
&& safeSubtreeListMatch(node.moduleStatements(), o.moduleStatements()));
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ModuleDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ModuleDeclaration.java
index e4d2afc..80c3cf6 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ModuleDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ModuleDeclaration.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016 IBM Corporation and others.
+ * 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
@@ -14,7 +14,6 @@
package org.eclipse.jdt.core.dom;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
/**
@@ -22,7 +21,7 @@
*
* <pre>
* ModuleDeclaration:
- * [ Javadoc ] { ExtendedModifier } <b>module</b> Name <b>{</b>
+ * [ Javadoc ] { Annotation } [ <b>open</b> ] <b>module</b> Name <b>{</b>
* [ ExportsStatement | OpensStatement | RequiresStatement | UsesStatement | ProvidesStatement ]
* <b>}</b>
* </pre>
@@ -30,7 +29,7 @@
* </p>
*
* @since 3.13 BETA_JAVA9
- *
+ *
* @noextend This class is not intended to be subclassed by clients.
* @noinstantiate This class is not intended to be instantiated by clients.
*/
@@ -44,10 +43,17 @@
new ChildPropertyDescriptor(ModuleDeclaration.class, "javadoc", Javadoc.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
/**
- * The "modifiers" structural property of this node type (element type: {@link IExtendedModifier}).
+ * The "annotations" structural property of this node type (element type: {@link Annotation}).
*/
- public static final ChildListPropertyDescriptor MODIFIERS_PROPERTY =
- new ChildListPropertyDescriptor(ModuleDeclaration.class, "modifiers", IExtendedModifier.class, CYCLE_RISK); //$NON-NLS-1$
+ public static final ChildListPropertyDescriptor ANNOTATIONS_PROPERTY =
+ new ChildListPropertyDescriptor(ModuleDeclaration.class, "annotations", Annotation.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+
+ /**
+ * The "open" structural property of this node type (type: {@link Boolean}).
+ */
+ public static final SimplePropertyDescriptor OPEN_PROPERTY =
+ new SimplePropertyDescriptor(ModuleDeclaration.class, "open", boolean.class, MANDATORY); //$NON-NLS-1$
/**
* The "name" structural property of this node type (child type: {@link Name}).
@@ -69,10 +75,11 @@
private static final List PROPERTY_DESCRIPTORS_9_0;
static {
- List properyList = new ArrayList(5);
+ List properyList = new ArrayList(6);
createPropertyList(ModuleDeclaration.class, properyList);
addProperty(JAVADOC_PROPERTY, properyList);
- addProperty(MODIFIERS_PROPERTY, properyList);
+ addProperty(ANNOTATIONS_PROPERTY, properyList);
+ addProperty(OPEN_PROPERTY, properyList);
addProperty(NAME_PROPERTY, properyList);
addProperty(MODULE_STATEMENTS_PROPERTY, properyList);
PROPERTY_DESCRIPTORS_9_0 = reapPropertyList(properyList);
@@ -99,12 +106,16 @@
private Javadoc optionalDocComment = null;
/**
- * The extended modifiers (element type: {@link IExtendedModifier}).
+ * The extended annotations (element type: {@link Annotation}).
* defaults to an empty list
- * (see constructor).
*
*/
- private ASTNode.NodeList modifiers = null;
+ private ASTNode.NodeList annotations = new ASTNode.NodeList(ANNOTATIONS_PROPERTY);
+
+ /**
+ * open versus normal; defaults to normal module.
+ */
+ private boolean isOpen = false;
/**
* The referenced module name; lazily initialized; defaults to a unspecified,
@@ -121,7 +132,6 @@
ModuleDeclaration(AST ast) {
super(ast);
unsupportedBelow9();
- this.modifiers = new ASTNode.NodeList(MODIFIERS_PROPERTY);
}
@Override
@@ -132,6 +142,21 @@
/* (omit javadoc for this method)
* Method declared on ASTNode.
*/
+ final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) {
+ if (property == OPEN_PROPERTY) {
+ if (get) {
+ return isOpen();
+ } else {
+ setOpen(value);
+ return false;
+ }
+ }
+ // allow default implementation to flag the error
+ return super.internalGetSetBooleanProperty(property, get, value);
+ }
+ /* (omit javadoc for this method)
+ * Method declared on ASTNode.
+ */
final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
if (property == JAVADOC_PROPERTY) {
if (get) {
@@ -157,8 +182,8 @@
* Method declared on ASTNode.
*/
final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
- if (property == MODIFIERS_PROPERTY) {
- return modifiers();
+ if (property == ANNOTATIONS_PROPERTY) {
+ return annotations();
}
if (property == MODULE_STATEMENTS_PROPERTY) {
return moduleStatements();
@@ -178,7 +203,8 @@
ModuleDeclaration result = new ModuleDeclaration(target);
result.setSourceRange(getStartPosition(), getLength());
result.setJavadoc((Javadoc) ASTNode.copySubtree(target, getJavadoc()));
- result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
+ result.setOpen(isOpen());
+ result.annotations().addAll(ASTNode.copySubtrees(target, annotations()));
result.setName((SimpleName) getName().clone(target));
result.moduleStatements().addAll(ASTNode.copySubtrees(target, moduleStatements()));
return result;
@@ -196,7 +222,7 @@
if (visitChildren) {
// visit children in normal left to right reading order
acceptChild(visitor, getJavadoc());
- acceptChildren(visitor, this.modifiers);
+ acceptChildren(visitor, this.annotations);
acceptChild(visitor, getName());
acceptChildren(visitor, this.moduleStatements);
}
@@ -227,27 +253,25 @@
}
/**
- * Returns the modifiers explicitly specified on this declaration.
- * <p>
- * this method is a convenience method that
- * computes these flags from {@link #modifiers()}.
- * </p>
+ * Returns whether this module declaration is open or not
*
- * @return the bit-wise "or" of <code>Modifier</code> constants
- * @see Modifier
+ * @return <code>true</code> if this is open, else
+ * <code>false</code>
*/
- public int getModifiers() {
- // convenience method -
- // performance could be improved by caching computed flags
- // but this would require tracking changes to this.modifiers
- int computedmodifierFlags = Modifier.NONE;
- for (Iterator it = modifiers().iterator(); it.hasNext(); ) {
- Object x = it.next();
- if (x instanceof Modifier) {
- computedmodifierFlags |= ((Modifier) x).getKeyword().toFlagValue();
- }
- }
- return computedmodifierFlags;
+ public boolean isOpen() {
+ return this.isOpen;
+ }
+
+ /**
+ * Sets whether this module declaration is open or not
+ *
+ * @param isOpen <code>true</code> if this is open module,
+ * and <code>false</code> if not
+ */
+ public void setOpen(boolean isOpen) {
+ preValueChange(OPEN_PROPERTY);
+ this.isOpen = isOpen;
+ postValueChange(OPEN_PROPERTY);
}
/**
@@ -291,14 +315,14 @@
}
/**
- * Returns the live ordered list of modifiers and annotations
+ * Returns the live ordered list of annotations
* of this declaration.
*
- * @return the live list of modifiers and annotations
- * (element type: {@link IExtendedModifier})
+ * @return the live list of annotations
+ * (element type: {@link Annotation})
*/
- public List modifiers() {
- return this.modifiers;
+ public List annotations() {
+ return this.annotations;
}
/**
@@ -317,14 +341,14 @@
@Override
int memSize() {
- return BASE_NODE_SIZE + 4 * 4;
+ return BASE_NODE_SIZE + 5 * 4;
}
@Override
int treeSize() {
return memSize()
+ (this.optionalDocComment == null ? 0 : getJavadoc().treeSize())
- + this.modifiers.listSize()
+ + this.annotations.listSize()
+ (this.name == null ? 0 : getName().treeSize())
+ this.moduleStatements.listSize();
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java
index 1422c1b..f6fba1f 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java
@@ -1234,7 +1234,9 @@
if (node.getJavadoc() != null) {
node.getJavadoc().accept(this);
}
- printModifiers(node.modifiers());
+ printModifiers(node.annotations());
+ if (node.isOpen())
+ this.buffer.append("open "); //$NON-NLS-1$
this.buffer.append("module"); //$NON-NLS-1$
this.buffer.append(" "); //$NON-NLS-1$
node.getName().accept(this);
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
index f96ca35..76df944 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
@@ -2088,13 +2088,34 @@
return doVisitUnchangedChildren(node);
}
int pos= rewriteJavadoc(node, ModuleDeclaration.JAVADOC_PROPERTY);
- pos= rewriteModifiers2(node, ModuleDeclaration.MODIFIERS_PROPERTY, pos);
+ pos= rewriteModifiers2(node, ModuleDeclaration.ANNOTATIONS_PROPERTY, pos);
+
+ RewriteEvent event= getEvent(node, ModuleDeclaration.OPEN_PROPERTY);
+ if (event != null && event.getChangeKind() != RewriteEvent.UNCHANGED) {
+ boolean fakeInModule = getScanner().getScanner().fakeInModule;
+ try {
+ boolean wasOpen= ((Boolean) event.getOriginalValue()).booleanValue();
+ if (wasOpen) {
+ this.tokenScanner.getScanner().fakeInModule = true;
+ int endPos= getScanner().getTokenStartOffset(TerminalTokens.TokenNamemodule, pos);
+ doTextRemove(pos, endPos - pos, getEditGroup(event));
+ } else {
+ doTextInsert(pos, "open ", getEditGroup(event)); //$NON-NLS-1$
+ }
+ } catch (CoreException e) {
+ handleException(e);
+ } finally {
+ this.tokenScanner.getScanner().fakeInModule = fakeInModule;
+ }
+ }
+
pos= rewriteRequiredNode(node, ModuleDeclaration.NAME_PROPERTY);
int startPos = getPosAfterLeftBrace(pos);
int startIndent= getIndent(node.getStartPosition()) + 1;
+ boolean fakeInModule = this.tokenScanner.getScanner().fakeInModule;
this.tokenScanner.getScanner().fakeInModule = true;
rewriteParagraphList(node, ModuleDeclaration.MODULE_STATEMENTS_PROPERTY, startPos, startIndent, 0, 1);
- this.tokenScanner.getScanner().fakeInModule = false;
+ this.tokenScanner.getScanner().fakeInModule = fakeInModule;
return false;
}
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
index 6850a42..35d8f27 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java
@@ -804,7 +804,10 @@
if (javadoc != null) {
javadoc.accept(this);
}
- visitList(node, ModuleDeclaration.MODIFIERS_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+ visitList(node, ModuleDeclaration.ANNOTATIONS_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+ if (getBooleanAttribute(node, ModuleDeclaration.OPEN_PROPERTY)) {
+ this.result.append("open ");//$NON-NLS-1$
+ }
this.result.append("module "); //$NON-NLS-1$
getChildNode(node, ModuleDeclaration.NAME_PROPERTY).accept(this);
this.result.append('{');