j3.27.0.0 working
This commit is contained in:
@@ -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>
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user