Skip to content

Commit 7cf3562

Browse files
committed
0.23.0 - Field initializer parsing. Better C# property block '{ get; set; }'and annotation parsing. And several new unit tests.
1 parent 0007395 commit 7cf3562

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1365
-657
lines changed

CHANGELOG.md

+29-2
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,40 @@ This project does its best to adhere to [Semantic Versioning](http://semver.org/
44

55

66
--------
7-
### [0.22.0](N/A) - 2020-04-18
7+
### [0.23.0](N/A) - 2021-06-28
8+
#### Added
9+
* Lots of additional unit tests
10+
* `TypeExtractor.isSimpleLiteral()` used to determine whether a `FieldDef.initializer` should be serialized as a literal value `"initializer"` or an `"initializerExpression"`
11+
12+
#### Changed
13+
* `FieldExtractor` now parses field default value assignments and returns `FieldDef` instead of `FieldSig` (`FieldDef` contains `initializer` field)
14+
* `FieldExtractor` constructor requires a new 3rd parameter, an `OperatorUtil<>`
15+
* `ClassAst` remove `T_ENUM` type parameter, enum members in a parsed enum will be represented by `T_FIELD`
16+
* `FieldDef.initializerToJson()` signature changed significantly to support new multiple token initializer expressions
17+
* `AccessModifierParser` and `AccessModifierEnum` removed `parseFromSrc()`, cleaned up code, added documentation
18+
* `AccessModifierParser` `tryParseFromSrc(String)` and `defaultAccessModifier(String, ...)` modified to takes `List<String>` for correctness and to simplify call sites
19+
* `AstExtractor.createFieldParser()` and implementations (`CsBlock` and `JavaBlock`) now return `AstParser<List<FieldDef>>` instead of `...FieldSig`
20+
* `BlockUtil` `parseKeyword()` and `tryParseKeyword()` replaced with `tryToBlock()`
21+
* `CsBlockParser._extractBlocksFromTree()` renamed `extractBlocksFromTree()` (which was already public)
22+
* `AstParser` added `blockComplete()` with empty default implementation, will be called by `BlockExtractor`
23+
24+
#### Removed
25+
* Merged `FieldSig` and `FieldSigResolved` into `FieldDef` and `FieldDefResolved`
26+
27+
#### Fixed
28+
* C# annotation parsing fixed to handle multiple annotations in the same block, i.e. '[Annotation(One), Annotation(Two), ...]'
29+
* An issue with nested classes/interfaces getting assigned the incorrect access modifiers
30+
* An issue with complex generic type parsing
31+
32+
33+
--------
34+
### [0.22.0](https://github.com/TeamworkGuy2/JParseCode/commit/0007395d8a4d53de3690ef5ef4e452f6256b5ea0) - 2021-04-18
835
#### Removed
936
* `ProjectClassSet` `resolveSimpleName()` in favor of moving the two lines of code to the single calling location
1037

1138
#### Fixed
1239
* C# full type name resolution fixed to resolve against the parent namespaces the class resides in (affects types in class signatures, method signatures, and fields)
13-
* Java class signature parsing fixed to support both `extends` and implements in the same signature `implements` (can't believe I overlooked this and didn't have a unit test)
40+
* Java class signature parsing fixed to support both `extends` and `implements` in the same signature (can't believe I overlooked this and didn't have a unit test!)
1441

1542

1643
--------

bin/jparse_code-with-tests.jar

13.4 KB
Binary file not shown.

bin/jparse_code.jar

13 KB
Binary file not shown.

package-lib.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version" : "0.22.0",
2+
"version" : "0.23.0",
33
"name" : "jparse-code",
44
"description" : "An in-progress suite of parsing/transpilation tools for C#, Java, and TypeScript code. Generates simple JSON ASTs.",
55
"homepage" : "https://github.com/TeamworkGuy2/JParseCode",

rsc/csharp/ParserExamples/Models/TrackInfo.cs

+8
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,13 @@ public void GetObjectData(SerializationInfo info, StreamingContext context) {
4040
public TType Refresh<TType>(TType tt) where TType : IConvertible {
4141
return tt;
4242
}
43+
44+
45+
class ArtistMeta
46+
{
47+
public string Name;
48+
Guid guid;
49+
protected int referenceCount;
50+
}
4351
}
4452
}

rsc/java/ParserExamples/Models/TrackInfo.java

+7
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,11 @@ public <TType extends Number> TType refresh(TType tt) {
3838
return tt;
3939
}
4040

41+
42+
class ArtistMeta {
43+
public String Name;
44+
Guid guid;
45+
protected int referenceCount;
46+
}
47+
4148
}

src/twg2/ast/interm/classes/ClassAst.java

+8-10
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
import twg2.annotations.Immutable;
88
import twg2.ast.interm.field.FieldDef;
99
import twg2.ast.interm.field.FieldDefResolved;
10-
import twg2.ast.interm.field.FieldSig;
11-
import twg2.ast.interm.field.FieldSigResolved;
1210
import twg2.ast.interm.method.MethodSigResolved;
1311
import twg2.ast.interm.method.MethodSigSimple;
1412
import twg2.ast.interm.method.ParameterSig;
@@ -38,23 +36,23 @@ public interface ClassAst<T_SIG extends ClassSig, T_BLOCK extends BlockType> ext
3836
* @since 2015-12-4
3937
*/
4038
@Immutable
41-
public static class Impl<T_SIG extends ClassSig, T_ENUM extends JsonWritableSig, T_FIELD extends JsonWritableSig, T_METHOD extends JsonWritableSig, T_PARAM extends JsonWritableSig, T_BLOCK extends BlockType>
39+
public static class Impl<T_SIG extends ClassSig, T_FIELD extends JsonWritableSig, T_METHOD extends JsonWritableSig, T_PARAM extends JsonWritableSig, T_BLOCK extends BlockType>
4240
implements ClassAst<T_SIG, T_BLOCK> {
4341
private final @Getter T_SIG signature;
4442
private final @Getter List<List<String>> usingStatements;
45-
private final @Getter List<T_ENUM> enumMembers;
43+
private final @Getter List<T_FIELD> enumMembers;
4644
private final @Getter List<T_FIELD> fields;
4745
private final @Getter List<T_METHOD> methods;
4846
private final @Getter T_BLOCK blockType;
4947

5048

51-
public Impl(T_SIG signature, List<List<String>> usingStatements, List<? extends T_FIELD> fields, List<? extends T_METHOD> methods, List<? extends T_ENUM> enums, T_BLOCK blockType) {
49+
public Impl(T_SIG signature, List<List<String>> usingStatements, List<? extends T_FIELD> fields, List<? extends T_METHOD> methods, List<? extends T_FIELD> enums, T_BLOCK blockType) {
5250
@SuppressWarnings("unchecked")
5351
var fieldsCast = (List<T_FIELD>)fields;
5452
@SuppressWarnings("unchecked")
5553
var methodsCast = (List<T_METHOD>)methods;
5654
@SuppressWarnings("unchecked")
57-
var enumsCast = (List<T_ENUM>)enums;
55+
var enumsCast = (List<T_FIELD>)enums;
5856

5957
this.signature = signature;
6058
this.usingStatements = usingStatements;
@@ -124,9 +122,9 @@ public String toString() {
124122
* @since 2016-1-2
125123
*/
126124
@Immutable
127-
public static class SimpleImpl<T_BLOCK extends BlockType> extends Impl<ClassSigSimple, FieldDef, FieldSig, MethodSigSimple, ParameterSig, T_BLOCK> {
125+
public static class SimpleImpl<T_BLOCK extends BlockType> extends Impl<ClassSigSimple, FieldDef, MethodSigSimple, ParameterSig, T_BLOCK> {
128126

129-
public SimpleImpl(ClassSigSimple signature, List<List<String>> usingStatements, List<? extends FieldSig> fields,
127+
public SimpleImpl(ClassSigSimple signature, List<List<String>> usingStatements, List<? extends FieldDef> fields,
130128
List<? extends MethodSigSimple> methods, List<? extends FieldDef> enums, T_BLOCK blockType) {
131129
super(signature, usingStatements, fields, methods, enums, blockType);
132130
}
@@ -141,9 +139,9 @@ public SimpleImpl(ClassSigSimple signature, List<List<String>> usingStatements,
141139
* @since 2015-12-4
142140
*/
143141
@Immutable
144-
public static class ResolvedImpl<T_BLOCK extends BlockType> extends Impl<ClassSigResolved, FieldDefResolved, FieldSigResolved, MethodSigResolved, ParameterSigResolved, T_BLOCK> {
142+
public static class ResolvedImpl<T_BLOCK extends BlockType> extends Impl<ClassSigResolved, FieldDefResolved, MethodSigResolved, ParameterSigResolved, T_BLOCK> {
145143

146-
public ResolvedImpl(ClassSigResolved signature, List<List<String>> usingStatements, List<? extends FieldSigResolved> fields,
144+
public ResolvedImpl(ClassSigResolved signature, List<List<String>> usingStatements, List<? extends FieldDefResolved> fields,
147145
List<? extends MethodSigResolved> methods, List<? extends FieldDefResolved> enums, T_BLOCK blockType) {
148146
super(signature, usingStatements, fields, methods, enums, blockType);
149147
}

src/twg2/ast/interm/field/FieldDef.java

+81-33
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,51 @@
22

33
import java.io.IOException;
44
import java.util.List;
5+
import java.util.concurrent.atomic.AtomicBoolean;
56

67
import lombok.Getter;
78
import twg2.annotations.Immutable;
89
import twg2.ast.interm.annotation.AnnotationSig;
10+
import twg2.ast.interm.type.TypeSig;
911
import twg2.ast.interm.type.TypeSig.TypeSigSimple;
1012
import twg2.io.json.stringify.JsonStringify;
1113
import twg2.parser.codeParser.Keyword;
1214
import twg2.parser.codeParser.extractors.TypeExtractor;
1315
import twg2.parser.codeParser.tools.NameUtil;
1416
import twg2.parser.fragment.CodeToken;
15-
import twg2.parser.fragment.CodeTokenType;
17+
import twg2.parser.output.JsonWritableSig;
1618
import twg2.parser.output.WriteSettings;
1719
import twg2.text.stringEscape.StringEscapeJson;
1820
import twg2.treeLike.simpleTree.SimpleTree;
1921

20-
/** A {@link FieldSig} with an initializer
22+
/** A class field definition, contains the field name, full name, type, access modifiers, annotations, comments, and initializer (if present)
2123
* @author TeamworkGuy2
2224
* @since 2016-09-04
2325
*/
2426
@Immutable
25-
public class FieldDef extends FieldSig {
26-
private final @Getter SimpleTree<CodeToken> initializer;
27-
28-
29-
public FieldDef(String name, List<String> fullName, TypeSigSimple fieldType, List<Keyword> accessModifiers,
30-
List<AnnotationSig> annotations, List<String> comments, SimpleTree<CodeToken> initializer) {
31-
super(name, fullName, fieldType, accessModifiers, annotations, comments);
27+
public class FieldDef implements JsonWritableSig {
28+
final @Getter String name;
29+
final @Getter List<String> fullName;
30+
final @Getter TypeSig.TypeSigSimple fieldType;
31+
final @Getter List<Keyword> accessModifiers;
32+
final @Getter List<AnnotationSig> annotations;
33+
final @Getter List<String> comments;
34+
final @Getter List<SimpleTree<CodeToken>> initializer;
35+
36+
37+
public FieldDef(String name, List<String> fullName, TypeSigSimple fieldType, List<? extends Keyword> accessModifiers,
38+
List<? extends AnnotationSig> annotations, List<String> comments, List<SimpleTree<CodeToken>> initializer) {
39+
@SuppressWarnings("unchecked")
40+
var accessModifiersCast = (List<Keyword>)accessModifiers;
41+
@SuppressWarnings("unchecked")
42+
var annotationsCast = (List<AnnotationSig>)annotations;
43+
44+
this.name = name;
45+
this.fullName = fullName;
46+
this.fieldType = fieldType;
47+
this.accessModifiers = accessModifiersCast;
48+
this.annotations = annotationsCast;
49+
this.comments = comments;
3250
this.initializer = initializer;
3351
}
3452

@@ -51,7 +69,7 @@ public void toJson(Appendable dst, WriteSettings st) throws IOException {
5169
.toArrayConsume(annotations, dst, (ann) -> ann.toJson(dst, st));
5270
}
5371

54-
initializerToJson(initializer, true, dst, st);
72+
initializerToJson(initializer, true, true, dst, st);
5573

5674
json.comma(dst).propName("comments", dst)
5775
.toStringArray(comments, dst);
@@ -69,39 +87,69 @@ public String toString() {
6987
/** Write a field initializer to a JSON field named 'initializer' if the value is a number, boolean, string, or null literal, else write it to a field named 'initializerExpression'
7088
* @throws IOException
7189
*/
72-
public static void initializerToJson(SimpleTree<CodeToken> astNode, boolean preClosingComma, Appendable dst, WriteSettings st) throws IOException {
73-
CodeToken data = null;
74-
boolean isNumOrBoolOrNull = false;
75-
if(astNode != null && !astNode.hasChildren() && (data = astNode.getData()) != null &&
76-
(data.getTokenType() == CodeTokenType.STRING ||
77-
(isNumOrBoolOrNull = TypeExtractor.isDefaultValueLiteral(data)))) {
78-
if(preClosingComma) {
79-
dst.append(", ");
80-
}
81-
dst.append("\"initializer\": ");
82-
if(isNumOrBoolOrNull) {
83-
dst.append(data.getText());
90+
public static void initializerToJson(List<SimpleTree<CodeToken>> astNodes, boolean preClosingComma, boolean includePropName, Appendable dst, WriteSettings st) throws IOException {
91+
AtomicBoolean isNumOrBoolOrNull = new AtomicBoolean(false);
92+
int astNodeCount = astNodes != null ? astNodes.size() : 0;
93+
if(astNodeCount > 0) {
94+
var text = TypeExtractor.isSimpleLiteral(astNodes, isNumOrBoolOrNull::set);
95+
if(text != null) {
96+
if(preClosingComma) {
97+
dst.append(", ");
98+
}
99+
if(includePropName) {
100+
dst.append("\"initializer\": ");
101+
}
102+
if(isNumOrBoolOrNull.get()) {
103+
dst.append(text);
104+
}
105+
else {
106+
dst.append('"');
107+
dst.append(StringEscapeJson.toJsonString(text));
108+
dst.append('"');
109+
}
84110
}
85111
else {
112+
if(preClosingComma) {
113+
dst.append(", ");
114+
}
115+
if(includePropName) {
116+
dst.append("\"initializerExpression\": ");
117+
}
86118
dst.append('"');
87-
dst.append(StringEscapeJson.toJsonString(data.getText()));
119+
CodeToken data;
120+
for(var astNode : astNodes) {
121+
if((data = astNode.getData()) != null) {
122+
dst.append(StringEscapeJson.toJsonString(data.getText()));
123+
}
124+
}
88125
dst.append('"');
89126
}
90127
}
91-
else if(astNode != null && astNode.hasChildren()) {
92-
if(preClosingComma) {
93-
dst.append(", ");
94-
}
95-
dst.append("\"initializerExpression\": ");
96-
if((data = astNode.getData()) != null && !TypeExtractor.isNullLiteral(data)) {
97-
dst.append('"');
98-
dst.append(StringEscapeJson.toJsonString(data.getText()));
99-
dst.append('"');
128+
}
129+
130+
131+
/** Convert a field initializer to a string
132+
*/
133+
public static String initializerToString(List<SimpleTree<CodeToken>> astNodes) {
134+
AtomicBoolean isNumOrBoolOrNull = new AtomicBoolean(false);
135+
int astNodeCount = astNodes != null ? astNodes.size() : 0;
136+
if(astNodeCount > 0) {
137+
var text = TypeExtractor.isSimpleLiteral(astNodes, isNumOrBoolOrNull::set);
138+
if(text != null) {
139+
return text;
100140
}
101141
else {
102-
dst.append(null);
142+
CodeToken data;
143+
text = "";
144+
for(var astNode : astNodes) {
145+
if((data = astNode.getData()) != null) {
146+
text += data.getText();
147+
}
148+
}
149+
return text;
103150
}
104151
}
152+
return null;
105153
}
106154

107155
}

src/twg2/ast/interm/field/FieldDefResolved.java

+27-9
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,44 @@
66
import lombok.Getter;
77
import twg2.annotations.Immutable;
88
import twg2.ast.interm.annotation.AnnotationSig;
9+
import twg2.ast.interm.type.TypeSig;
910
import twg2.ast.interm.type.TypeSig.TypeSigResolved;
1011
import twg2.io.json.stringify.JsonStringify;
1112
import twg2.parser.codeParser.Keyword;
1213
import twg2.parser.codeParser.tools.NameUtil;
1314
import twg2.parser.fragment.CodeToken;
15+
import twg2.parser.output.JsonWritableSig;
1416
import twg2.parser.output.WriteSettings;
1517
import twg2.treeLike.simpleTree.SimpleTree;
1618

17-
/** A {@link FieldSigResolved} with an initializer
19+
/** A {@link FieldDef} resolved (i.e. with fully qualifying name and type names) with an initializer
1820
* @author TeamworkGuy2
1921
* @since 2016-09-04
2022
*/
2123
@Immutable
22-
public class FieldDefResolved extends FieldSigResolved {
23-
private final @Getter SimpleTree<CodeToken> initializer;
24-
25-
26-
public FieldDefResolved(String name, List<String> fullName, TypeSigResolved fieldType, List<Keyword> accessModifiers,
27-
List<AnnotationSig> annotations, List<String> comments, SimpleTree<CodeToken> initializer) {
28-
super(name, fullName, fieldType, accessModifiers, annotations, comments);
24+
public class FieldDefResolved implements JsonWritableSig {
25+
final @Getter String name;
26+
final @Getter List<String> fullName;
27+
final @Getter TypeSig.TypeSigResolved fieldType;
28+
final @Getter List<Keyword> accessModifiers;
29+
final @Getter List<AnnotationSig> annotations;
30+
final @Getter List<String> comments;
31+
final @Getter List<SimpleTree<CodeToken>> initializer;
32+
33+
34+
public FieldDefResolved(String name, List<String> fullName, TypeSigResolved fieldType, List<? extends Keyword> accessModifiers,
35+
List<? extends AnnotationSig> annotations, List<String> comments, List<SimpleTree<CodeToken>> initializer) {
36+
@SuppressWarnings("unchecked")
37+
var accessModifiersCast = (List<Keyword>)accessModifiers;
38+
@SuppressWarnings("unchecked")
39+
var annotationsCast = (List<AnnotationSig>)annotations;
40+
41+
this.name = name;
42+
this.fullName = fullName;
43+
this.fieldType = fieldType;
44+
this.accessModifiers = accessModifiersCast;
45+
this.annotations = annotationsCast;
46+
this.comments = comments;
2947
this.initializer = initializer;
3048
}
3149

@@ -48,7 +66,7 @@ public void toJson(Appendable dst, WriteSettings st) throws IOException {
4866
.toArrayConsume(annotations, dst, (ann) -> ann.toJson(dst, st));
4967
}
5068

51-
FieldDef.initializerToJson(initializer, true, dst, st);
69+
FieldDef.initializerToJson(initializer, true, true, dst, st);
5270

5371
json.comma(dst).propName("comments", dst)
5472
.toStringArray(comments, dst);

0 commit comments

Comments
 (0)