j3.27.0.0 working

This commit is contained in:
Mann Patel
2025-10-11 02:02:27 -06:00
parent 6c591bbf37
commit d80c25c5d7
2973 changed files with 383519 additions and 51603 deletions

View File

@@ -0,0 +1,71 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>javaparser-parent</artifactId>
<groupId>com.github.javaparser</groupId>
<version>3.27.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>javaparser-core-serialization</artifactId>
<description>Serializers for the JavaParser AST.</description>
<licenses>
<license>
<name>GNU Lesser General Public License</name>
<url>http://www.gnu.org/licenses/lgpl-3.0.html</url>
<distribution>repo</distribution>
</license>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
<comments>A business-friendly OSS license</comments>
</license>
</licenses>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Automatic-Module-Name>com.github.javaparser.core.serialization</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
</dependency>
<dependency>
<groupId>com.github.javaparser</groupId>
<artifactId>javaparser-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
<version>2.1.3</version>
</dependency>
<!-- The jakarta.json variant of Glassfish is now available under a new name, Eclipse Parsson -->
<dependency>
<groupId>org.eclipse.parsson</groupId>
<artifactId>parsson</artifactId>
<version>1.1.7</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,203 @@
/*
* Copyright (C) 2007-2010 Júlio Vilmar Gesser.
* Copyright (C) 2011, 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.serialization;
import static com.github.javaparser.ast.NodeList.toNodeList;
import static com.github.javaparser.metamodel.JavaParserMetaModel.getNodeMetaModel;
import static com.github.javaparser.serialization.JavaParserJsonSerializer.*;
import com.github.javaparser.*;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.comments.Comment;
import com.github.javaparser.metamodel.BaseNodeMetaModel;
import com.github.javaparser.metamodel.PropertyMetaModel;
import com.github.javaparser.utils.Log;
import jakarta.json.JsonArray;
import jakarta.json.JsonObject;
import jakarta.json.JsonReader;
import jakarta.json.JsonValue;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
/**
* Deserializes the JSON file that was built by {@link JavaParserJsonSerializer}.
*/
public class JavaParserJsonDeserializer {
/**
* Deserializes json, contained by JsonReader, into AST node.
* The root node and all its child nodes will be deserialized.
* @param reader json-p reader (object-level reader, <a href="https://javaee.github.io/jsonp/">see their docs</a>)
* @return the root level deserialized node
*/
public Node deserializeObject(JsonReader reader) {
Log.info("Deserializing JSON to Node.");
JsonObject jsonObject = reader.readObject();
return deserializeObject(jsonObject);
}
/**
* Recursive depth-first deserializing method that creates a Node instance from JsonObject.
*
* @param nodeJson json object at current level containg values as properties
* @return deserialized node including all children.
* @implNote the Node instance will be constructed by the properties defined in the meta model.
* Non meta properties will be set after Node is instantiated.
* @implNote comment is included in the propertyKey meta model, but not set when constructing the Node instance.
* That is, comment is not included in the constructor propertyKey list, and therefore needs to be set
* after constructing the node.
* See {@link com.github.javaparser.metamodel.BaseNodeMetaModel#construct(Map)} how the node is contructed
*/
private Node deserializeObject(JsonObject nodeJson) {
try {
String serializedNodeType = nodeJson.getString(JsonNode.CLASS.propertyKey);
BaseNodeMetaModel nodeMetaModel = getNodeMetaModel(Class.forName(serializedNodeType))
.orElseThrow(() -> new IllegalStateException(
"Trying to deserialize an unknown node type: " + serializedNodeType));
Map<String, Object> parameters = new HashMap<>();
Map<String, JsonValue> deferredJsonValues = new HashMap<>();
for (String name : nodeJson.keySet()) {
if (name.equals(JsonNode.CLASS.propertyKey)) {
continue;
}
Optional<PropertyMetaModel> optionalPropertyMetaModel =
nodeMetaModel.getAllPropertyMetaModels().stream()
.filter(mm -> mm.getName().equals(name))
.findFirst();
if (!optionalPropertyMetaModel.isPresent()) {
deferredJsonValues.put(name, nodeJson.get(name));
continue;
}
PropertyMetaModel propertyMetaModel = optionalPropertyMetaModel.get();
if (propertyMetaModel.isNodeList()) {
JsonArray nodeListJson = nodeJson.getJsonArray(name);
parameters.put(name, deserializeNodeList(nodeListJson));
} else if (propertyMetaModel.isNode()) {
parameters.put(name, deserializeObject(nodeJson.getJsonObject(name)));
} else {
Class<?> type = propertyMetaModel.getType();
if (type == String.class) {
parameters.put(name, nodeJson.getString(name));
} else if (type == boolean.class) {
parameters.put(name, Boolean.parseBoolean(nodeJson.getString(name)));
} else if (Enum.class.isAssignableFrom(type)) {
parameters.put(name, Enum.valueOf((Class<? extends Enum>) type, nodeJson.getString(name)));
} else {
throw new IllegalStateException("Don't know how to convert: " + type);
}
}
}
Node node = nodeMetaModel.construct(parameters);
// COMMENT is in the propertyKey meta model, but not required as constructor parameter.
// Set it after construction
if (parameters.containsKey(JsonNode.COMMENT.propertyKey)) {
node.setComment((Comment) parameters.get(JsonNode.COMMENT.propertyKey));
}
for (String name : deferredJsonValues.keySet()) {
if (!readNonMetaProperties(name, deferredJsonValues.get(name), node)) {
throw new IllegalStateException(
"Unknown propertyKey: " + nodeMetaModel.getQualifiedClassName() + "." + name);
}
}
setSymbolResolverIfCompilationUnit(node);
return node;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
private NodeList<?> deserializeNodeList(JsonArray nodeListJson) {
return nodeListJson.stream()
.map(nodeJson -> deserializeObject((JsonObject) nodeJson))
.collect(toNodeList());
}
/**
* Reads properties from json not included in meta model (i.e., RANGE and TOKEN_RANGE).
* When read, it sets the deserialized value to the node instance.
* @param name propertyKey name for json value
* @param jsonValue json value that needs to be deserialized for this propertyKey
* @param node instance to which the deserialized value will be set to
* @return true if propertyKey is read from json and set to Node instance
*/
protected boolean readNonMetaProperties(String name, JsonValue jsonValue, Node node) {
return readRange(name, jsonValue, node) || readTokenRange(name, jsonValue, node);
}
protected boolean readRange(String name, JsonValue jsonValue, Node node) {
if (name.equals(JsonNode.RANGE.propertyKey)) {
JsonObject jsonObject = (JsonObject) jsonValue;
Position begin = new Position(
jsonObject.getInt(JsonRange.BEGIN_LINE.propertyKey),
jsonObject.getInt(JsonRange.BEGIN_COLUMN.propertyKey));
Position end = new Position(
jsonObject.getInt(JsonRange.END_LINE.propertyKey),
jsonObject.getInt(JsonRange.END_COLUMN.propertyKey));
node.setRange(new Range(begin, end));
return true;
}
return false;
}
protected boolean readTokenRange(String name, JsonValue jsonValue, Node node) {
if (name.equals(JsonNode.TOKEN_RANGE.propertyKey)) {
JsonObject jsonObject = (JsonObject) jsonValue;
JavaToken begin = readToken(JsonTokenRange.BEGIN_TOKEN.propertyKey, jsonObject);
JavaToken end = readToken(JsonTokenRange.END_TOKEN.propertyKey, jsonObject);
node.setTokenRange(new TokenRange(begin, end));
return true;
}
return false;
}
protected JavaToken readToken(String name, JsonObject jsonObject) {
JsonObject tokenJson = jsonObject.getJsonObject(name);
return new JavaToken(
tokenJson.getInt(JsonToken.KIND.propertyKey), tokenJson.getString(JsonToken.TEXT.propertyKey));
}
/**
* This method sets symbol resolver to Node if it is an instance of CompilationUnit
* and a SymbolResolver is configured in the static configuration. This is necessary to be able to resolve symbols
* within the cu after deserialization. Normally, when parsing java with JavaParser, the symbol resolver is injected
* to the cu as a data element with key SYMBOL_RESOLVER_KEY.
* @param node instance to which symbol resolver will be set to when instance of a Compilation Unit
* @see com.github.javaparser.ast.Node#SYMBOL_RESOLVER_KEY
* @see com.github.javaparser.ParserConfiguration#ParserConfiguration()
*/
private void setSymbolResolverIfCompilationUnit(Node node) {
if (node instanceof CompilationUnit
&& StaticJavaParser.getConfiguration().getSymbolResolver().isPresent()) {
CompilationUnit cu = (CompilationUnit) node;
cu.setData(
Node.SYMBOL_RESOLVER_KEY,
StaticJavaParser.getConfiguration().getSymbolResolver().get());
}
}
}

View File

@@ -0,0 +1,201 @@
/*
* Copyright (C) 2007-2010 Júlio Vilmar Gesser.
* Copyright (C) 2011, 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.serialization;
import static com.github.javaparser.utils.Utils.decapitalize;
import static java.util.Objects.requireNonNull;
import com.github.javaparser.JavaToken;
import com.github.javaparser.Range;
import com.github.javaparser.TokenRange;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.metamodel.BaseNodeMetaModel;
import com.github.javaparser.metamodel.JavaParserMetaModel;
import com.github.javaparser.metamodel.PropertyMetaModel;
import com.github.javaparser.utils.Log;
import jakarta.json.stream.JsonGenerator;
/**
* Serializes an AST or a partial AST to JSON.
*/
public class JavaParserJsonSerializer {
/**
* Serializes node and all its children into json. Any node siblings will be ignored.
*
* @param node the node that will be the root level json object
* @param generator the json-p generator for writing the json
* @see <a href="https://javaee.github.io/jsonp/">json-p</a>
*/
public void serialize(Node node, JsonGenerator generator) {
requireNonNull(node);
Log.info("Serializing Node to JSON.");
try {
serialize(null, node, generator);
} finally {
generator.close();
}
}
/**
* Recursive depth-first method that serializes nodes into json
*
* @param nodeName nullable String. If null, it is the root object, otherwise it is the property key for the object
* @param node the current node to be serialized
* @param generator the json-p generator for writing the json
*/
private void serialize(String nodeName, Node node, JsonGenerator generator) {
requireNonNull(node);
BaseNodeMetaModel nodeMetaModel = JavaParserMetaModel.getNodeMetaModel(node.getClass())
.orElseThrow(() -> new IllegalStateException("Unknown Node: " + node.getClass()));
if (nodeName == null) {
generator.writeStartObject();
} else {
generator.writeStartObject(nodeName);
}
generator.write(JsonNode.CLASS.propertyKey, node.getClass().getName());
this.writeNonMetaProperties(node, generator);
for (PropertyMetaModel propertyMetaModel : nodeMetaModel.getAllPropertyMetaModels()) {
String name = propertyMetaModel.getName();
Object value = propertyMetaModel.getValue(node);
if (value != null) {
if (propertyMetaModel.isNodeList()) {
NodeList<Node> list = (NodeList<Node>) value;
generator.writeStartArray(name);
for (Node n : list) {
serialize(null, n, generator);
}
generator.writeEnd();
} else if (propertyMetaModel.isNode()) {
serialize(name, (Node) value, generator);
} else {
generator.write(name, value.toString());
}
}
}
generator.writeEnd();
}
/***
* This method writes json for properties not included in meta model (i.e., RANGE and TOKEN_RANGE).
* This method could be overriden so that - for example - tokens are not written to json to save space
*
* @see com.github.javaparser.metamodel.BaseNodeMetaModel#getAllPropertyMetaModels()
*/
protected void writeNonMetaProperties(Node node, JsonGenerator generator) {
this.writeRange(node, generator);
this.writeTokens(node, generator);
}
protected void writeRange(Node node, JsonGenerator generator) {
if (node.hasRange()) {
Range range = node.getRange().get();
generator.writeStartObject(JsonNode.RANGE.propertyKey);
generator.write(JsonRange.BEGIN_LINE.propertyKey, range.begin.line);
generator.write(JsonRange.BEGIN_COLUMN.propertyKey, range.begin.column);
generator.write(JsonRange.END_LINE.propertyKey, range.end.line);
generator.write(JsonRange.END_COLUMN.propertyKey, range.end.column);
generator.writeEnd();
}
}
protected void writeTokens(Node node, JsonGenerator generator) {
if (node.getTokenRange().isPresent()) {
TokenRange tokenRange = node.getTokenRange().get();
generator.writeStartObject(JsonNode.TOKEN_RANGE.propertyKey);
writeToken(JsonTokenRange.BEGIN_TOKEN.propertyKey, tokenRange.getBegin(), generator);
writeToken(JsonTokenRange.END_TOKEN.propertyKey, tokenRange.getEnd(), generator);
generator.writeEnd();
}
}
protected void writeToken(String name, JavaToken token, JsonGenerator generator) {
generator.writeStartObject(name);
generator.write(JsonToken.KIND.propertyKey, token.getKind());
generator.write(JsonToken.TEXT.propertyKey, token.getText());
generator.writeEnd();
}
/**
* excludes properties from meta model (except comment)
**/
public enum JsonNode {
RANGE("range"),
TOKEN_RANGE("tokenRange"),
COMMENT(decapitalize(JavaParserMetaModel.commentMetaModel.getTypeName())),
CLASS("!");
final String propertyKey;
JsonNode(String p) {
this.propertyKey = p;
}
public String toString() {
return this.propertyKey;
}
}
public enum JsonRange {
BEGIN_LINE("beginLine"),
BEGIN_COLUMN("beginColumn"),
END_LINE("endLine"),
END_COLUMN("endColumn");
final String propertyKey;
JsonRange(String p) {
this.propertyKey = p;
}
public String toString() {
return this.propertyKey;
}
}
public enum JsonTokenRange {
BEGIN_TOKEN("beginToken"),
END_TOKEN("endToken");
final String propertyKey;
JsonTokenRange(String p) {
this.propertyKey = p;
}
public String toString() {
return this.propertyKey;
}
}
public enum JsonToken {
TEXT("text"),
KIND("kind");
final String propertyKey;
JsonToken(String p) {
this.propertyKey = p;
}
public String toString() {
return this.propertyKey;
}
}
}

View File

@@ -0,0 +1,239 @@
/*
* Copyright (C) 2007-2010 Júlio Vilmar Gesser.
* Copyright (C) 2011, 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.serialization;
import static com.github.javaparser.StaticJavaParser.*;
import static com.github.javaparser.serialization.JavaParserJsonSerializerTest.serialize;
import static com.github.javaparser.utils.Utils.normalizeEolInTextBlock;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.github.javaparser.ParserConfiguration;
import com.github.javaparser.Range;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.TokenRange;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.comments.Comment;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.type.Type;
import com.github.javaparser.javadoc.Javadoc;
import com.github.javaparser.javadoc.JavadocBlockTag;
import com.github.javaparser.resolution.SymbolResolver;
import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
import com.github.javaparser.resolution.types.ResolvedType;
import com.github.javaparser.utils.LineSeparator;
import jakarta.json.Json;
import java.io.StringReader;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
class JavaParserJsonDeserializerTest {
private final JavaParserJsonDeserializer deserializer = new JavaParserJsonDeserializer();
@Test
void simpleTest() {
CompilationUnit cu = parse("public class X{} class Z{}");
String serialized = serialize(cu, false);
Node deserialized = deserializer.deserializeObject(Json.createReader(new StringReader(serialized)));
assertEqualsStringIgnoringEol("public class X {\n}\n\nclass Z {\n}\n", deserialized.toString());
assertEquals(cu.hashCode(), deserialized.hashCode());
}
@Test
void testRawType() {
Type type = parseType("Blub");
String serialized = serialize(type, false);
Node deserialized = deserializer.deserializeObject(Json.createReader(new StringReader(serialized)));
assertEqualsStringIgnoringEol("Blub", deserialized.toString());
assertEquals(type.hashCode(), deserialized.hashCode());
}
@Test
void testDiamondType() {
Type type = parseType("Blub<>");
String serialized = serialize(type, false);
Node deserialized = deserializer.deserializeObject(Json.createReader(new StringReader(serialized)));
assertEqualsStringIgnoringEol("Blub<>", deserialized.toString());
assertEquals(type.hashCode(), deserialized.hashCode());
}
@Test
void testGenerics() {
Type type = parseType("Blub<Blab, Bleb>");
String serialized = serialize(type, false);
Node deserialized = deserializer.deserializeObject(Json.createReader(new StringReader(serialized)));
assertEqualsStringIgnoringEol("Blub<Blab, Bleb>", deserialized.toString());
assertEquals(type.hashCode(), deserialized.hashCode());
}
@Test
void testOperator() {
Expression expr = parseExpression("1+1");
String serialized = serialize(expr, false);
Node deserialized = deserializer.deserializeObject(Json.createReader(new StringReader(serialized)));
assertEqualsStringIgnoringEol("1 + 1", deserialized.toString());
assertEquals(expr.hashCode(), deserialized.hashCode());
}
@Test
void testPrimitiveType() {
Type type = parseType("int");
String serialized = serialize(type, false);
Node deserialized = deserializer.deserializeObject(Json.createReader(new StringReader(serialized)));
assertEqualsStringIgnoringEol("int", deserialized.toString());
assertEquals(type.hashCode(), deserialized.hashCode());
}
@Test
void testComment() {
CompilationUnit cu = parse("/* block comment */\npublic class X{ \n // line comment\npublic void test() {}\n}");
String serialized = serialize(cu, false);
CompilationUnit deserialized =
(CompilationUnit) deserializer.deserializeObject(Json.createReader(new StringReader(serialized)));
ClassOrInterfaceDeclaration classXDeclaration =
deserialized.getClassByName("X").get();
assertTrue(classXDeclaration.getComment().isPresent());
Comment comment = classXDeclaration.getComment().get();
assertEquals(
"com.github.javaparser.ast.comments.BlockComment",
comment.getClass().getName());
assertEquals(" block comment ", comment.getContent());
MethodDeclaration methodDeclaration = classXDeclaration.getMethods().get(0);
assertTrue(methodDeclaration.getComment().isPresent());
assertEquals(
"com.github.javaparser.ast.comments.LineComment",
methodDeclaration.getComment().get().getClass().getName());
assertEquals(" line comment", methodDeclaration.getComment().get().getContent());
}
@Test
void testJavaDocComment() {
CompilationUnit cu = parse("public class X{ " + " /**\n"
+ " * Woke text.\n"
+ " * @param a blub\n"
+ " * @return true \n"
+ " */"
+ " public boolean test(int a) { return true; }\n"
+ "}");
String serialized = serialize(cu, false);
CompilationUnit deserialized =
(CompilationUnit) deserializer.deserializeObject(Json.createReader(new StringReader(serialized)));
ClassOrInterfaceDeclaration classDeclaration =
deserialized.getClassByName("X").get();
MethodDeclaration methodDeclaration = classDeclaration.getMethods().get(0);
assertTrue(methodDeclaration.getJavadoc().isPresent());
Javadoc javadoc = methodDeclaration.getJavadoc().get();
JavadocBlockTag paramBlockTag = javadoc.getBlockTags().get(0);
assertEquals("param", paramBlockTag.getTagName());
assertEquals("blub", paramBlockTag.getContent().toText());
JavadocBlockTag returnBlockTag = javadoc.getBlockTags().get(1);
assertEquals("return", returnBlockTag.getTagName());
assertEquals("true", returnBlockTag.getContent().toText());
}
@Test
void testNonMetaProperties() {
CompilationUnit cu = parse("public class X{} class Z{}");
String serialized = serialize(cu, false);
CompilationUnit deserialized =
(CompilationUnit) deserializer.deserializeObject(Json.createReader(new StringReader(serialized)));
assertTrue(deserialized.hasRange());
Range range = deserialized.getRange().get();
assertEquals(1, range.begin.line);
assertEquals(1, range.begin.line);
assertEquals(26, range.end.column);
assertTrue(deserialized.getTokenRange().isPresent());
TokenRange tokenRange = deserialized.getTokenRange().get();
assertEquals("public", tokenRange.getBegin().getText());
assertEquals("", tokenRange.getEnd().getText());
}
@Test
void testAttachingSymbolResolver() {
SymbolResolver stubResolver = new SymbolResolver() {
@Override
public <T> T resolveDeclaration(Node node, Class<T> resultClass) {
return null;
}
@Override
public <T> T toResolvedType(Type javaparserType, Class<T> resultClass) {
return null;
}
@Override
public ResolvedType calculateType(Expression expression) {
return null;
}
@Override
public ResolvedReferenceTypeDeclaration toTypeDeclaration(Node node) {
return null;
}
};
StaticJavaParser.getConfiguration().setSymbolResolver(stubResolver);
CompilationUnit cu = parse("public class X{} class Z{}");
String serialized = serialize(cu, false);
CompilationUnit deserialized =
(CompilationUnit) deserializer.deserializeObject(Json.createReader(new StringReader(serialized)));
assertTrue(deserialized.containsData(Node.SYMBOL_RESOLVER_KEY));
assertEquals(stubResolver, deserialized.getData(Node.SYMBOL_RESOLVER_KEY));
}
@AfterAll
static void clearConfiguration() {
StaticJavaParser.setConfiguration(new ParserConfiguration());
}
/**
* Assert that "actual" equals "expected", and that any EOL characters in "actual" are correct for the platform.
*/
private static void assertEqualsStringIgnoringEol(String expected, String actual) {
assertEquals(
normalizeEolInTextBlock(expected, LineSeparator.ARBITRARY),
normalizeEolInTextBlock(actual, LineSeparator.ARBITRARY));
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2007-2010 Júlio Vilmar Gesser.
* Copyright (C) 2011, 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.serialization;
import static com.github.javaparser.StaticJavaParser.parse;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import jakarta.json.Json;
import jakarta.json.stream.JsonGenerator;
import jakarta.json.stream.JsonGeneratorFactory;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.Test;
class JavaParserJsonSerializerTest {
@Test
void test() {
CompilationUnit cu = parse("class X{java.util.Y y;}");
String serialized = serialize(cu, false);
assertEquals(
"{\"!\":\"com.github.javaparser.ast.CompilationUnit\",\"range\":{\"beginLine\":1,\"beginColumn\":1,\"endLine\":1,\"endColumn\":23},\"tokenRange\":{\"beginToken\":{\"kind\":19,\"text\":\"class\"},\"endToken\":{\"kind\":0,\"text\":\"\"}},\"imports\":[],\"types\":[{\"!\":\"com.github.javaparser.ast.body.ClassOrInterfaceDeclaration\",\"range\":{\"beginLine\":1,\"beginColumn\":1,\"endLine\":1,\"endColumn\":23},\"tokenRange\":{\"beginToken\":{\"kind\":19,\"text\":\"class\"},\"endToken\":{\"kind\":104,\"text\":\"}\"}},\"extendedTypes\":[],\"implementedTypes\":[],\"isInterface\":\"false\",\"permittedTypes\":[],\"typeParameters\":[],\"members\":[{\"!\":\"com.github.javaparser.ast.body.FieldDeclaration\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":22},\"tokenRange\":{\"beginToken\":{\"kind\":98,\"text\":\"java\"},\"endToken\":{\"kind\":107,\"text\":\";\"}},\"modifiers\":[],\"variables\":[{\"!\":\"com.github.javaparser.ast.body.VariableDeclarator\",\"range\":{\"beginLine\":1,\"beginColumn\":21,\"endLine\":1,\"endColumn\":21},\"tokenRange\":{\"beginToken\":{\"kind\":98,\"text\":\"y\"},\"endToken\":{\"kind\":98,\"text\":\"y\"}},\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":21,\"endLine\":1,\"endColumn\":21},\"tokenRange\":{\"beginToken\":{\"kind\":98,\"text\":\"y\"},\"endToken\":{\"kind\":98,\"text\":\"y\"}},\"identifier\":\"y\"},\"type\":{\"!\":\"com.github.javaparser.ast.type.ClassOrInterfaceType\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":19},\"tokenRange\":{\"beginToken\":{\"kind\":98,\"text\":\"java\"},\"endToken\":{\"kind\":98,\"text\":\"Y\"}},\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":19,\"endLine\":1,\"endColumn\":19},\"tokenRange\":{\"beginToken\":{\"kind\":98,\"text\":\"Y\"},\"endToken\":{\"kind\":98,\"text\":\"Y\"}},\"identifier\":\"Y\"},\"scope\":{\"!\":\"com.github.javaparser.ast.type.ClassOrInterfaceType\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":17},\"tokenRange\":{\"beginToken\":{\"kind\":98,\"text\":\"java\"},\"endToken\":{\"kind\":98,\"text\":\"util\"}},\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":14,\"endLine\":1,\"endColumn\":17},\"tokenRange\":{\"beginToken\":{\"kind\":98,\"text\":\"util\"},\"endToken\":{\"kind\":98,\"text\":\"util\"}},\"identifier\":\"util\"},\"scope\":{\"!\":\"com.github.javaparser.ast.type.ClassOrInterfaceType\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":12},\"tokenRange\":{\"beginToken\":{\"kind\":98,\"text\":\"java\"},\"endToken\":{\"kind\":98,\"text\":\"java\"}},\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":9,\"endLine\":1,\"endColumn\":12},\"tokenRange\":{\"beginToken\":{\"kind\":98,\"text\":\"java\"},\"endToken\":{\"kind\":98,\"text\":\"java\"}},\"identifier\":\"java\"},\"annotations\":[]},\"annotations\":[]},\"annotations\":[]}}],\"annotations\":[]}],\"modifiers\":[],\"name\":{\"!\":\"com.github.javaparser.ast.expr.SimpleName\",\"range\":{\"beginLine\":1,\"beginColumn\":7,\"endLine\":1,\"endColumn\":7},\"tokenRange\":{\"beginToken\":{\"kind\":98,\"text\":\"X\"},\"endToken\":{\"kind\":98,\"text\":\"X\"}},\"identifier\":\"X\"},\"annotations\":[]}]}",
serialized);
}
static String serialize(Node node, boolean prettyPrint) {
Map<String, ?> config = new HashMap<>();
if (prettyPrint) {
config.put(JsonGenerator.PRETTY_PRINTING, null);
}
JsonGeneratorFactory generatorFactory = Json.createGeneratorFactory(config);
JavaParserJsonSerializer serializer = new JavaParserJsonSerializer();
StringWriter jsonWriter = new StringWriter();
try (JsonGenerator generator = generatorFactory.createGenerator(jsonWriter)) {
serializer.serialize(node, generator);
}
return jsonWriter.toString();
}
}