Skip to content

Commit d14366d

Browse files
committed
0.15.6 - Support parameter default values, update unit tests.
1 parent b1176a9 commit d14366d

22 files changed

+129
-81
lines changed

CHANGELOG.md

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

55

66
--------
7-
### [0.15.5](N/A) - 2018-09-14
7+
### [0.15.6](N/A) - 2018-09-22
8+
#### Added
9+
* Parameter default value parsing support added to `MethodParametersParser`
10+
* Added `DataTypeExtractor.isDefaultValueLiteral()` to check for field/parameter default values
11+
12+
#### Changed
13+
* Renamed `CsKeyword.Inst` -> `CsKeyword.CsKeywordUtil`
14+
* Renamed `JavaKeyword.Inst` -> `JavaKeyword.JavaKeywordUtil`
15+
* Unit tests changed to use static imports of `TypeAssert.ary()` instead of `new Object[] {...}` and `TypeAssert.ls()` instead of `Arrays.asList()`
16+
17+
18+
--------
19+
### [0.15.5](https://github.com/TeamworkGuy2/JParseCode/commit/cac4e10c769b47ec3b73e2e716befc19ab1876f4) - 2018-09-14
820
#### Changed
921
* `ParserWorkFlow` returns the `-help` message if no arguments are given when run
1022

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
JParseCode
22
==============
3-
version: 0.15.5
3+
version: 0.15.6
44

55
In progress C#/Java/TypeScript parser tools built atop [JTextParser](https://github.com/TeamworkGuy2/JTextParser), [Jackson](https://github.com/FasterXML/jackson-core/) (core, databind, annotations) and half a dozen other utility libraries.
66

bin/jparse_code-with-tests.jar

914 Bytes
Binary file not shown.

bin/jparse_code.jar

729 Bytes
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.15.5",
2+
"version" : "0.15.6",
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",

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public static void initializerToJson(SimpleTree<CodeToken> astNode, boolean preC
7373
boolean isNumOrBoolOrNull = false;
7474
if(astNode != null && !astNode.hasChildren() && (data = astNode.getData()) != null &&
7575
(data.getTokenType() == CodeTokenType.STRING ||
76-
(isNumOrBoolOrNull = (data.getTokenType() == CodeTokenType.NUMBER || DataTypeExtractor.isBooleanLiteral(data) || DataTypeExtractor.isNullLiteral(data))))) {
76+
(isNumOrBoolOrNull = DataTypeExtractor.isDefaultValueLiteral(data)))) {
7777
if(preClosingComma) {
7878
dst.append(", ");
7979
}

src/twg2/parser/codeParser/csharp/CsBlockParser.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public AstParser<List<FieldSig>> createFieldParser(BlockAst<CsBlock> block, AstP
8484
public AstParser<List<MethodSigSimple>> createMethodParser(BlockAst<CsBlock> block, AstParser<List<AnnotationSig>> annotationParser, AstParser<List<String>> commentParser) {
8585
val lang = CodeLanguageOptions.C_SHARP;
8686
val typeParser = new DataTypeExtractor(lang, true);
87-
return new MethodExtractor(lang.displayName(), CsKeyword.check, block, typeParser, annotationParser, commentParser);
87+
return new MethodExtractor(lang.displayName(), CsKeyword.check, lang.getOperatorUtil(), block, typeParser, annotationParser, commentParser);
8888
}
8989

9090

src/twg2/parser/codeParser/csharp/CsKeyword.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public enum CsKeyword implements AccessModifier {
9494
WHILE("while");
9595

9696

97-
public static final CsKeyword.Inst check = new CsKeyword.Inst();
97+
public static final CsKeyword.CsKeywordUtil check = new CsKeyword.CsKeywordUtil();
9898

9999
public final String srcName;
100100
public final boolean isType;
@@ -146,7 +146,7 @@ public String toSrc() {
146146
* @since 2016-1-14
147147
*/
148148
@Accessors(fluent = true)
149-
public static class Inst implements KeywordUtil<CsKeyword> {
149+
public static class CsKeywordUtil implements KeywordUtil<CsKeyword> {
150150
public final String[] keywords;
151151
private final CsKeyword[] values;
152152
private final String[] primitives;

src/twg2/parser/codeParser/extractors/DataTypeExtractor.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -129,20 +129,27 @@ public static <T> boolean isPossiblyType(KeywordUtil<? extends AccessModifier> k
129129
}
130130

131131

132-
/** Check if a tree node is a boolean literal
132+
/** Check if a {@link CodeToken} is a boolean literal
133133
*/
134134
public static boolean isBooleanLiteral(CodeToken node) {
135135
return node.getTokenType() == CodeTokenType.KEYWORD && ("true".equals(node.getText()) || "false".equals(node.getText()));
136136
}
137137

138138

139-
/** Check if a tree node is a null literal
139+
/** Check if a {@link CodeToken} is a null literal
140140
*/
141141
public static boolean isNullLiteral(CodeToken node) {
142142
return node.getTokenType() == CodeTokenType.KEYWORD && "null".equals(node.getText());
143143
}
144144

145145

146+
/** Check if a {@link CodeToken} is a numeric literal, a boolean literal, or a null literal
147+
*/
148+
public static boolean isDefaultValueLiteral(CodeToken node) {
149+
return (node.getTokenType() == CodeTokenType.NUMBER || DataTypeExtractor.isBooleanLiteral(node) || DataTypeExtractor.isNullLiteral(node));
150+
}
151+
152+
146153
/** Check if one or two nodes are a number with an optional -/+ sign
147154
* @param node1
148155
* @param node2Optional

src/twg2/parser/codeParser/extractors/MethodExtractor.java

+7-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import twg2.parser.codeParser.AccessModifier;
1212
import twg2.parser.codeParser.BlockType;
1313
import twg2.parser.codeParser.KeywordUtil;
14+
import twg2.parser.codeParser.Operator;
15+
import twg2.parser.codeParser.OperatorUtil;
1416
import twg2.parser.codeParser.tools.NameUtil;
1517
import twg2.parser.fragment.AstFragType;
1618
import twg2.parser.fragment.CodeToken;
@@ -37,6 +39,7 @@ static enum State {
3739

3840

3941
KeywordUtil<? extends AccessModifier> keywordUtil;
42+
OperatorUtil<? extends Operator> operatorUtil;
4043
AstParser<List<AnnotationSig>> annotationParser;
4144
AstParser<List<String>> commentParser;
4245
AstParser<TypeSig.TypeSigSimple> typeParser;
@@ -51,10 +54,11 @@ static enum State {
5154
* @param annotationParser this annotation parser should be being run external from this instance. When this instance finds a method signature,
5255
* the annotation parser should already contain results (i.e. {@link AstParser#getParserResult()}) for the method's annotations
5356
*/
54-
public MethodExtractor(String langName, KeywordUtil<? extends AccessModifier> keywordUtil, BlockAst<? extends BlockType> parentBlock,
57+
public MethodExtractor(String langName, KeywordUtil<? extends AccessModifier> keywordUtil, OperatorUtil<? extends Operator> operatorUtil, BlockAst<? extends BlockType> parentBlock,
5558
AstParser<TypeSig.TypeSigSimple> typeParser, AstParser<List<AnnotationSig>> annotationParser, AstParser<List<String>> commentParser) {
5659
super(langName, "method signature", parentBlock, State.COMPLETE, State.FAILED);
5760
this.keywordUtil = keywordUtil;
61+
this.operatorUtil = operatorUtil;
5862
this.methods = new ArrayList<>();
5963
this.typeParser = typeParser;
6064
this.annotationParser = annotationParser;
@@ -170,7 +174,7 @@ private Consume findingParams(SimpleTree<CodeToken> tokenNode) {
170174
val comments = new ArrayList<>(commentParser.getParserResult());
171175
commentParser.recycle();
172176

173-
val params = MethodParametersParser.extractParamsFromSignature(keywordUtil, annotationParser, tokenNode);
177+
val params = MethodParametersParser.extractParamsFromSignature(keywordUtil, operatorUtil, annotationParser, tokenNode);
174178
val accessMods = new ArrayList<>(accessModifiers);
175179
annotationParser.recycle();
176180

@@ -199,7 +203,7 @@ public MethodExtractor recycle() {
199203

200204
@Override
201205
public MethodExtractor copy() {
202-
val copy = new MethodExtractor(this.langName, this.keywordUtil, this.parentBlock, this.typeParser.copy(), this.annotationParser.copy(), this.commentParser.copy());
206+
val copy = new MethodExtractor(this.langName, this.keywordUtil, this.operatorUtil, this.parentBlock, this.typeParser.copy(), this.annotationParser.copy(), this.commentParser.copy());
203207
return copy;
204208
}
205209

src/twg2/parser/codeParser/extractors/MethodParametersParser.java

+18-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import twg2.ast.interm.method.ParameterSig;
1010
import twg2.parser.codeParser.AccessModifier;
1111
import twg2.parser.codeParser.KeywordUtil;
12+
import twg2.parser.codeParser.Operator;
13+
import twg2.parser.codeParser.OperatorUtil;
1214
import twg2.parser.fragment.CodeToken;
1315
import twg2.parser.fragment.CodeTokenType;
1416
import twg2.parser.stateMachine.AstParser;
@@ -21,7 +23,8 @@
2123
public class MethodParametersParser {
2224

2325
// TODO does not support default parameters
24-
public static List<ParameterSig> extractParamsFromSignature(KeywordUtil<? extends AccessModifier> keywordUtil, AstParser<List<AnnotationSig>> annotationParser, SimpleTree<CodeToken> sigNode) {
26+
public static List<ParameterSig> extractParamsFromSignature(KeywordUtil<? extends AccessModifier> keywordUtil, OperatorUtil<? extends Operator> operatorUtil,
27+
AstParser<List<AnnotationSig>> annotationParser, SimpleTree<CodeToken> sigNode) {
2528
val childs = sigNode.getChildren();
2629
int size = childs.size();
2730

@@ -64,6 +67,7 @@ public static List<ParameterSig> extractParamsFromSignature(KeywordUtil<? extend
6467
}
6568
i = annotationCompletedAt;
6669

70+
// read parameter type and name
6771
token = childs.get(i + 0).getData();
6872

6973
val type = token.getText();
@@ -76,10 +80,21 @@ public static List<ParameterSig> extractParamsFromSignature(KeywordUtil<? extend
7680
// each parameter is expected to have 2, so jump the optional one
7781
i++;
7882
}
83+
84+
val name = childs.get(i + 1).getData().getText();
85+
86+
// read parameter default value if available
87+
String defaultValue = null;
88+
if(i + 3 < size && (token = childs.get(i + 2).getData()).getTokenType() == CodeTokenType.OPERATOR && operatorUtil.assignmentOperators().is(token)) {
89+
if(DataTypeExtractor.isDefaultValueLiteral(token = childs.get(i + 3).getData())) {
90+
defaultValue = token.getText();
91+
i += 2;
92+
}
93+
}
94+
7995
List<AnnotationSig> annotations = annotationParser.getParserResult();
8096
annotations = annotations.size() > 0 ? new ArrayList<>(annotations) : null;
81-
val name = childs.get(i + 1).getData().getText();
82-
val param = new ParameterSig(name, type, paramMods, annotations, optional, null);
97+
val param = new ParameterSig(name, type, paramMods, annotations, optional, defaultValue);
8398
params.add(param);
8499
}
85100

src/twg2/parser/codeParser/java/JavaBlockParser.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public AstParser<List<FieldSig>> createFieldParser(BlockAst<JavaBlock> block, As
8383
public AstParser<List<MethodSigSimple>> createMethodParser(BlockAst<JavaBlock> block, AstParser<List<AnnotationSig>> annotationParser, AstParser<List<String>> commentParser) {
8484
val lang = CodeLanguageOptions.JAVA;
8585
val typeParser = new DataTypeExtractor(lang, true);
86-
return new MethodExtractor(lang.displayName(), JavaKeyword.check, block, typeParser, annotationParser, commentParser);
86+
return new MethodExtractor(lang.displayName(), JavaKeyword.check, lang.getOperatorUtil(), block, typeParser, annotationParser, commentParser);
8787
}
8888

8989

src/twg2/parser/codeParser/java/JavaKeyword.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public enum JavaKeyword implements AccessModifier {
7070
WHILE("while");
7171

7272

73-
public static final Inst check = new JavaKeyword.Inst();
73+
public static final JavaKeywordUtil check = new JavaKeyword.JavaKeywordUtil();
7474

7575
public final String srcName;
7676
public final boolean isType;
@@ -118,7 +118,7 @@ public String toSrc() {
118118

119119

120120
@Accessors(fluent = true)
121-
public static class Inst implements KeywordUtil<JavaKeyword> {
121+
public static class JavaKeywordUtil implements KeywordUtil<JavaKeyword> {
122122
public final String[] keywords;
123123
private final JavaKeyword[] values;
124124
private final String[] primitives;

test/twg2/parser/codeParser/test/CsClassParseTest.java

+16-14
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
import static twg2.parser.test.utils.FieldAssert.assertField;
55
import static twg2.parser.test.utils.MethodAssert.assertParameter;
66
import static twg2.parser.test.utils.TypeAssert.assertType;
7+
import static twg2.parser.test.utils.TypeAssert.ary;
78
import static twg2.parser.test.utils.TypeAssert.ls;
89

910
import java.io.IOException;
1011
import java.nio.file.Paths;
11-
import java.util.Arrays;
1212
import java.util.Collections;
1313
import java.util.List;
1414
import java.util.Map.Entry;
@@ -41,7 +41,7 @@
4141
* @since 2016-1-1
4242
*/
4343
public class CsClassParseTest {
44-
private static List<String> srcLines = Arrays.asList(
44+
private static List<String> srcLines = ls(
4545
"namespace ParserExamples.Samples {",
4646
"",
4747
" /// <summary>",
@@ -111,7 +111,7 @@ public class CsClassParseTest {
111111
private CodeFileAndAst<CsBlock> simpleCs = CodeFileAndAst.<CsBlock>parse(CodeLanguageOptions.C_SHARP, "SimpleCs.cs", "ParserExamples.Samples.SimpleCs", true, srcLines);
112112

113113
@Parameter
114-
private CodeFileSrc file = ParseCodeFile.parseFiles(Arrays.asList(Paths.get("rsc/csharp/ParserExamples/Models/TrackInfo.cs")), FileReadUtil.threadLocalInst(), null).get(0);
114+
private CodeFileSrc file = ParseCodeFile.parseFiles(ls(Paths.get("rsc/csharp/ParserExamples/Models/TrackInfo.cs")), FileReadUtil.threadLocalInst(), null).get(0);
115115

116116

117117
public CsClassParseTest() throws IOException {
@@ -128,6 +128,8 @@ public void parseBlocksTest() {
128128
ClassAst.SimpleImpl<CsBlock> trackInfoBlock = blocks.get(0).getValue();
129129
Assert.assertEquals(CsBlock.CLASS, trackInfoBlock.getBlockType());
130130
Assert.assertEquals("TrackInfo", trackInfoBlock.getSignature().getSimpleName());
131+
132+
Assert.assertEquals(ls("ISerializable", "IComparable<TrackInfo>"), trackInfoBlock.getSignature().getExtendImplementSimpleNames());
131133
}
132134

133135

@@ -145,9 +147,9 @@ public void simpleCsParseTest() {
145147

146148
List<FieldSig> fs = clas.getFields();
147149
assertField(fs, 0, fullClassName + ".mod", "int");
148-
Assert.assertEquals(Arrays.asList(" <value>The modification count.</value>\n"), fs.get(0).getComments());
149-
// annotation: EmptyAnnotation()
150+
Assert.assertEquals(ls(" <value>The modification count.</value>\n"), fs.get(0).getComments());
150151
List<AnnotationSig> as = fs.get(0).getAnnotations();
152+
// annotation: EmptyAnnotation()
151153
assertAnnotation(as, 0, "EmptyAnnotation", new String[0], new String[0]);
152154
// annotation: IntAnnotation(-1)
153155
assertAnnotation(as, 1, "IntAnnotation", new String[] { "value" }, "-1");
@@ -163,7 +165,7 @@ public void simpleCsParseTest() {
163165
assertAnnotation(as, 6, "MultiNamedArgAnnotation", new String[] { "num", "flag", "value" }, "1.23", "false", "abc");
164166

165167
assertField(fs, 1, fullClassName + "._name", "string");
166-
assertField(fs, 2, fullClassName + ".Names", ls("IList", ls("string")));
168+
assertField(fs, 2, fullClassName + ".Names", ary("IList", ary("string")));
167169
assertField(fs, 3, fullClassName + ".Count", "int");
168170
assertField(fs, 4, fullClassName + ".C2", "float");
169171
assertField(fs, 5, fullClassName + ".C3", "decimal");
@@ -175,13 +177,13 @@ public void simpleCsParseTest() {
175177
// AddName(...)
176178
MethodSigSimple m = clas.getMethods().get(0);
177179
Assert.assertEquals(fullClassName + ".AddName", NameUtil.joinFqName(m.fullName));
178-
Assert.assertEquals(Arrays.asList(" <summary>Add name</summary>\n",
180+
Assert.assertEquals(ls(" <summary>Add name</summary>\n",
179181
" <param name=\"name\">the name</param>\n",
180182
" <returns>the names</returns>\n"), m.comments);
181183
List<ParameterSig> ps = m.paramSigs;
182184
Assert.assertEquals(2, ps.size());
183-
assertParameter(ps, 0, "name", "string", null, Arrays.asList(new AnnotationSig("NotNull", NameUtil.splitFqName("NotNull"), Collections.emptyMap())));
184-
assertParameter(ps, 1, "zest", "int", null, null);
185+
assertParameter(ps, 0, "name", "string", null, null, ls(new AnnotationSig("NotNull", NameUtil.splitFqName("NotNull"), Collections.emptyMap())));
186+
assertParameter(ps, 1, "zest", "int", "0", null, null);
185187
// annotations:
186188
//{"name": "OperationContract", "arguments": { } },
187189
assertAnnotation(m.annotations, 0, "OperationContract", new String[0], new String[0]);
@@ -193,15 +195,15 @@ public void simpleCsParseTest() {
193195
assertAnnotation(m.annotations, 2, "TransactionFlow", new String[] { "value" }, new String[] { "TransactionFlowOption.Allowed" });
194196

195197
//returnType: {"typeName": "Result", "genericParameters": [ {"typeName": "IList", "genericParameters": [ {"typeName": "String"}]}]}
196-
assertType(ls("Result", ls("IList", ls("String"))), m.returnType);
198+
assertType(ary("Result", ary("IList", ary("String"))), m.returnType);
197199

198200
// SetNames(...)
199201
m = clas.getMethods().get(1);
200202
Assert.assertEquals(fullClassName + ".SetNames", NameUtil.joinFqName(m.fullName));
201-
List<ParameterSig> params = m.paramSigs;
202-
assertParameter(params, 0, "inst", "SimpleCs", Arrays.asList(CsKeyword.THIS), null);
203-
assertParameter(params, 1, "constraints", "Constraints", Arrays.asList(CsKeyword.REF), null);
204-
assertParameter(params, 2, "names", "string[]", Arrays.asList(CsKeyword.PARAMS), null);
203+
ps = m.paramSigs;
204+
assertParameter(ps, 0, "inst", "SimpleCs", null, ls(CsKeyword.THIS), null);
205+
assertParameter(ps, 1, "constraints", "Constraints", null, ls(CsKeyword.REF), null);
206+
assertParameter(ps, 2, "names", "string[]", null, ls(CsKeyword.PARAMS), null);
205207
}
206208

207209
}

test/twg2/parser/codeParser/test/CsEnumParseTest.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package twg2.parser.codeParser.test;
22

3-
import java.util.Arrays;
3+
import static twg2.parser.test.utils.TypeAssert.ls;
4+
45
import java.util.List;
56

67
import org.junit.Assert;
@@ -21,7 +22,7 @@
2122
* @since 2016-1-1
2223
*/
2324
public class CsEnumParseTest {
24-
private static final CodeFileAndAst<CsBlock> simpleEnumCs = CodeFileAndAst.<CsBlock>parse(CodeLanguageOptions.C_SHARP, "SimpleEnumCs.cs", "ParserExamples.Samples.SimpleEnumCs", true, Arrays.asList(
25+
private static final CodeFileAndAst<CsBlock> simpleEnumCs = CodeFileAndAst.<CsBlock>parse(CodeLanguageOptions.C_SHARP, "SimpleEnumCs.cs", "ParserExamples.Samples.SimpleEnumCs", true, ls(
2526
"namespace ParserExamples.Samples {",
2627
"",
2728
" /// <summary>",
@@ -55,7 +56,7 @@ public void simpleEnumCsParseTest() {
5556
FieldSig f = enums.get(0);
5657
Assert.assertEquals(fullClassName + ".Fields", NameUtil.joinFqName(f.getFullName()));
5758
Assert.assertEquals("short", f.getFieldType().getTypeName());
58-
Assert.assertEquals(Arrays.asList(" <value>The fields enum</value>\n"), f.getComments());
59+
Assert.assertEquals(ls(" <value>The fields enum</value>\n"), f.getComments());
5960

6061
f = enums.get(1);
6162
Assert.assertEquals(fullClassName + ".Methods", NameUtil.joinFqName(f.getFullName()));
@@ -64,7 +65,7 @@ public void simpleEnumCsParseTest() {
6465
f = enums.get(2);
6566
Assert.assertEquals(fullClassName + ".Classes", NameUtil.joinFqName(f.getFullName()));
6667
Assert.assertEquals("short", f.getFieldType().getTypeName());
67-
Assert.assertEquals(Arrays.asList(" <value>The classes enum</value>\n"), f.getComments());
68+
Assert.assertEquals(ls(" <value>The classes enum</value>\n"), f.getComments());
6869
}
6970

7071
}

0 commit comments

Comments
 (0)