Skip to content

Commit 88ab130

Browse files
committed
0.18.1 - fix C# 'typeof(...)' annotation/attribute parsing
1 parent bb033bc commit 88ab130

File tree

8 files changed

+47
-13
lines changed

8 files changed

+47
-13
lines changed

CHANGELOG.md

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

55

66
--------
7-
### [0.18.0](N/A) - 2019-03-30
7+
### [0.18.1](N/A) - 2019-07-02
8+
#### Fixed
9+
* `AnnotationExtractor` to handle C# `typeof(T)` annotation arguments
10+
11+
12+
--------
13+
### [0.18.0](https://github.com/TeamworkGuy2/JParseCode/commit/bb033bcc4cffc4382a20d7f2394976e087690557) - 2019-03-30
814
#### Changed
915
* Added `-debug` and `-threads #` command line arguments
1016
* More detailed debug and log file information

bin/jparse_code-with-tests.jar

182 Bytes
Binary file not shown.

bin/jparse_code.jar

411 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.18.0",
2+
"version" : "0.18.1",
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/parser/codeParser/extractors/AnnotationExtractor.java

+18-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.HashMap;
44

55
import twg2.ast.interm.annotation.AnnotationSig;
6+
import twg2.parser.codeParser.csharp.CsKeyword;
67
import twg2.parser.codeParser.tools.NameUtil;
78
import twg2.parser.fragment.CodeToken;
89
import twg2.parser.fragment.CodeTokenType;
@@ -27,15 +28,20 @@ public static AnnotationSig parseAnnotationBlock(CodeLanguage lang, CodeTokenTyp
2728
var paramChilds = annotParamsNode != null ? annotParamsNode.getChildren() : null;
2829
int size = paramChilds != null ? paramChilds.size() : 0;
2930

30-
if(annotNameType != CodeTokenType.IDENTIFIER) { throw new IllegalArgumentException("annotation node expected to contain identifier, found '" + annotName + "'"); }
31+
if(annotNameType != CodeTokenType.IDENTIFIER) {
32+
throw new IllegalArgumentException("annotation node expected to contain identifier, found '" + annotName + "'");
33+
}
3134

3235
var params = new HashMap<String, String>();
3336
boolean firstParamUnnamed = false;
3437

3538
// parse an annotation '(arguments, ...)'
3639
if(size > 0) {
40+
var operatorUtil = lang.getOperatorUtil();
3741
var annotParamsBlock = annotParamsNode.getData();
38-
if(annotParamsBlock.getTokenType() != CodeTokenType.BLOCK) { throw new IllegalArgumentException("annotation node expected to contain identifier, found '" + annotParamsBlock.getText() + "'"); }
42+
if(annotParamsBlock.getTokenType() != CodeTokenType.BLOCK) {
43+
throw new IllegalArgumentException("annotation node expected to contain identifier, found " + annotParamsBlock.getTokenType() + " '" + annotParamsBlock.getText() + "'");
44+
}
3945

4046
// += 2, for the value and the separator
4147
for(int i = 0; i < size; i++) {
@@ -44,7 +50,7 @@ public static AnnotationSig parseAnnotationBlock(CodeLanguage lang, CodeTokenTyp
4450
String paramName = null;
4551

4652
// parse and step over named arguments, i.e. 'Annotation(id = "...")'
47-
if(paramType == CodeTokenType.IDENTIFIER && i < size - 2 && paramChilds.get(i + 1).getData().getTokenType() == CodeTokenType.OPERATOR && lang.getOperatorUtil().assignmentOperators().is(paramChilds.get(i + 1).getData())) {
53+
if(paramType == CodeTokenType.IDENTIFIER && i < size - 2 && paramChilds.get(i + 1).getData().getTokenType() == CodeTokenType.OPERATOR && operatorUtil.assignmentOperators().is(paramChilds.get(i + 1).getData())) {
4854
paramName = param.getText();
4955
i += 2;
5056
param = paramChilds.get(i).getData();
@@ -70,18 +76,26 @@ else if(paramType == CodeTokenType.STRING) {
7076
String valueStr = StringTrim.trimQuotes(param.getText());
7177

7278
// handles concatenated strings 'Annotation(name = 'a' + 'b')
73-
if(i + 2 < size && lang.getOperatorUtil().concatOperators().is(paramChilds.get(i + 1).getData()) && paramChilds.get(i + 2).getData().getTokenType() == CodeTokenType.STRING) {
79+
if(i + 2 < size && operatorUtil.concatOperators().is(paramChilds.get(i + 1).getData()) && paramChilds.get(i + 2).getData().getTokenType() == CodeTokenType.STRING) {
7480
valueStr = valueStr + StringTrim.trimQuotes(paramChilds.get(i + 2).getData().getText());
7581
i += 2;
7682
}
7783

7884
params.put(paramName, valueStr);
7985
}
8086
else if(paramType == CodeTokenType.KEYWORD) {
87+
if(param.getText().toUpperCase().contains("TYPEOF")) {
88+
System.out.println("test");
89+
}
8190
// type-literal-keyword: 'Annotation(true)'
8291
if(lang.getKeywordUtil().typeLiterals().is(param)) {
8392
params.put(paramName, param.getText());
8493
}
94+
// hack for C# typeof(T) in annotation parameter lists
95+
else if(CsKeyword.TYPEOF.toSrc().equals(param.getText()) && i + 1 < size && CodeTokenType.BLOCK == paramChilds.get(i + 1).getData().getTokenType()) {
96+
params.put(paramName, param.getText() + paramChilds.get(i + 1).getData().getText());
97+
i++;
98+
}
8599
}
86100
// catches other things like 'Annotation(Integer.TYPE)' or 'Annotation(String.class)'
87101
else if(paramType == CodeTokenType.IDENTIFIER) {

src/twg2/parser/codeParser/tools/CodeTokenEnumSubSet.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import twg2.parser.fragment.CodeToken;
77
import twg2.parser.fragment.CodeTokenType;
88

9-
/**
9+
/** An {@link EnumSubSet} for {@link CodeTokenType}
1010
* @author TeamworkGuy2
1111
* @since 2016-4-12
1212
*/
@@ -31,6 +31,10 @@ public CodeTokenEnumSubSet(CodeTokenType expectedType, Iterable<E> enums, Predic
3131
}
3232

3333

34+
/** Check whether a {@link CodeToken}'s type matches the expected type of this enum subset and the the CodeToken's text is contained in this enum subset
35+
* @param node check the CodeToken's {@link CodeToken#getText()}
36+
* @return whether the token text is found in this enum subset
37+
*/
3438
public boolean is(CodeToken node) {
3539
if(node != null && node.getTokenType() == this.expectedType) {
3640
return super.find(node.getText()) != null;
@@ -39,6 +43,10 @@ public boolean is(CodeToken node) {
3943
}
4044

4145

46+
/** Parse a {@link CodeToken}'s text against this enum subset and return the matching value
47+
* @param node parse the CodeToken's {@link CodeToken#getText()}
48+
* @return the enum subset value matching the token's text or null if no matching value found for the enum name
49+
*/
4250
public E parse(CodeToken node) {
4351
if(node != null && node.getTokenType() == this.expectedType) {
4452
return super.find(node.getText());

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public class CsClassParseTest {
5656
" [IntAnnotation(-1)]",
5757
" [BoolAnnotation(true)]",
5858
" [IdentifierAnnotation(Integer.TYPE)]",
59+
" [IdentifierAnnotation(typeof(Dictionary<String, Integer>))]",
5960
" [StringAnnotation(Name = \"\")]",
6061
" [MultiArgAnnotation(\"abc\", false , 1.23)]",
6162
" [MultiNamedArgAnnotation(num =1.23, flag=false ,value = \"abc\")]",
@@ -160,12 +161,14 @@ public void simpleCsParseTest() {
160161
assertAnnotation(as, 2, "BoolAnnotation", new String[] { "value" }, "true");
161162
// annotation: IdentifierAnnotation(Integer.TYPE)
162163
assertAnnotation(as, 3, "IdentifierAnnotation", new String[] { "value" }, "Integer.TYPE");
164+
// annotation: IdentifierAnnotation(typeof(Dictionary<String, Integer>))
165+
assertAnnotation(as, 4, "IdentifierAnnotation", new String[] { "value" }, "typeof(Dictionary<String, Integer>)");
163166
// annotation: StringAnnotation(Name = "")
164-
assertAnnotation(as, 4, "StringAnnotation", new String[] { "Name" }, "");
167+
assertAnnotation(as, 5, "StringAnnotation", new String[] { "Name" }, "");
165168
// annotation: MultiArgAnnotation(\"abc\", false, 1.23)
166-
assertAnnotation(as, 5, "MultiArgAnnotation", new String[] { "arg1", "arg2", "arg3" }, "abc", "false", "1.23");
169+
assertAnnotation(as, 6, "MultiArgAnnotation", new String[] { "arg1", "arg2", "arg3" }, "abc", "false", "1.23");
167170
// annotations: MultiNamedArgAnnotation(num =1.23, flag=false ,value = "abc")
168-
assertAnnotation(as, 6, "MultiNamedArgAnnotation", new String[] { "num", "flag", "value" }, "1.23", "false", "abc");
171+
assertAnnotation(as, 7, "MultiNamedArgAnnotation", new String[] { "num", "flag", "value" }, "1.23", "false", "abc");
169172

170173
assertField(fs, 1, fullClassName + "._name", "string");
171174
assertField(fs, 2, fullClassName + ".Names", ary("IList", ary("string")));

test/twg2/parser/codeParser/test/JavaClassParseTest.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public class JavaClassParseTest {
5656
" @IntAnnotation(-1)",
5757
" @BoolAnnotation(true)",
5858
" @IdentifierAnnotation(Integer.TYPE)",
59+
" @IdentifierAnnotation(Map.class)",
5960
" @StringAnnotation(Name = \"\")",
6061
" @MultiArgAnnotation(\"abc\", false , 1.23)",
6162
" @MultiNamedArgAnnotation(num =1.23, flag=false ,value = \"abc\")",
@@ -146,12 +147,14 @@ public void simpleJavaParseTest() {
146147
assertAnnotation(as, 2, "BoolAnnotation", new String[] { "value" }, "true");
147148
// annotations: IdentifierAnnotation(Integer.TYPE)
148149
assertAnnotation(as, 3, "IdentifierAnnotation", new String[] { "value" }, "Integer.TYPE");
150+
// annotations: IdentifierAnnotation(Map.class)
151+
assertAnnotation(as, 4, "IdentifierAnnotation", new String[] { "value" }, "Map.class");
149152
// annotations: StringAnnotation(Name = "")
150-
assertAnnotation(as, 4, "StringAnnotation", new String[] { "Name" }, "");
153+
assertAnnotation(as, 5, "StringAnnotation", new String[] { "Name" }, "");
151154
// annotations: MultiArgAnnotation("abc", false , 1.23)
152-
assertAnnotation(as, 5, "MultiArgAnnotation", new String[] { "arg1", "arg2", "arg3" }, "abc", "false", "1.23");
155+
assertAnnotation(as, 6, "MultiArgAnnotation", new String[] { "arg1", "arg2", "arg3" }, "abc", "false", "1.23");
153156
// annotations: MultiNamedArgAnnotation(num =1.23, flag=false ,value = "abc")
154-
assertAnnotation(as, 6, "MultiNamedArgAnnotation", new String[] { "num", "flag", "value" }, "1.23", "false", "abc");
157+
assertAnnotation(as, 7, "MultiNamedArgAnnotation", new String[] { "num", "flag", "value" }, "1.23", "false", "abc");
155158

156159
assertField(fields, 1, fullClassName + "._name", "String");
157160
assertField(fields, 2, fullClassName + ".Names", ary("List", ary("String")));

0 commit comments

Comments
 (0)