Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSarika Sinha2019-11-28 04:46:43 +0000
committerSarika Sinha2019-12-07 12:17:16 +0000
commitccf6e4b85f958e25ff2d828d9211acab530a13f4 (patch)
tree5a2ac89e73292d7b6a62a15e29692e60746f3df5
parentd3c7714097800c956772f7fe7fcfc69bd1ebb975 (diff)
downloadeclipse.jdt.core-ccf6e4b85f958e25ff2d828d9211acab530a13f4.tar.gz
eclipse.jdt.core-ccf6e4b85f958e25ff2d828d9211acab530a13f4.tar.xz
eclipse.jdt.core-ccf6e4b85f958e25ff2d828d9211acab530a13f4.zip
Bug 553154 - [14] Records - DOM AST SupportY20191208-2315I20191209-1110
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTStructuralPropertyTest.java8
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java3
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java12
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java48
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTMatcher.java38
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java11
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java37
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java29
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java25
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodDeclaration.java118
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecordDeclaration.java464
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/NaiveASTFlattener.java45
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteFlattener.java20
-rw-r--r--org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/util/DOMASTUtil.java95
14 files changed, 946 insertions, 7 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTStructuralPropertyTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTStructuralPropertyTest.java
index 9158ad630e..5f87d7c2cf 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTStructuralPropertyTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTStructuralPropertyTest.java
@@ -8,6 +8,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*
+ * 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
*******************************************************************************/
@@ -356,7 +360,7 @@ public class ASTStructuralPropertyTest extends org.eclipse.jdt.core.tests.junit.
}
public void testNodeClassForType() {
- Set classes = new HashSet(100);
+ Set classes = new HashSet(103);
// make sure node types are contiguous starting at 0
int hi = 0;
for (int nodeType = 1; nodeType < 110; nodeType++) {
@@ -372,7 +376,7 @@ public class ASTStructuralPropertyTest extends org.eclipse.jdt.core.tests.junit.
// oops - guess that's not valid
}
}
- assertEquals("Wrong last known type", 102, hi); // last known one
+ assertEquals("Wrong last known type", 103, hi); // last known one
assertEquals("Wrong number of distinct types", hi, classes.size()); // all classes are distinct
}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java
index fd7bedc9eb..a63d7e2d68 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTTest.java
@@ -8897,7 +8897,8 @@ public class ASTTest extends org.eclipse.jdt.core.tests.junit.extension.TestCase
ASTNode.MODULE_MODIFIER,
ASTNode.SWITCH_EXPRESSION,
ASTNode.YIELD_STATEMENT,
- ASTNode.TEXT_BLOCK
+ ASTNode.TEXT_BLOCK,
+ ASTNode.RECORD_DECLARATION
};
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
index c42131b458..1723c65997 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/AST.java
@@ -818,6 +818,7 @@ public final class AST {
int apiLevel;
private boolean previewEnabled;
+
/**
* Tag bit value. This represents internal state of the tree.
*/
@@ -3638,6 +3639,17 @@ public final class AST {
throw new UnsupportedOperationException("Operation not supported in JLS2 AST"); //$NON-NLS-1$
}
}
+
+
+ /**
+ *
+ * @return If previewEnabled flag is set to <code>true</true>, return <code>true</code> else <code>false</code>
+ * @since 3.20 BETA_JAVA
+ * @noreference This method is not intended to be referenced by clients.
+ */
+ public boolean isPreviewEnabledSet() {
+ return this.previewEnabled;
+ }
/**
*
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 65818bf183..1bdd4d5402 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
@@ -41,6 +41,7 @@ import org.eclipse.jdt.core.dom.ModuleModifier.ModuleModifierKeyword;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.CompactConstructorDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
import org.eclipse.jdt.internal.compiler.ast.IntersectionCastTypeReference;
@@ -74,6 +75,7 @@ import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner;
import org.eclipse.jdt.internal.compiler.parser.Scanner;
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
import org.eclipse.jdt.internal.core.dom.SourceRangeVerifier;
+import org.eclipse.jdt.internal.core.dom.util.DOMASTUtil;
import org.eclipse.jdt.internal.core.util.Util;
/**
@@ -525,6 +527,9 @@ class ASTConverter {
setModifiers(methodDecl, methodDeclaration);
boolean isConstructor = methodDeclaration.isConstructor();
methodDecl.setConstructor(isConstructor);
+ if (DOMASTUtil.isRecordDeclarationSupported(this.ast)) {
+ methodDecl.setCompactConstructor(methodDeclaration instanceof CompactConstructorDeclaration);
+ }
final SimpleName methodName = new SimpleName(this.ast);
methodName.internalSetIdentifier(new String(methodDeclaration.selector));
int start = methodDeclaration.sourceStart;
@@ -3061,6 +3066,12 @@ class ASTConverter {
} else {
return convertToAnnotationDeclaration(typeDeclaration);
}
+ case org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.RECORD_DECL :
+ if (!DOMASTUtil.isRecordDeclarationSupported(this.ast)) {
+ return null;
+ } else {
+ return convertToRecordDeclaration(typeDeclaration);
+ }
}
checkCanceled();
@@ -3375,6 +3386,38 @@ class ASTConverter {
}
return enumDeclaration2;
}
+
+ private RecordDeclaration convertToRecordDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration) {
+ checkCanceled();
+ // record declaration cannot be built if the source is not >= 14, since record is then seen as an identifier
+ final RecordDeclaration recordDeclaration = new RecordDeclaration(this.ast);
+ setModifiers(recordDeclaration, typeDeclaration);
+ final SimpleName typeName = new SimpleName(this.ast);
+ typeName.internalSetIdentifier(new String(typeDeclaration.name));
+ typeName.setSourceRange(typeDeclaration.sourceStart, typeDeclaration.sourceEnd - typeDeclaration.sourceStart + 1);
+ recordDeclaration.setName(typeName);
+ recordDeclaration.setSourceRange(typeDeclaration.declarationSourceStart, typeDeclaration.bodyEnd - typeDeclaration.declarationSourceStart + 1);
+
+ org.eclipse.jdt.internal.compiler.ast.TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
+ if (superInterfaces != null) {
+ for (int index = 0, length = superInterfaces.length; index < length; index++) {
+ recordDeclaration.superInterfaceTypes().add(convertType(superInterfaces[index]));
+ }
+ }
+ org.eclipse.jdt.internal.compiler.ast.TypeParameter[] typeParameters = typeDeclaration.typeParameters;
+ if (typeParameters != null) {
+ for (int index = 0, length = typeParameters.length; index < length; index++) {
+ recordDeclaration.typeParameters().add(convert(typeParameters[index]));
+ }
+ }
+ buildBodyDeclarations(typeDeclaration, recordDeclaration, false);
+ if (this.resolveBindings) {
+ recordNodes(recordDeclaration, typeDeclaration);
+ recordNodes(typeName, typeDeclaration);
+ recordDeclaration.resolveBinding();
+ }
+ return recordDeclaration;
+ }
public Expression convertToExpression(org.eclipse.jdt.internal.compiler.ast.Statement statement) {
if (statement instanceof org.eclipse.jdt.internal.compiler.ast.Expression &&
((org.eclipse.jdt.internal.compiler.ast.Expression) statement).isTrulyExpression()) {
@@ -5390,6 +5433,11 @@ class ASTConverter {
this.scanner.resetTo(enumDeclaration2.declarationSourceStart, enumDeclaration2.sourceStart);
this.setModifiers(enumDeclaration, enumDeclaration2.annotations, enumDeclaration2.sourceStart);
}
+
+ protected void setModifiers(RecordDeclaration recordDeclaration, org.eclipse.jdt.internal.compiler.ast.TypeDeclaration recordDeclaration2) {
+ this.scanner.resetTo(recordDeclaration2.declarationSourceStart, recordDeclaration2.sourceStart);
+ this.setModifiers(recordDeclaration, recordDeclaration2.annotations, recordDeclaration2.sourceStart);
+ }
protected void setModifiers(EnumConstantDeclaration enumConstantDeclaration, org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration) {
switch(this.ast.apiLevel) {
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 476d186ec5..97286123cb 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
@@ -20,6 +20,8 @@ package org.eclipse.jdt.core.dom;
import java.util.Iterator;
import java.util.List;
+import org.eclipse.jdt.internal.core.dom.util.DOMASTUtil;
+
/**
* Concrete superclass and default implementation of an AST subtree matcher.
* <p>
@@ -1517,7 +1519,10 @@ public class ASTMatcher {
&& safeSubtreeListMatch(node.thrownExceptionTypes(), o.thrownExceptionTypes())
: node.getExtraDimensions() == o.getExtraDimensions()
&& safeSubtreeListMatch(node.internalThrownExceptions(), o.internalThrownExceptions()))
- && safeSubtreeMatch(node.getBody(), o.getBody());
+ && safeSubtreeMatch(node.getBody(), o.getBody())
+ && (DOMASTUtil.isRecordDeclarationSupported(node.getAST())
+ ? node.isCompactConstructor() == o.isCompactConstructor()
+ : true);
}
/**
@@ -1976,6 +1981,37 @@ public class ASTMatcher {
* @return <code>true</code> if the subtree matches, or
* <code>false</code> if they do not match or the other object has a
* different node type or is <code>null</code>
+ * @since 3.20 BETA_JAVA
+ */
+ public boolean match(RecordDeclaration node, Object other) {
+ if (!(other instanceof RecordDeclaration)) {
+ return false;
+ }
+ RecordDeclaration o = (RecordDeclaration) other;
+ return (
+ safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
+ && safeSubtreeListMatch(node.modifiers(), o.modifiers())
+ && safeSubtreeMatch(node.getName(), o.getName())
+ && safeSubtreeListMatch(node.superInterfaceTypes(), o.superInterfaceTypes())
+ && safeSubtreeMatch(node.typeParameters(), o.typeParameters())
+ && safeSubtreeListMatch(
+ node.bodyDeclarations(),
+ o.bodyDeclarations()));
+ }
+
+ /**
+ * Returns whether the given node and the other object match.
+ * <p>
+ * The default implementation provided by this class tests whether the
+ * other object is a node of the same type with structurally isomorphic
+ * child subtrees. Subclasses may override this method as needed.
+ * </p>
+ *
+ * @param node the node
+ * @param other the other object, or <code>null</code>
+ * @return <code>true</code> if the subtree matches, or
+ * <code>false</code> if they do not match or the other object has a
+ * different node type or is <code>null</code>
*
* @since 3.14
*/
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java
index ab815d29a5..d98eac8b9a 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTNode.java
@@ -981,6 +981,15 @@ public abstract class ASTNode {
* @since 3.20
*/
public static final int TEXT_BLOCK = 102;
+
+ /**
+ * Node type constant indicating a node of type
+ * <code>RecordDeclaration</code>.
+ * @see RecordDeclaration
+ * @since 3.20 BETA_JAVA
+ */
+ public static final int RECORD_DECLARATION = 103;
+
/**
* Returns the node class for the corresponding node type.
@@ -1130,6 +1139,8 @@ public abstract class ASTNode {
return QualifiedName.class;
case QUALIFIED_TYPE :
return QualifiedType.class;
+ case RECORD_DECLARATION :
+ return RecordDeclaration.class;
case REQUIRES_DIRECTIVE :
return RequiresDirective.class;
case RETURN_STATEMENT :
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java
index bb5494e294..57e9eda62c 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTVisitor.java
@@ -8,6 +8,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*
+ * 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
*******************************************************************************/
@@ -1346,6 +1350,24 @@ public abstract class ASTVisitor {
* Visits the given type-specific AST node.
* <p>
* The default implementation does nothing and return true.
+ * Subclasses may re-implement.
+ * </p>
+ *
+ * @param node the node to visit
+ * @return <code>true</code> if the children of this node should be
+ * visited, and <code>false</code> if the children of this node should
+ * be skipped
+ * @since 3.20 BETA_JAVA
+ * @noreference This method is not intended to be referenced by clients.
+ */
+ public boolean visit(RecordDeclaration node) {
+ return true;
+ }
+
+ /**
+ * Visits the given type-specific AST node.
+ * <p>
+ * The default implementation does nothing and return true.
* Subclasses may reimplement.
* </p>
*
@@ -2749,6 +2771,21 @@ public abstract class ASTVisitor {
/**
* End of visit the given type-specific AST node.
* <p>
+ * The default implementation does nothing. Subclasses may re implement.
+ * </p>
+ *
+ * @param node the node to visit
+ * @since 3.20 BETA_JAVA
+ * @noreference This method is not intended to be referenced by clients.
+ */
+ public void endVisit(RecordDeclaration node) {
+ // default implementation: do nothing
+ }
+
+
+ /**
+ * End of visit the given type-specific AST node.
+ * <p>
* The default implementation does nothing. Subclasses may reimplement.
* </p>
*
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java
index ef2783f72a..bd2aa8ceb7 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/BindingResolver.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*
+ * 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
*******************************************************************************/
@@ -871,6 +875,29 @@ class BindingResolver {
ITypeBinding resolveType(EnumDeclaration type) {
return null;
}
+
+ /**
+ * Resolves the given record declaration and returns the binding
+ * for it.
+ * <p>
+ * The implementation of <code>RecordDeclaration.resolveBinding</code>
+ * forwards to this method. How the record declaration resolves is often
+ * a function of the context in which the declaration node is embedded
+ * as well as the record declaration subtree itself.
+ * </p>
+ * <p>
+ * The default implementation of this method returns <code>null</code>.
+ * Subclasses may re implement.
+ * </p>
+ *
+ * @param type the record declaration of interest
+ * @return the binding for the given record declaration, or <code>null</code>
+ * if no binding is available
+ * @since 3.20 BETA_JAVA
+ */
+ ITypeBinding resolveType(RecordDeclaration type) {
+ return null;
+ }
/**
* Resolves the given type and returns the type binding for it.
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
index ee36dc5527..abb11eec6c 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/DefaultBindingResolver.java
@@ -8,6 +8,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*
+ * 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
* Stephan Herrmann - Contribution for
@@ -1676,6 +1680,27 @@ class DefaultBindingResolver extends BindingResolver {
}
return null;
}
+
+ @Override
+ ITypeBinding resolveType(RecordDeclaration type) {
+ final Object node = this.newAstToOldAst.get(type);
+ if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) {
+ org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node;
+ ITypeBinding typeBinding = this.getTypeBinding(typeDeclaration.binding);
+ if (typeBinding == null) {
+ return null;
+ }
+ this.bindingsToAstNodes.put(typeBinding, type);
+ String key = typeBinding.getKey();
+ if (key != null) {
+ this.bindingTables.bindingKeysToBindings.put(key, typeBinding);
+ }
+ return typeBinding;
+ }
+ return null;
+ }
+
+
@Override
synchronized ITypeBinding resolveType(Type type) {
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodDeclaration.java
index 158c19f26e..dc8a9498c9 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodDeclaration.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/MethodDeclaration.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * Copyright (c) 2000, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
*
* SPDX-License-Identifier: EPL-2.0
*
+ * 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
*******************************************************************************/
@@ -17,6 +21,8 @@ package org.eclipse.jdt.core.dom;
import java.util.ArrayList;
import java.util.List;
+import org.eclipse.jdt.internal.core.dom.util.DOMASTUtil;
+
/**
* Method declaration AST node type. A method declaration
* is the union of a method declaration and a constructor declaration.
@@ -87,6 +93,13 @@ public class MethodDeclaration extends BodyDeclaration {
*/
public static final SimplePropertyDescriptor CONSTRUCTOR_PROPERTY =
new SimplePropertyDescriptor(MethodDeclaration.class, "constructor", boolean.class, MANDATORY); //$NON-NLS-1$
+
+ /**
+ * The "compact constructor" structural property of record node type (type: {@link Boolean}).
+ * @since 3.20 BETA_JAVA
+ */
+ public static final SimplePropertyDescriptor COMPACT_CONSTRUCTOR_PROPERTY =
+ new SimplePropertyDescriptor(MethodDeclaration.class, "compactConstructor", boolean.class, OPTIONAL); //$NON-NLS-1$
/**
* The "name" structural property of this node type (child type: {@link SimpleName}).
@@ -199,6 +212,14 @@ public class MethodDeclaration extends BodyDeclaration {
* @since 3.10
*/
private static final List PROPERTY_DESCRIPTORS_8_0;
+
+ /**
+ * A list of property descriptors (element type:
+ * {@link StructuralPropertyDescriptor}),
+ * or null if uninitialized.
+ * @since 3.20 BETA_JAVA
+ */
+ private static final List PROPERTY_DESCRIPTORS_9_0;
static {
List propertyList = new ArrayList(10);
@@ -242,7 +263,24 @@ public class MethodDeclaration extends BodyDeclaration {
addProperty(EXTRA_DIMENSIONS2_PROPERTY, propertyList);
addProperty(THROWN_EXCEPTION_TYPES_PROPERTY, propertyList);
addProperty(BODY_PROPERTY, propertyList);
- PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+ PROPERTY_DESCRIPTORS_8_0 = reapPropertyList(propertyList);
+
+ propertyList = new ArrayList(14);
+ createPropertyList(MethodDeclaration.class, propertyList);
+ addProperty(JAVADOC_PROPERTY, propertyList);
+ addProperty(MODIFIERS2_PROPERTY, propertyList);
+ addProperty(CONSTRUCTOR_PROPERTY, propertyList);
+ addProperty(TYPE_PARAMETERS_PROPERTY, propertyList);
+ addProperty(RETURN_TYPE2_PROPERTY, propertyList);
+ addProperty(NAME_PROPERTY, propertyList);
+ addProperty(RECEIVER_TYPE_PROPERTY, propertyList);
+ addProperty(RECEIVER_QUALIFIER_PROPERTY, propertyList);
+ addProperty(PARAMETERS_PROPERTY, propertyList);
+ addProperty(EXTRA_DIMENSIONS2_PROPERTY, propertyList);
+ addProperty(THROWN_EXCEPTION_TYPES_PROPERTY, propertyList);
+ addProperty(BODY_PROPERTY, propertyList);
+ addProperty(COMPACT_CONSTRUCTOR_PROPERTY, propertyList);
+ PROPERTY_DESCRIPTORS_9_0 = reapPropertyList(propertyList);
}
/**
@@ -255,10 +293,28 @@ public class MethodDeclaration extends BodyDeclaration {
* @since 3.0
*/
public static List propertyDescriptors(int apiLevel) {
+ return propertyDescriptors(apiLevel, false);
+ }
+
+ /**
+ * Returns a list of structural property descriptors for this node type.
+ * Clients must not modify the result.
+ *
+ * @param apiLevel the API level; one of the
+ * <code>AST.JLS*</code> constants
+ * @param previewEnabled the previewEnabled flag
+ * @return a list of property descriptors (element type:
+ * {@link StructuralPropertyDescriptor})
+ * @noreference This method is not intended to be referenced by clients.
+ * @since 3.20 BETA_JAVA
+ */
+ public static List propertyDescriptors(int apiLevel, boolean previewEnabled) {
if (apiLevel == AST.JLS2_INTERNAL) {
return PROPERTY_DESCRIPTORS_2_0;
} else if (apiLevel < AST.JLS8_INTERNAL) {
return PROPERTY_DESCRIPTORS_3_0;
+ } else if (DOMASTUtil.isRecordDeclarationSupported(apiLevel, previewEnabled)) {
+ return PROPERTY_DESCRIPTORS_9_0;
} else {
return PROPERTY_DESCRIPTORS_8_0;
}
@@ -269,6 +325,13 @@ public class MethodDeclaration extends BodyDeclaration {
* Defaults to method.
*/
private boolean isConstructor = false;
+
+
+ /**
+ * <code>true</code> for a compact constructor in a record, <code>false</code> for a method.
+ * Defaults to method.
+ */
+ private boolean isCompactConstructor = false;
/**
* The method name; lazily initialized; defaults to an unspecified,
@@ -400,6 +463,11 @@ public class MethodDeclaration extends BodyDeclaration {
}
@Override
+ final List internalStructuralPropertiesForType(int apiLevel, boolean previewEnabled) {
+ return propertyDescriptors(apiLevel, previewEnabled);
+ }
+
+ @Override
final int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) {
if (property == MODIFIERS_PROPERTY) {
if (get) {
@@ -430,10 +498,19 @@ public class MethodDeclaration extends BodyDeclaration {
setConstructor(value);
return false;
}
+ } else if (property == COMPACT_CONSTRUCTOR_PROPERTY) {
+ if (get) {
+ return isCompactConstructor();
+ } else {
+ setCompactConstructor(value);
+ return false;
+ }
}
// allow default implementation to flag the error
return super.internalGetSetBooleanProperty(property, get, value);
}
+
+
@Override
final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
@@ -577,6 +654,9 @@ public class MethodDeclaration extends BodyDeclaration {
} else {
result.thrownExceptions().addAll(ASTNode.copySubtrees(target, thrownExceptions()));
}
+ if (DOMASTUtil.isRecordDeclarationSupported(this.ast)) {
+ result.setCompactConstructor(isCompactConstructor());
+ }
result.setBody(
(Block) ASTNode.copySubtree(target, getBody()));
return result;
@@ -642,6 +722,40 @@ public class MethodDeclaration extends BodyDeclaration {
}
/**
+ * Returns whether this declaration declares a constructor or a method.
+ *
+ * @return <code>true</code> if this is a compact constructor declaration in a record,
+ * and <code>false</code> if this is a method declaration
+ * @since 3.20 BETA_JAVA
+ * @noreference This method is not intended to be referenced by clients.
+ * @exception UnsupportedOperationException if this operation is not used in JLS14
+ * @exception UnsupportedOperationException if this operation is used with previewEnabled flag as false
+ */
+
+ public boolean isCompactConstructor() {
+ supportedOnlyIn14();
+ unsupportedWithoutPreviewError();
+ return this.isCompactConstructor;
+ }
+
+ /**
+ * Sets whether this declaration declares a compact constructor in a record or a method.
+ *
+ * @param isCompactConstructor <code>true</code> for a constructor declaration,
+ * and <code>false</code> for a method declaration
+ * @since 3.20 BETA_JAVA
+ * @noreference This method is not intended to be referenced by clients.
+ * @exception UnsupportedOperationException if this operation is not used in JLS14
+ * @exception UnsupportedOperationException if this operation is used with previewEnabled flag as false
+ */
+
+ public void setCompactConstructor(boolean isCompactConstructor) {
+ preValueChange(COMPACT_CONSTRUCTOR_PROPERTY);
+ this.isCompactConstructor = isCompactConstructor;
+ postValueChange(COMPACT_CONSTRUCTOR_PROPERTY);
+ }
+
+ /**
* Returns the live ordered list of type parameters of this method
* declaration (added in JLS3 API). This list is non-empty for parameterized methods.
*
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecordDeclaration.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecordDeclaration.java
new file mode 100644
index 0000000000..68a5969b99
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecordDeclaration.java
@@ -0,0 +1,464 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * 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.core.dom;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Record declaration AST node type (added in JLS14 API).
+ *
+ * <pre>
+ * RecordDeclaration:
+ * [ Javadoc ] { ExtendedModifier } <b>record</b> Identifier
+ * [ <b>&lt;</b> TypeParameter <b>&gt;</b> ]
+ * [ Type { <b>,</b> Type } ]
+ * [ <b>;</b> { RecordBodyDeclaration | <b>;</b> } ]
+ * <b>}</b>
+ * </pre>
+ * The {@link #bodyDeclarations()} list holds the class body declarations
+ * that appear after the semicolon.
+ * <p>
+ * When a Javadoc comment is present, the source
+ * range begins with the first character of the "/**" comment delimiter.
+ * When there is no Javadoc comment, the source range begins with the first
+ * character of the first modifier or annotation (if present), or the
+ * first character of the "record" keyword (if no
+ * modifiers or annotations). The source range extends through the last
+ * character of the "}" token following the body declarations.
+ * </p>
+ *
+ * @since 3.20 BETA_JAVA
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noreference This class is not intended to be referenced by clients as it is a part of Java preview feature.
+ */
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public class RecordDeclaration extends AbstractTypeDeclaration {
+
+ /**
+ * The "javadoc" structural property of this node type (child type: {@link Javadoc}).
+ * @since 3.20 BETA_JAVA
+ */
+ public static final ChildPropertyDescriptor JAVADOC_PROPERTY =
+ internalJavadocPropertyFactory(RecordDeclaration.class);
+
+ /**
+ * The "modifiers" structural property of this node type (element type: {@link IExtendedModifier}) (added in JLS3 API).
+ * @since 3.20 BETA_JAVA
+ */
+ public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
+ internalModifiers2PropertyFactory(RecordDeclaration.class);
+
+ /**
+ * The "interface" structural property of this node type (type: {@link Boolean}).
+ * @since 3.20 BETA_JAVA
+ */
+ public static final SimplePropertyDescriptor INTERFACE_PROPERTY =
+ new SimplePropertyDescriptor(RecordDeclaration.class, "interface", boolean.class, MANDATORY); //$NON-NLS-1$
+
+ /**
+ * The "name" structural property of this node type (child type: {@link SimpleName}).
+ * @since 3.20 BETA_JAVA
+ */
+ public static final ChildPropertyDescriptor NAME_PROPERTY =
+ internalNamePropertyFactory(RecordDeclaration.class);
+
+
+ /**
+ * The "superInterfaceTypes" structural property of this node type (element type: {@link Type}) (added in JLS3 API).
+ * @since 3.20 BETA_JAVA
+ */
+ public static final ChildListPropertyDescriptor SUPER_INTERFACE_TYPES_PROPERTY =
+ new ChildListPropertyDescriptor(RecordDeclaration.class, "superInterfaceTypes", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+ /**
+ * The "typeParameters" structural property of this node type (element type: {@link TypeParameter}) (added in JLS3 API).
+ * @since 3.20 BETA_JAVA
+ */
+ public static final ChildListPropertyDescriptor TYPE_PARAMETERS_PROPERTY =
+ new ChildListPropertyDescriptor(RecordDeclaration.class, "typeParameters", TypeParameter.class, NO_CYCLE_RISK); //$NON-NLS-1$
+
+ /**
+ * The "bodyDeclarations" structural property of this node type (element type: {@link BodyDeclaration}) (added in JLS3 API).
+ * @since 3.20 BETA_JAVA
+ */
+ public static final ChildListPropertyDescriptor BODY_DECLARATIONS_PROPERTY =
+ internalBodyDeclarationPropertyFactory(RecordDeclaration.class);
+
+ /**
+ * A list of property descriptors (element type:
+ * {@link StructuralPropertyDescriptor}),
+ * or null if uninitialized.
+ * @since 3.20 BETA_JAVA
+ */
+ private static final List PROPERTY_DESCRIPTORS;
+
+ static {
+
+ ArrayList propertyList = new ArrayList(8);
+ createPropertyList(RecordDeclaration.class, propertyList);
+ addProperty(JAVADOC_PROPERTY, propertyList);
+ addProperty(MODIFIERS2_PROPERTY, propertyList);
+ addProperty(INTERFACE_PROPERTY, propertyList);
+ addProperty(NAME_PROPERTY, propertyList);
+ addProperty(TYPE_PARAMETERS_PROPERTY, propertyList);
+ addProperty(SUPER_INTERFACE_TYPES_PROPERTY, propertyList);
+ addProperty(BODY_DECLARATIONS_PROPERTY, propertyList);
+ PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
+ }
+
+ /**
+ * Returns a list of structural property descriptors for this node type.
+ * Clients must not modify the result.
+ *
+ * @param apiLevel the API level; one of the
+ * <code>AST.JLS*</code> constants
+
+ * @return a list of property descriptors (element type:
+ * {@link StructuralPropertyDescriptor})
+ * @noreference This method is not intended to be referenced by clients.
+ * @since 3.20 BETA_JAVA
+ */
+ public static List propertyDescriptors(int apiLevel) {
+ return propertyDescriptors(apiLevel, false);
+ }
+
+ /**
+ * Returns a list of structural property descriptors for this node type.
+ * Clients must not modify the result.
+ *
+ * @param apiLevel the API level; one of the
+ * <code>AST.JLS*</code> constants
+ * @param previewEnabled the previewEnabled flag
+ * @return a list of property descriptors (element type:
+ * {@link StructuralPropertyDescriptor})
+ * @noreference This method is not intended to be referenced by clients.
+ * @since 3.20 BETA_JAVA
+ */
+ public static List propertyDescriptors(int apiLevel, boolean previewEnabled) {
+ if (apiLevel == AST.JLS14_INTERNAL && previewEnabled) {
+ return PROPERTY_DESCRIPTORS;
+ }
+ return null;
+ }
+
+ /**
+ * The type parameters (element type: {@link TypeParameter}).
+ * Null in JLS2. Added in JLS3; defaults to an empty list
+ * (see constructor).
+ * @since 3.20 BETA_JAVA
+ */
+ private ASTNode.NodeList typeParameters = null;
+
+
+ /**
+ * The superinterface types (element type: {@link Type}).
+ * Null in JLS2. Added in JLS3; defaults to an empty list
+ * (see constructor).
+ * @since 3.20 BETA_JAVA
+ */
+ private ASTNode.NodeList superInterfaceTypes = null;
+
+ /**
+ * Creates a new AST node for a type declaration owned by the given
+ * AST. By default, the type declaration is for a class of an
+ * unspecified, but legal, name; no modifiers; no javadoc;
+ * no type parameters; no superinterfaces; and an empty list
+ * of body declarations.
+ * <p>
+ * N.B. This constructor is package-private; all subclasses must be
+ * declared in the same package; clients are unable to declare
+ * additional subclasses.
+ * </p>
+ *
+ * @param ast the AST that is to own this node
+ * @exception UnsupportedOperationException if this operation is used other than JLS14
+ * @exception UnsupportedOperationException if this expression is used with previewEnabled flag as false
+ */
+ RecordDeclaration(AST ast) {
+ super(ast);
+ supportedOnlyIn14();
+ unsupportedWithoutPreviewError();
+ this.typeParameters = new ASTNode.NodeList(TYPE_PARAMETERS_PROPERTY);
+ this.superInterfaceTypes = new ASTNode.NodeList(SUPER_INTERFACE_TYPES_PROPERTY);
+ }
+
+ @Override
+ final List internalStructuralPropertiesForType(int apiLevel) {
+ return propertyDescriptors(apiLevel);
+ }
+
+ @Override
+ final List internalStructuralPropertiesForType(int apiLevel, boolean previewEnabled) {
+ return propertyDescriptors(apiLevel, previewEnabled);
+ }
+
+ @Override
+ final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
+ if (property == JAVADOC_PROPERTY) {
+ if (get) {
+ return getJavadoc();
+ } else {
+ setJavadoc((Javadoc) child);
+ return null;
+ }
+ }
+ if (property == NAME_PROPERTY) {
+ if (get) {
+ return getName();
+ } else {
+ setName((SimpleName) child);
+ return null;
+ }
+ }
+ // allow default implementation to flag the error
+ return super.internalGetSetChildProperty(property, get, child);
+ }
+
+ @Override
+ final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
+ if (property == MODIFIERS2_PROPERTY) {
+ return modifiers();
+ }
+ if (property == TYPE_PARAMETERS_PROPERTY) {
+ return typeParameters();
+ }
+ if (property == SUPER_INTERFACE_TYPES_PROPERTY) {
+ return superInterfaceTypes();
+ }
+ if (property == BODY_DECLARATIONS_PROPERTY) {
+ return bodyDeclarations();
+ }
+ // allow default implementation to flag the error
+ return super.internalGetChildListProperty(property);
+ }
+
+ @Override
+ final ChildPropertyDescriptor internalJavadocProperty() {
+ return JAVADOC_PROPERTY;
+ }
+
+ @Override
+ final ChildListPropertyDescriptor internalModifiers2Property() {
+ return MODIFIERS2_PROPERTY;
+ }
+
+ @Override
+ final ChildPropertyDescriptor internalNameProperty() {
+ return NAME_PROPERTY;
+ }
+
+ @Override
+ final ChildListPropertyDescriptor internalBodyDeclarationsProperty() {
+ return BODY_DECLARATIONS_PROPERTY;
+ }
+
+ @Override
+ final int getNodeType0() {
+ return TYPE_DECLARATION;
+ }
+
+ @Override
+ ASTNode clone0(AST target) {
+ RecordDeclaration result = new RecordDeclaration(target);
+ result.setSourceRange(getStartPosition(), getLength());
+ result.setJavadoc(
+ (Javadoc) ASTNode.copySubtree(target, getJavadoc()));
+ result.setName((SimpleName) getName().clone(target));
+ result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
+ result.typeParameters().addAll(
+ ASTNode.copySubtrees(target, typeParameters()));
+ result.superInterfaceTypes().addAll(
+ ASTNode.copySubtrees(target, superInterfaceTypes()));
+ result.bodyDeclarations().addAll(
+ ASTNode.copySubtrees(target, bodyDeclarations()));
+ return result;
+ }
+
+ @Override
+ final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
+ // dispatch to correct overloaded match method
+ return matcher.match(this, other);
+ }
+
+ @Override
+ void accept0(ASTVisitor visitor) {
+ boolean visitChildren = visitor.visit(this);
+ if (visitChildren) {
+ // visit children in normal left to right reading order
+ acceptChild(visitor, getJavadoc());
+ acceptChildren(visitor, this.modifiers);
+ acceptChild(visitor, getName());
+ acceptChildren(visitor, this.typeParameters);
+ acceptChildren(visitor, this.superInterfaceTypes);
+ acceptChildren(visitor, this.bodyDeclarations);
+ }
+ visitor.endVisit(this);
+ }
+
+ /**
+ * Returns the live ordered list of type parameters of this type
+ * declaration (added in JLS3 API). This list is non-empty for parameterized types.
+ *
+ * @return the live list of type parameters
+ * (element type: {@link TypeParameter})
+ * @since 3.20 BETA_JAVA
+ */
+ public List typeParameters() {
+ return this.typeParameters;
+ }
+
+
+ /**
+ * Returns the live ordered list of superinterfaces of this type
+ * declaration (added in JLS3 API). For a class declaration, these are the interfaces
+ * that this class implements; for an interface declaration,
+ * these are the interfaces that this interface extends.
+ *
+ * @return the live list of interface types
+ * (element type: {@link Type})
+ * @since 3.20 BETA_JAVA
+ */
+ public List superInterfaceTypes() {
+ return this.superInterfaceTypes;
+ }
+
+ /**
+ * Returns the ordered list of field declarations of this type
+ * declaration. For a class declaration, these are the
+ * field declarations; for an interface declaration, these are
+ * the constant declarations.
+ * <p>
+ * This convenience method returns this node's body declarations
+ * with non-fields filtered out. Unlike <code>bodyDeclarations</code>,
+ * this method does not return a live result.
+ * </p>
+ *
+ * @return the (possibly empty) list of field declarations
+ */
+ public FieldDeclaration[] getFields() {
+ List bd = bodyDeclarations();
+ int fieldCount = 0;
+ for (Iterator it = bd.listIterator(); it.hasNext(); ) {
+ if (it.next() instanceof FieldDeclaration) {
+ fieldCount++;
+ }
+ }
+ FieldDeclaration[] fields = new FieldDeclaration[fieldCount];
+ int next = 0;
+ for (Iterator it = bd.listIterator(); it.hasNext(); ) {
+ Object decl = it.next();
+ if (decl instanceof FieldDeclaration) {
+ fields[next++] = (FieldDeclaration) decl;
+ }
+ }
+ return fields;
+ }
+
+ /**
+ * Returns the ordered list of method declarations of this type
+ * declaration.
+ * <p>
+ * This convenience method returns this node's body declarations
+ * with non-methods filtered out. Unlike <code>bodyDeclarations</code>,
+ * this method does not return a live result.
+ * </p>
+ *
+ * @return the (possibly empty) list of method (and constructor)
+ * declarations
+ */
+ public MethodDeclaration[] getMethods() {
+ List bd = bodyDeclarations();
+ int methodCount = 0;
+ for (Iterator it = bd.listIterator(); it.hasNext(); ) {
+ if (it.next() instanceof MethodDeclaration) {
+ methodCount++;
+ }
+ }
+ MethodDeclaration[] methods = new MethodDeclaration[methodCount];
+ int next = 0;
+ for (Iterator it = bd.listIterator(); it.hasNext(); ) {
+ Object decl = it.next();
+ if (decl instanceof MethodDeclaration) {
+ methods[next++] = (MethodDeclaration) decl;
+ }
+ }
+ return methods;
+ }
+
+ /**
+ * Returns the ordered list of member type declarations of this type
+ * declaration.
+ * <p>
+ * This convenience method returns this node's body declarations
+ * with non-types filtered out. Unlike <code>bodyDeclarations</code>,
+ * this method does not return a live result.
+ * </p>
+ *
+ * @return the (possibly empty) list of member type declarations
+ */
+ public RecordDeclaration[] getTypes() {
+ List bd = bodyDeclarations();
+ int typeCount = 0;
+ for (Iterator it = bd.listIterator(); it.hasNext(); ) {
+ if (it.next() instanceof RecordDeclaration) {
+ typeCount++;
+ }
+ }
+ RecordDeclaration[] memberTypes = new RecordDeclaration[typeCount];
+ int next = 0;
+ for (Iterator it = bd.listIterator(); it.hasNext(); ) {
+ Object decl = it.next();
+ if (decl instanceof RecordDeclaration) {
+ memberTypes[next++] = (RecordDeclaration) decl;
+ }
+ }
+ return memberTypes;
+ }
+
+ @Override
+ ITypeBinding internalResolveBinding() {
+ return this.ast.getBindingResolver().resolveType(this);
+ }
+
+ @Override
+ int memSize() {
+ return super.memSize() + 6 * 4;
+ }
+
+ @Override
+ int treeSize() {
+ return memSize()
+ + (this.optionalDocComment == null ? 0 : getJavadoc().treeSize())
+ + (this.modifiers == null ? 0 : this.modifiers.listSize())
+ + (this.typeName == null ? 0 : getName().treeSize())
+ + (this.typeParameters == null ? 0 : this.typeParameters.listSize())
+ + (this.superInterfaceTypes == null ? 0 : this.superInterfaceTypes.listSize())
+ + this.bodyDeclarations.listSize();
+ }
+
+ @Override
+ SimplePropertyDescriptor internalModifiersProperty() {
+ // node type does not exist before JLS 14
+ return null;
+ }
+
+}
+
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 c8bdbb7cc5..68d4661722 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
@@ -1303,6 +1303,51 @@ public class NaiveASTFlattener extends ASTVisitor {
}
@Override
+ public boolean visit(RecordDeclaration node) {
+ if (node.getJavadoc() != null) {
+ node.getJavadoc().accept(this);
+ }
+ printIndent();
+ printModifiers(node.modifiers());
+ this.buffer.append("record ");//$NON-NLS-1$
+ node.getName().accept(this);
+ this.buffer.append(" ");//$NON-NLS-1$
+ if (!node.superInterfaceTypes().isEmpty()) {
+ this.buffer.append("implements ");//$NON-NLS-1$
+ for (Iterator it = node.superInterfaceTypes().iterator(); it.hasNext(); ) {
+ Type t = (Type) it.next();
+ t.accept(this);
+ if (it.hasNext()) {
+ this.buffer.append(", ");//$NON-NLS-1$
+ }
+ }
+ this.buffer.append(" ");//$NON-NLS-1$
+ }
+ if (!node.typeParameters().isEmpty()) {
+ this.buffer.append("<");//$NON-NLS-1$
+ for (Iterator it = node.typeParameters().iterator(); it.hasNext(); ) {
+ TypeParameter t = (TypeParameter) it.next();
+ t.accept(this);
+ if (it.hasNext()) {
+ this.buffer.append(",");//$NON-NLS-1$
+ }
+ }
+ this.buffer.append(">");//$NON-NLS-1$
+ }
+ this.buffer.append("{");//$NON-NLS-1$
+ if (!node.bodyDeclarations().isEmpty()) {
+ this.buffer.append("; ");//$NON-NLS-1$
+ for (Iterator it = node.bodyDeclarations().iterator(); it.hasNext(); ) {
+ BodyDeclaration d = (BodyDeclaration) it.next();
+ d.accept(this);
+ // other body declarations include trailing punctuation
+ }
+ }
+ this.buffer.append("}\n");//$NON-NLS-1$
+ return false;
+ }
+
+ @Override
public boolean visit(RequiresDirective node) {
printIndent();
this.buffer.append("requires");//$NON-NLS-1$
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 cc0ed65731..e4ce272e3f 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
@@ -850,6 +850,26 @@ public class ASTRewriteFlattener extends ASTVisitor {
}
@Override
+ public boolean visit(RecordDeclaration node) {
+ ASTNode javadoc= getChildNode(node, RecordDeclaration.JAVADOC_PROPERTY);
+ if (javadoc != null) {
+ javadoc.accept(this);
+ }
+ visitList(node, RecordDeclaration.MODIFIERS2_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
+ this.result.append("enum ");//$NON-NLS-1$
+ getChildNode(node, RecordDeclaration.NAME_PROPERTY).accept(this);
+ this.result.append(' ');
+ visitList(node, RecordDeclaration.SUPER_INTERFACE_TYPES_PROPERTY, String.valueOf(','), "implements ", Util.EMPTY_STRING); //$NON-NLS-1$
+ this.result.append(' ');
+ visitList(node, TypeDeclaration.TYPE_PARAMETERS_PROPERTY, String.valueOf(','), String.valueOf('<'), String.valueOf('>'));
+
+ this.result.append('{');
+ visitList(node, RecordDeclaration.BODY_DECLARATIONS_PROPERTY, Util.EMPTY_STRING, String.valueOf(';'), Util.EMPTY_STRING);
+ this.result.append('}');
+ return false;
+ }
+
+ @Override
public boolean visit(RequiresDirective node) {
this.result.append("requires "); //$NON-NLS-1$
visitList(node, RequiresDirective.MODIFIERS_PROPERTY, String.valueOf(' '), Util.EMPTY_STRING, String.valueOf(' '));
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/util/DOMASTUtil.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/util/DOMASTUtil.java
new file mode 100644
index 0000000000..9071686042
--- /dev/null
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/util/DOMASTUtil.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * 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.core.dom.util;
+
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+
+public class DOMASTUtil {
+
+ /**
+ * Validates if the given <code>AST</code> supports the provided <code>nodeType</code>. This API checks for node
+ * types supported from JLS 14 onwards and will return <code>true></code> for nodes added before JLS14.
+ *
+ * @param ast
+ * the AST to be evaluated
+ * @param nodeType
+ * the node type constant indicating a node of type to be evaluated
+ * @return <code>true</code> if the given <code>AST</code> supports the provided <code>nodeType</code> else
+ * <code>false</code>
+ * @see ASTNode#getNodeType()
+ * @since 3.20 BETA_JAVA
+ */
+ private static boolean isNodeTypeSupportedinAST(AST ast, int nodeType) {
+ return isNodeTypeSupportedinAST(ast.apiLevel(), ast.isPreviewEnabledSet(), nodeType);
+ }
+
+ /**
+ * Validates if the given <code>apiLevel</code> and <code>previewEnabled</code> supports the provided
+ * <code>nodeType</code>. This API checks for node types supported from JLS 14 onwards and will return
+ * <code>true></code> for nodes added before JLS14.
+ *
+ * @param apiLevel
+ * the level to be checked
+ * @param previewEnabled
+ * the preview feature to be considered
+ * @param nodeType
+ * the node type constant indicating a node of type to be evaluated
+ * @return <code>true</code> if the given <code>AST</code> supports the provided <code>nodeType</code> else
+ * <code>false</code>
+ * @see ASTNode#getNodeType()
+ * @since 3.20 BETA_JAVA
+ */
+ private static boolean isNodeTypeSupportedinAST(int apiLevel, boolean previewEnabled, int nodeType) {
+ switch (nodeType) {
+ case ASTNode.SWITCH_EXPRESSION:
+ case ASTNode.YIELD_STATEMENT:
+ return apiLevel >= AST.JLS14;
+ case ASTNode.TEXT_BLOCK:
+ case ASTNode.RECORD_DECLARATION:
+ return isPreviewEnabled(apiLevel, previewEnabled);
+ }
+ return false;
+ }
+
+ private static boolean isPreviewEnabled(int apiLevel, boolean previewEnabled) {
+ return (apiLevel == AST.JLS14 && previewEnabled);
+ }
+
+ public static boolean isSwitchExpressionSupported(AST ast) {
+ return isNodeTypeSupportedinAST(ast, ASTNode.SWITCH_EXPRESSION);
+ }
+
+ public static boolean isYieldStatementSupported(AST ast) {
+ return isNodeTypeSupportedinAST(ast, ASTNode.YIELD_STATEMENT);
+ }
+
+ public static boolean isTextBlockSupported(AST ast) {
+ return isNodeTypeSupportedinAST(ast, ASTNode.TEXT_BLOCK);
+ }
+
+ public static boolean isRecordDeclarationSupported(AST ast) {
+ return isNodeTypeSupportedinAST(ast, ASTNode.RECORD_DECLARATION);
+ }
+
+ public static boolean isRecordDeclarationSupported(int apiLevel, boolean previewEnabled) {
+ return isNodeTypeSupportedinAST(apiLevel, previewEnabled, ASTNode.RECORD_DECLARATION);
+ }
+
+}

Back to the top