RecordDeclarationTest.java
/*
* Copyright (C) 2013-2024 The JavaParser Team.
*
* This file is part of JavaParser.
*
* JavaParser can be used either under the terms of
* a) the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* b) the terms of the Apache License
*
* You should have received a copy of both licenses in LICENCE.LGPL and
* LICENCE.APACHE. Please refer to those files for details.
*
* JavaParser is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*/
package com.github.javaparser.ast.body;
import static com.github.javaparser.utils.TestUtils.assertEqualsStringIgnoringEol;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
import com.github.javaparser.ParserConfiguration;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Modifier;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.expr.ObjectCreationExpr;
import com.github.javaparser.utils.TestParser;
import java.util.List;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.opentest4j.AssertionFailedError;
public class RecordDeclarationTest {
@Nested
class LanguageLevels {
@ParameterizedTest
@EnumSource(
value = ParserConfiguration.LanguageLevel.class,
names = {"JAVA_13", "JAVA_13_PREVIEW", "JAVA_14", "JAVA_15"})
void basicGrammarCompiles_languageLevelValidation_forbidden(ParserConfiguration.LanguageLevel languageLevel) {
String s = "record Point(int x, int y) { }";
assertThrows(AssertionFailedError.class, () -> {
CompilationUnit cu = TestParser.parseCompilationUnit(languageLevel, s);
});
}
@ParameterizedTest
@EnumSource(
value = ParserConfiguration.LanguageLevel.class,
names = {"JAVA_14_PREVIEW", "JAVA_15_PREVIEW", "JAVA_16", "JAVA_16_PREVIEW"})
void basicGrammarCompiles_languageLevelValidation_permitted(ParserConfiguration.LanguageLevel languageLevel) {
String s = "record Point(int x, int y) { }";
CompilationUnit cu = TestParser.parseCompilationUnit(languageLevel, s);
}
@ParameterizedTest
@EnumSource(
value = ParserConfiguration.LanguageLevel.class,
names = {"JAVA_14_PREVIEW", "JAVA_15_PREVIEW", "JAVA_16", "JAVA_16_PREVIEW"})
void languageLevelValidation_recordAsTypeIdentifier_permitted(ParserConfiguration.LanguageLevel languageLevel) {
String s = "class record {}";
assertThrows(AssertionFailedError.class, () -> {
CompilationUnit cu = TestParser.parseCompilationUnit(languageLevel, s);
});
}
@ParameterizedTest
@EnumSource(
value = ParserConfiguration.LanguageLevel.class,
names = {"JAVA_13", "JAVA_13_PREVIEW", "JAVA_14", "JAVA_15"})
void languageLevelValidation_recordAsTypeIdentifier_forbidden(ParserConfiguration.LanguageLevel languageLevel) {
String s = "class record {}";
CompilationUnit cu = TestParser.parseCompilationUnit(languageLevel, s);
}
}
/**
* https://openjdk.java.net/jeps/395#Description
*/
@Test
void basicGrammarCompiles() {
String s = "record Point(int x, int y) { }";
assertOneRecordDeclaration(TestParser.parseCompilationUnit(s));
}
/**
* https://openjdk.java.net/jeps/395#Description
*/
@Test
void basicGrammar() {
String s = "record Point(int x, int y) { }";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
RecordDeclaration recordDeclaration =
cu.findAll(RecordDeclaration.class).get(0);
assertTrue(recordDeclaration.isRecordDeclaration());
assertTrue(recordDeclaration.getImplementedTypes().isEmpty());
assertTrue(recordDeclaration.getTypeParameters().isEmpty());
assertTrue(recordDeclaration.getFullyQualifiedName().isPresent());
assertEquals("Point", recordDeclaration.getFullyQualifiedName().get());
assertTrue(recordDeclaration.isRecordDeclaration());
NodeList<Parameter> parameters = recordDeclaration.getParameters();
assertEquals(2, parameters.size());
Parameter parameter0 = parameters.get(0);
assertEquals("x", parameter0.getNameAsString());
assertEquals("int", parameter0.getTypeAsString());
Parameter parameter1 = parameters.get(1);
assertEquals("y", parameter1.getNameAsString());
assertEquals("int", parameter1.getTypeAsString());
assertEquals(0, recordDeclaration.getMembers().size());
}
/**
* https://openjdk.java.net/jeps/395#Description
*/
@Test
void basicRecordPrints() {
String s = "record Point(int x, int y) { }";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
String expected = "" + "record Point(int x, int y) {\n" + "}\n" + "";
assertEqualsStringIgnoringEol(expected, cu.toString());
}
@Test
void genericRecordPrints() {
String s = "record Point<X,Y>(X x, Y y) { }";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
String expected = "" + "record Point<X, Y>(X x, Y y) {\n" + "}\n" + "";
assertEqualsStringIgnoringEol(expected, cu.toString());
}
/**
* https://openjdk.java.net/jeps/395#Restrictions-on-record
*/
@Test
void record_cannotExtend() {
String s = "record Point(int x, int y) extends OtherThing { }";
assertCompilationFails(s);
}
/**
* https://openjdk.java.net/jeps/395#Restrictions-on-records
*/
@Test
void record_cannotBeAbstract() {
String s = "abstract record Point(int x, int y) { }";
assertCompilationFails(s);
}
/**
* https://openjdk.java.net/jeps/395#Restrictions-on-records
*/
@Test
void record_mayImplementInterfaces() {
String s = "record Point(int x, int y) implements OtherInterface { }";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
}
/**
* https://openjdk.java.net/jeps/395#Restrictions-on-records
*/
@Test
void record_mayBeStatic() {
String s = "static record Point(int x, int y) { }";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
}
@Test
void recordWithVarArgs() {
String s = "record R(T1 c1, Tn... cn){ }";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
List<RecordDeclaration> recordDeclarations = cu.findAll(RecordDeclaration.class);
assertEquals(1, recordDeclarations.size());
RecordDeclaration recordDeclaration = recordDeclarations.get(0);
NodeList<Parameter> parameters = recordDeclaration.getParameters();
assertEquals(2, parameters.size());
Parameter parameter0 = parameters.get(0);
assertEquals("c1", parameter0.getNameAsString());
assertEquals("T1", parameter0.getTypeAsString());
assertFalse(parameter0.isVarArgs());
Parameter parameter1 = parameters.get(1);
assertEquals("cn", parameter1.getNameAsString());
assertEquals("Tn", parameter1.getTypeAsString());
assertTrue(parameter1.isVarArgs());
}
@Test
void recordWithAnnotationedParameters() {
String s = "record Card(@MyAnno Rank rank, @MyAnno Suit suit) { }";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
List<RecordDeclaration> recordDeclarations = cu.findAll(RecordDeclaration.class);
assertEquals(1, recordDeclarations.size());
RecordDeclaration recordDeclaration = recordDeclarations.get(0);
NodeList<Parameter> parameters = recordDeclaration.getParameters();
assertEquals(2, parameters.size());
Parameter parameter0 = parameters.get(0);
assertEquals("rank", parameter0.getNameAsString());
assertEquals("Rank", parameter0.getTypeAsString());
assertEquals(1, parameter0.getAnnotations().size());
Parameter parameter1 = parameters.get(1);
assertEquals("suit", parameter1.getNameAsString());
assertEquals("Suit", parameter1.getTypeAsString());
assertEquals(1, parameter1.getAnnotations().size());
assertEquals(0, recordDeclaration.getMembers().size());
}
@Test
void record_emptyMembers() {
String s = "record Point(int x, int y) { }";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
List<RecordDeclaration> recordDeclarations = cu.findAll(RecordDeclaration.class);
RecordDeclaration recordDeclaration = recordDeclarations.get(0);
assertEquals(0, recordDeclaration.getMembers().size());
}
@Test
void record_permitStaticMethods() {
String s = "" + "record ABC(int x, int y) {\n"
+ "\n"
+ " static public int abc() {\n"
+ " return x;\n"
+ " }\n"
+ "\n"
+ "}\n"
+ "";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
}
@Test
void record_permitMethods() {
String s = "" + "record ABC(int x, int y) {\n"
+ "\n"
+ " public int x() {\n"
+ " return x;\n"
+ " }\n"
+ "\n"
+ " public String xyz() {\n"
+ " return \"10\";\n"
+ " }\n"
+ "\n"
+ "}\n"
+ "";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
}
@Test
void record_forbidNonStaticFields() {
String s = "record Point(int x, int y) { int z; }";
assertCompilationFails(s);
}
@Test
void record_permitStaticFields() {
String s = "record Point(int x, int y) { static int z; }";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
}
@Test
void record_permitPublicStaticFieldInRecord1() {
String s = "public final record RecordPublicField() {" + " public static final Object EMPTY = new Object();"
+ "}\n";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
}
@Test
void record_permitPublicStaticFieldInNestedRecord() {
String s =
"public final record RecordTopLevel(Object member) {\n" + " private static record RecordNested() {\n"
+ " public static final RecordNested EMPTY = new RecordNested();\n"
+ " }\n"
+ "}\n";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertTwoRecordDeclarations(cu);
}
@Test
void record_permitStaticFields2() {
String s = "" + "record ABC(int x, int y) {\n"
+ "\n"
+ " static int z;\n"
+ "\n"
+ " static {\n"
+ " int z = 10;\n"
+ " }\n"
+ "\n"
+ " public int x() {\n"
+ " return x;\n"
+ " }\n"
+ "\n"
+ "}\n"
+ "";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
}
/**
* https://openjdk.java.net/jeps/395#Restrictions-on-records
*/
@Test
void record_isImplicitlyFinal() {
String s = "record Point(int x, int y) { static int z; }";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
RecordDeclaration recordDeclaration =
cu.findFirst(RecordDeclaration.class).get();
assertFalse(recordDeclaration.hasModifier(Modifier.Keyword.FINAL));
assertTrue(recordDeclaration.isFinal(), "Records are implicitly final.");
}
/**
* https://openjdk.java.net/jeps/395#Restrictions-on-records
*/
@Test
void record_isImplicitlyFinalWithoutExplicit() {
String s = "record Point(int x, int y) { static int z; }";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
RecordDeclaration recordDeclaration =
cu.findFirst(RecordDeclaration.class).get();
assertFalse(recordDeclaration.hasModifier(Modifier.Keyword.FINAL));
assertTrue(recordDeclaration.isFinal(), "Records are implicitly final.");
}
/**
* https://openjdk.java.net/jeps/395#Restrictions-on-records
*/
@Test
void record_canHaveGenerics() {
String s = "record Point <T> (T x, int y) { }";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
RecordDeclaration recordDeclaration =
cu.findFirst(RecordDeclaration.class).get();
assertFalse(recordDeclaration.getTypeParameters().isEmpty());
assertEquals("T", recordDeclaration.getTypeParameters().get(0).getNameAsString());
}
@Test
void record_mustNotAllowMismatchedComponentAccessorReturnType() {
String s = "record Point(int x, int y) {\n" + " public String x() {\n"
+ " return \"10\";\n"
+ " }\n"
+ "}";
assertCompilationFails(s);
}
@Test
void record_allowMethodsWithSameNameAsRecordComponentButNotAnAccessorMethod() {
String s = "record Point(int x, int y) {\n" + " public String x(int a) {\n"
+ " return \"10\";\n"
+ " }\n"
+ "}";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
}
@Test
void record_allowMethodsWithSameNameAsRecordComponentButNotAnAccessorMethod2() {
String s = "record Point(int x, int y) {\n" + " public int x(int a) {\n"
+ " return 10;\n"
+ " }\n"
+ "}";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
}
@Test
void record_allowComponentAccessorWithMatchingType() {
String s =
"record Point(int x, int y) {\n" + " public int x() {\n" + " return 10;\n" + " }\n" + "}";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
}
/**
* https://openjdk.java.net/jeps/395#Restrictions-on-records
*/
@Test
void record_allowNestedWithinClass() {
String s = "\n" + "class X {\n" + " record Point(int x, int y) {\n" + " }\n" + "}\n";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
}
/**
* https://openjdk.java.net/jeps/395#Restrictions-on-records
*/
@Test
void record_componentsAreImplicitlyFinal() {
String s = "record Point(int x, int y) { }";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
RecordDeclaration recordDeclaration =
cu.findAll(RecordDeclaration.class).get(0);
NodeList<Parameter> parameters = recordDeclaration.getParameters();
assertTrue(parameters.get(0).isFinal());
assertTrue(parameters.get(1).isFinal());
}
/**
* https://openjdk.java.net/jeps/395#Restrictions-on-records
*/
@Test
void record_allowClassWithinRecord() {
String s = "\n" + "record Point(int x, int y) {\n" + " class X {\n" + " }\n" + "}\n";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
List<RecordDeclaration> recordDeclarations = cu.findAll(RecordDeclaration.class);
assertEquals(1, recordDeclarations.size());
RecordDeclaration recordDeclaration = recordDeclarations.get(0);
BodyDeclaration<?> member = recordDeclaration.getMember(0);
assertTrue(member.isClassOrInterfaceDeclaration());
}
/**
* https://openjdk.java.net/jeps/395#Restrictions-on-records
*/
@Test
void record_allowNestedWithinInterface() {
String s = "\n" + "interface X {\n" + " record Point(int x, int y) {\n" + " }\n" + "}\n";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
}
/**
* https://openjdk.java.net/jeps/395#Restrictions-on-records
*/
@Test
void record_allowNestedWithinEnum() {
String s = "\n" + "enum ABC {\n"
+ " ABC;\n"
+ " \n"
+ " record Point(int x, int y) {\n"
+ " }\n"
+ "}\n";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
}
/**
* https://openjdk.java.net/jeps/395#Restrictions-on-records
*/
@Test
void record_allowNestedMultiple() {
String s = "\n" + "interface Y {\n"
+ " class X {\n"
+ " record Point(int x, int y) {\n"
+ " }\n"
+ " }\n"
+ "}\n";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
}
/**
* https://openjdk.java.net/jeps/395#Restrictions-on-records
*/
@Test
void record_allowNestedMultiple2() {
String s = "\n" + "interface Y {\n"
+ " class X {\n"
+ " record Point(int x, int y) {\n"
+ " }\n"
+ " record PointB(int x, int y) {\n"
+ " }\n"
+ " }\n"
+ "\n"
+ " record PointC(int x, int y) {\n"
+ " }\n"
+ "}\n";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
List<RecordDeclaration> recordDeclarations = cu.findAll(RecordDeclaration.class);
assertEquals(3, recordDeclarations.size());
}
/**
* https://openjdk.java.net/jeps/395#Restrictions-on-records
*/
@Test
void record_topLevelRecordsAreNotStatic() {
String s = "record Point(int x, int y) { }\n";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
RecordDeclaration recordDeclaration =
cu.findAll(RecordDeclaration.class).get(0);
assertFalse(recordDeclaration.hasModifier(Modifier.Keyword.STATIC));
assertFalse(recordDeclaration.isStatic(), "Top level Records are NOT implicitly static.");
}
/**
* https://openjdk.java.net/jeps/395#Restrictions-on-records
*/
@Test
void record_nestedRecordsAreImplicitlyStatic() {
String s = "\n" + "class X {\n" + " record Point(int x, int y) {\n" + " }\n" + "}\n";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
RecordDeclaration recordDeclaration =
cu.findAll(RecordDeclaration.class).get(0);
assertFalse(recordDeclaration.hasModifier(Modifier.Keyword.STATIC));
assertTrue(recordDeclaration.isStatic(), "Nested Records are implicitly static.");
}
@Test
void record_canBeCreatedUsingKeywordNew() {
String s = "\n" + "\n"
+ "record Point(int x, int y) {\n"
+ "}\n"
+ "\n"
+ "class X {\n"
+ " public static void main(String[] args) {\n"
+ " new Point(10, 3);\n"
+ " }\n"
+ "}\n\n";
CompilationUnit cu = TestParser.parseCompilationUnit(s);
assertOneRecordDeclaration(cu);
ClassOrInterfaceDeclaration coid =
cu.findAll(ClassOrInterfaceDeclaration.class).get(0);
List<ObjectCreationExpr> objectCreationExprs = coid.findAll(ObjectCreationExpr.class);
assertEquals(1, objectCreationExprs.size());
ObjectCreationExpr objectCreationExpr = objectCreationExprs.get(0);
assertEquals("Point", objectCreationExpr.getTypeAsString());
}
/**
* Note the Record Declaration Constructor does not include parameters.
* (parameters are, instead, included within the record declaration)
* <p>
* https://bugs.openjdk.java.net/browse/JDK-8222777
*/
@Test
void recordDeclarationFromTheJDK8222777() {
CompilationUnit cu = TestParser.parseCompilationUnit("" + "public record Range(int lo, int hi) {\n"
+ "\n"
+ " public Range {\n"
+ " if (lo > hi) /* referring here to the implicit constructor parameters */\n"
+ " throw new IllegalArgumentException(String.format(\"(%d,%d)\", lo, hi));\n"
+ " }\n"
+ "}");
RecordDeclaration recordDeclaration =
cu.findFirst(RecordDeclaration.class).get();
assertThat(recordDeclaration.getNameAsString()).isEqualTo("Range");
assertThat(recordDeclaration.getModifiers()).containsExactly(Modifier.publicModifier());
// test parameters
// get constructor
// test parameters (none)
}
@Test
void recordDeclaration_exampleFromJls_8_10_4_1_normalCanonicalConstructors() {
CompilationUnit cu = TestParser.parseCompilationUnit("" + "import java.lang.annotation.Target;\n"
+ "import java.lang.annotation.ElementType;\n"
+ "\n"
+ "@interface Foo {}\n"
+ "@interface Bar {}\n"
+ "\n"
+ "record Person(@Foo String name) {\n"
+ " Person(String name2) {\n"
+ " }\n"
+ "}");
RecordDeclaration recordDeclaration =
cu.findFirst(RecordDeclaration.class).get();
assertThat(recordDeclaration.getNameAsString()).isEqualTo("Person");
assertThat(recordDeclaration.getModifiers()).isEmpty();
assertThat(recordDeclaration.getConstructors()).hasSize(1);
assertThat(recordDeclaration.getCompactConstructors()).hasSize(0);
}
@Test
void compactConstructor_exampleFromJls_8_10_4_2_compactConstructors() {
CompilationUnit cu = TestParser.parseCompilationUnit("" + "record Rational(int num, int denom) {\n"
+ " private static int gcd(int a, int b) {\n"
+ " if (b == 0) return Math.abs(a);\n"
+ " else return gcd(b, a % b);\n"
+ " }\n"
+ " \n"
+ " Rational {\n"
+ " int gcd = gcd(num, denom);\n"
+ " num /= gcd;\n"
+ " denom /= gcd;\n"
+ " }\n"
+ "}\n");
RecordDeclaration recordDeclaration =
cu.findFirst(RecordDeclaration.class).get();
assertThat(recordDeclaration.getNameAsString()).isEqualTo("Rational");
assertThat(recordDeclaration.getModifiers()).isEmpty();
assertThat(recordDeclaration.getConstructors()).hasSize(0);
assertThat(recordDeclaration.getCompactConstructors()).hasSize(1);
}
@Test
void nonCompactConstructor_exampleFromJls_8_10_4_2_compactConstructors() {
CompilationUnit cu = TestParser.parseCompilationUnit("" + "record Rational(int num, int denom) {\n"
+ " private static int gcd(int a, int b) {\n"
+ " if (b == 0) return Math.abs(a);\n"
+ " else return gcd(b, a % b);\n"
+ " }\n"
+ " \n"
+ " Rational(int num, int demon) {\n"
+ " int gcd = gcd(num, denom);\n"
+ " num /= gcd;\n"
+ " denom /= gcd;\n"
+ " this.num = num;\n"
+ " this.denom = denom;\n"
+ " }\n"
+ "}\n");
RecordDeclaration recordDeclaration =
cu.findFirst(RecordDeclaration.class).get();
assertThat(recordDeclaration.getNameAsString()).isEqualTo("Rational");
assertThat(recordDeclaration.getModifiers()).isEmpty();
assertThat(recordDeclaration.getConstructors()).hasSize(1);
assertThat(recordDeclaration.getCompactConstructors()).hasSize(0);
}
/**
* https://openjdk.java.net/jeps/395
*/
@Test
void localRecords() {
CompilationUnit cu = TestParser.parseCompilationUnit("" + "class Scratch {\n"
+ " List<Merchant> findTopMerchants(List<Merchant> merchants, int month) {\n"
+ " // Local record\n"
+ " record MerchantSales(Merchant merchant, double sales) {}\n"
+ "\n"
+ " return merchants.stream()\n"
+ " .map(merchant -> new MerchantSales(merchant, computeSales(merchant, month)))\n"
+ " .sorted((m1, m2) -> Double.compare(m2.sales(), m1.sales()))\n"
+ " .map(MerchantSales::merchant)\n"
+ " .collect(toList());\n"
+ " }\n"
+ "}\n");
RecordDeclaration recordDeclaration =
cu.findFirst(RecordDeclaration.class).get();
assertThat(recordDeclaration.getNameAsString()).isEqualTo("MerchantSales");
}
@Test
void instanceFieldIsNotAllowedInRecord() {
String s = "record X { int record; }";
assertThrows(AssertionFailedError.class, () -> {
CompilationUnit cu = TestParser.parseCompilationUnit(s);
});
}
private void assertCompilationFails(String s) {
assertThrows(AssertionFailedError.class, () -> {
CompilationUnit cu = TestParser.parseCompilationUnit(s);
});
}
private void assertOneRecordDeclaration(CompilationUnit cu) {
List<RecordDeclaration> recordDeclarations = cu.findAll(RecordDeclaration.class);
assertEquals(1, recordDeclarations.size());
}
private void assertTwoRecordDeclarations(CompilationUnit cu) {
List<RecordDeclaration> recordDeclarations = cu.findAll(RecordDeclaration.class);
assertEquals(2, recordDeclarations.size());
}
}