Skip to content

Commit

Permalink
Fix bugs in Parser
Browse files Browse the repository at this point in the history
 * Fix `Parser` incorrectly recognizing values as pointers when `const` is placed after type (issue #173)
 * Add `Parser` support for C++11 `using` declarations that act as `typedef` (issue #169)
 * Let `Parser` accept variables initialized with parentheses (issue #179)
 * Fix `Parser` confusion between attributes and namespace-less templates (issue #181)
  • Loading branch information
saudet committed May 14, 2017
1 parent 89e91f1 commit b5378cf
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 10 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@

* Fix `Parser` incorrectly recognizing values as pointers when `const` is placed after type ([issue #173](https://github.com/bytedeco/javacpp/issues/173))
* Add `Parser` support for C++11 `using` declarations that act as `typedef` ([issue #169](https://github.com/bytedeco/javacpp/issues/169))
* Let `Parser` accept variables initialized with parentheses ([issue #179](https://github.com/bytedeco/javacpp/issues/179))
* Fix `Parser` confusion between attributes and namespace-less templates ([issue #181](https://github.com/bytedeco/javacpp/issues/181))
* Fix issue with `Loader.getCallerClass()` when a `SecurityManager` cannot be created ([issue #176](https://github.com/bytedeco/javacpp/issues/176))
* Make it possible to rename enumerators of C++ `enum class` ([issue #180](https://github.com/bytedeco/javacpp/issues/180))
* Make the arbitrary resources available to process executed with `Builder.buildCommand` via the `BUILD_PATH` environment variable
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/bytedeco/javacpp/tools/Generator.java
Original file line number Diff line number Diff line change
Expand Up @@ -3213,10 +3213,10 @@ String[] cppCastTypeName(Class<?> type, Annotation ... annotations) {
}
typeName = cppTypeName(type);
boolean[] b = ((Const)a).value();
if (b.length > 1 && b[1]) {
if (b.length > 1 && b[1] && !typeName[0].endsWith(" const *")) {
typeName[0] = valueTypeName(typeName) + " const *";
}
if (b.length > 0 && b[0]) {
if (b.length > 0 && b[0] && !typeName[0].startsWith("const ")) {
typeName[0] = "const " + typeName[0];
}
Annotation by = by(annotations);
Expand Down
43 changes: 35 additions & 8 deletions src/main/java/org/bytedeco/javacpp/tools/Parser.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2013-2016 Samuel Audet
* Copyright (C) 2013-2017 Samuel Audet
*
* Licensed either under the Apache License, Version 2.0, or (at your option)
* under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -451,7 +451,9 @@ Type type(Context context) throws ParserException {
}
type.cppName += type.cppName.endsWith(">") ? " >" : ">";
} else if (token.match(Token.CONST, Token.CONSTEXPR)) {
if (type.cppName.length() == 0) {
int template = type.cppName.lastIndexOf('<');
String simpleName = template >= 0 ? type.cppName.substring(0, template) : type.cppName;
if (!simpleName.trim().contains(" ") || type.simple) {
type.constValue = true;
} else {
type.constPointer = true;
Expand Down Expand Up @@ -1003,8 +1005,8 @@ Declarator declarator(Context context, String defaultName, int infoNumber, boole
needCast |= info.cast && !type.cppName.equals(type.javaName);
}

if (!valueType) {
if (dcl.indirections == 0 && !dcl.reference) {
if (!valueType || context.virtualize) {
if (!valueType && dcl.indirections == 0 && !dcl.reference) {
type.annotations += "@ByVal ";
} else if (dcl.indirections == 0 && dcl.reference) {
if (type.javaName.contains("@ByPtrPtr ")) {
Expand Down Expand Up @@ -1389,7 +1391,8 @@ String commentAfter() throws ParserException {
}

Attribute attribute() throws ParserException {
if (!tokens.get().match(Token.IDENTIFIER)) {
// attributes might have arguments that start with '(', but not '<'
if (!tokens.get().match(Token.IDENTIFIER) || tokens.get(1).match('<')) {
return null;
}
Attribute attr = new Attribute();
Expand Down Expand Up @@ -1555,6 +1558,12 @@ Parameters parameters(Context context, int infoNumber, boolean useDefaults) thro
tokens.next();
}
}
if (dcls.size() == 1 && (dcls.get(0) == null || dcls.get(0).type == null
|| dcls.get(0).type.cppName == null || dcls.get(0).type.cppName.length() == 0)) {
// this looks more like a variable initialization
tokens.index = backIndex;
return null;
}
params.declarators = dcls.toArray(new Declarator[dcls.size()]);
return params;
}
Expand Down Expand Up @@ -1828,7 +1837,7 @@ boolean variable(Context context, DeclarationList declList) throws ParserExcepti
Declaration decl = new Declaration();
String cppName = dcl.cppName;
String javaName = dcl.javaName;
if (javaName == null || !tokens.get().match('[', '=', ',', ':', ';')) {
if (javaName == null || !tokens.get().match('(', '[', '=', ',', ':', ';')) {
tokens.index = backIndex;
return false;
} else if (!dcl.type.staticMember && context.javaName != null) {
Expand Down Expand Up @@ -2138,11 +2147,22 @@ boolean macro(Context context, DeclarationList declList) throws ParserException

boolean typedef(Context context, DeclarationList declList) throws ParserException {
String spacing = tokens.get().spacing;
if (!tokens.get().match(Token.TYPEDEF)) {
// the "using" token can also act as a "typedef"
String usingDefName = tokens.get().match(Token.USING) && tokens.get(1).match(Token.IDENTIFIER)
&& tokens.get(2).match('=') ? tokens.get(1).value : null;
if (!tokens.get().match(Token.TYPEDEF) && usingDefName == null) {
return false;
}
Declaration decl = new Declaration();
if (usingDefName != null) {
tokens.next().expect(Token.IDENTIFIER);
tokens.next().expect('=');
tokens.next();
}
Declarator dcl = declarator(context, null, 0, false, 0, true, false);
if (usingDefName != null) {
dcl.cppName = usingDefName;
}
tokens.next();

String typeName = dcl.type.cppName, defName = dcl.cppName;
Expand Down Expand Up @@ -2210,7 +2230,14 @@ boolean typedef(Context context, DeclarationList declList) throws ParserExceptio
info.pointerTypes(typeName);
}
if (info.annotations == null) {
info.cast(!dcl.cppName.equals(info.pointerTypes[0]));
if (dcl.type.annotations != null && dcl.type.annotations.length() > 0
&& !dcl.type.annotations.startsWith("@ByVal ")
&& !dcl.type.annotations.startsWith("@Cast(")
&& !dcl.type.annotations.startsWith("@Const ")) {
info.annotations(dcl.type.annotations.trim());
} else {
info.cast(!dcl.cppName.equals(info.pointerTypes[0]));
}
}
infoMap.put(info);
}
Expand Down

0 comments on commit b5378cf

Please sign in to comment.