Commit 19c81b11 authored by Masato Nagai's avatar Masato Nagai Committed by Wouter van Oortmerssen

[C++] better type mismatch error (#4623)

* better parse error

* pass str as a pointer instead of a reference for more efficient performance
parent 36f85648
...@@ -647,11 +647,11 @@ class Parser : public ParserState { ...@@ -647,11 +647,11 @@ class Parser : public ParserState {
size_t fieldn, size_t fieldn,
const StructDef *parent_struct_def); const StructDef *parent_struct_def);
FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes); FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes);
FLATBUFFERS_CHECKED_ERROR TryTypedValue(int dtoken, bool check, Value &e, FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken, bool check, Value &e,
BaseType req, bool *destmatch); BaseType req, bool *destmatch);
FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef* field); FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef* field);
FLATBUFFERS_CHECKED_ERROR TokenError(); FLATBUFFERS_CHECKED_ERROR TokenError();
FLATBUFFERS_CHECKED_ERROR ParseSingleValue(Value &e); FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e);
FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(Type &type, int64_t *result); FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(Type &type, int64_t *result);
StructDef *LookupCreateStruct(const std::string &name, StructDef *LookupCreateStruct(const std::string &name,
bool create_if_new = true, bool create_if_new = true,
......
...@@ -648,7 +648,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) { ...@@ -648,7 +648,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
if (token_ == '=') { if (token_ == '=') {
NEXT(); NEXT();
ECHECK(ParseSingleValue(field->value)); ECHECK(ParseSingleValue(&field->name, field->value));
if (!IsScalar(type.base_type) || if (!IsScalar(type.base_type) ||
(struct_def.fixed && field->value.constant != "0")) (struct_def.fixed && field->value.constant != "0"))
return Error( return Error(
...@@ -878,11 +878,11 @@ CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field, ...@@ -878,11 +878,11 @@ CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
(token_ == kTokenIdentifier || token_ == kTokenStringConstant)) { (token_ == kTokenIdentifier || token_ == kTokenStringConstant)) {
ECHECK(ParseHash(val, field)); ECHECK(ParseHash(val, field));
} else { } else {
ECHECK(ParseSingleValue(val)); ECHECK(ParseSingleValue(field ? &field->name : nullptr, val));
} }
break; break;
} }
default: ECHECK(ParseSingleValue(val)); break; default: ECHECK(ParseSingleValue(field ? &field->name : nullptr, val)); break;
} }
return NoError(); return NoError();
} }
...@@ -1201,7 +1201,7 @@ CheckedError Parser::ParseMetaData(SymbolTable<Value> *attributes) { ...@@ -1201,7 +1201,7 @@ CheckedError Parser::ParseMetaData(SymbolTable<Value> *attributes) {
attributes->Add(name, e); attributes->Add(name, e);
if (Is(':')) { if (Is(':')) {
NEXT(); NEXT();
ECHECK(ParseSingleValue(*e)); ECHECK(ParseSingleValue(&name, *e));
} }
if (Is(')')) { if (Is(')')) {
NEXT(); NEXT();
...@@ -1213,7 +1213,7 @@ CheckedError Parser::ParseMetaData(SymbolTable<Value> *attributes) { ...@@ -1213,7 +1213,7 @@ CheckedError Parser::ParseMetaData(SymbolTable<Value> *attributes) {
return NoError(); return NoError();
} }
CheckedError Parser::TryTypedValue(int dtoken, bool check, Value &e, CheckedError Parser::TryTypedValue(const std::string *name, int dtoken, bool check, Value &e,
BaseType req, bool *destmatch) { BaseType req, bool *destmatch) {
bool match = dtoken == token_; bool match = dtoken == token_;
if (match) { if (match) {
...@@ -1225,7 +1225,9 @@ CheckedError Parser::TryTypedValue(int dtoken, bool check, Value &e, ...@@ -1225,7 +1225,9 @@ CheckedError Parser::TryTypedValue(int dtoken, bool check, Value &e,
} else { } else {
return Error(std::string("type mismatch: expecting: ") + return Error(std::string("type mismatch: expecting: ") +
kTypeNames[e.type.base_type] + kTypeNames[e.type.base_type] +
", found: " + kTypeNames[req]); ", found: " + kTypeNames[req] +
", name: " + (name ? *name : "") +
", value: " + e.constant);
} }
} }
NEXT(); NEXT();
...@@ -1310,13 +1312,13 @@ CheckedError Parser::TokenError() { ...@@ -1310,13 +1312,13 @@ CheckedError Parser::TokenError() {
return Error("cannot parse value starting with: " + TokenToStringId(token_)); return Error("cannot parse value starting with: " + TokenToStringId(token_));
} }
CheckedError Parser::ParseSingleValue(Value &e) { CheckedError Parser::ParseSingleValue(const std::string *name, Value &e) {
// First see if this could be a conversion function: // First see if this could be a conversion function:
if (token_ == kTokenIdentifier && *cursor_ == '(') { if (token_ == kTokenIdentifier && *cursor_ == '(') {
auto functionname = attribute_; auto functionname = attribute_;
NEXT(); NEXT();
EXPECT('('); EXPECT('(');
ECHECK(ParseSingleValue(e)); ECHECK(ParseSingleValue(name, e));
EXPECT(')'); EXPECT(')');
// clang-format off // clang-format off
#define FLATBUFFERS_FN_DOUBLE(name, op) \ #define FLATBUFFERS_FN_DOUBLE(name, op) \
...@@ -1362,17 +1364,17 @@ CheckedError Parser::ParseSingleValue(Value &e) { ...@@ -1362,17 +1364,17 @@ CheckedError Parser::ParseSingleValue(Value &e) {
} }
} else { } else {
bool match = false; bool match = false;
ECHECK(TryTypedValue(kTokenIntegerConstant, IsScalar(e.type.base_type), e, ECHECK(TryTypedValue(name, kTokenIntegerConstant, IsScalar(e.type.base_type), e,
BASE_TYPE_INT, &match)); BASE_TYPE_INT, &match));
ECHECK(TryTypedValue(kTokenFloatConstant, IsFloat(e.type.base_type), e, ECHECK(TryTypedValue(name, kTokenFloatConstant, IsFloat(e.type.base_type), e,
BASE_TYPE_FLOAT, &match)); BASE_TYPE_FLOAT, &match));
ECHECK(TryTypedValue(kTokenStringConstant, ECHECK(TryTypedValue(name, kTokenStringConstant,
e.type.base_type == BASE_TYPE_STRING, e, e.type.base_type == BASE_TYPE_STRING, e,
BASE_TYPE_STRING, &match)); BASE_TYPE_STRING, &match));
auto istrue = IsIdent("true"); auto istrue = IsIdent("true");
if (istrue || IsIdent("false")) { if (istrue || IsIdent("false")) {
attribute_ = NumToString(istrue); attribute_ = NumToString(istrue);
ECHECK(TryTypedValue(kTokenIdentifier, IsBool(e.type.base_type), e, ECHECK(TryTypedValue(name, kTokenIdentifier, IsBool(e.type.base_type), e,
BASE_TYPE_BOOL, &match)); BASE_TYPE_BOOL, &match));
} }
if (!match) return TokenError(); if (!match) return TokenError();
......
No preview for this file type
// automatically generated by the FlatBuffers compiler, do not modify // automatically generated by the FlatBuffers compiler, do not modify
import * as NS9459827973991502386 from "./namespace_test1_generated"; import * as NS4989953370203581498 from "./namespace_test1_generated";
/** /**
* @constructor * @constructor
*/ */
...@@ -39,24 +39,24 @@ static getRootAsTableInFirstNS(bb:flatbuffers.ByteBuffer, obj?:TableInFirstNS):T ...@@ -39,24 +39,24 @@ static getRootAsTableInFirstNS(bb:flatbuffers.ByteBuffer, obj?:TableInFirstNS):T
* @param {NamespaceA.NamespaceB.TableInNestedNS=} obj * @param {NamespaceA.NamespaceB.TableInNestedNS=} obj
* @returns {NamespaceA.NamespaceB.TableInNestedNS|null} * @returns {NamespaceA.NamespaceB.TableInNestedNS|null}
*/ */
fooTable(obj?:NS9459827973991502386.NamespaceA.NamespaceB.TableInNestedNS):NS9459827973991502386.NamespaceA.NamespaceB.TableInNestedNS|null { fooTable(obj?:NS4989953370203581498.NamespaceA.NamespaceB.TableInNestedNS):NS4989953370203581498.NamespaceA.NamespaceB.TableInNestedNS|null {
var offset = this.bb!.__offset(this.bb_pos, 4); var offset = this.bb!.__offset(this.bb_pos, 4);
return offset ? (obj || new NS9459827973991502386.NamespaceA.NamespaceB.TableInNestedNS).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; return offset ? (obj || new NS4989953370203581498.NamespaceA.NamespaceB.TableInNestedNS).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
}; };
/** /**
* @returns {NamespaceA.NamespaceB.EnumInNestedNS} * @returns {NamespaceA.NamespaceB.EnumInNestedNS}
*/ */
fooEnum():NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS { fooEnum():NS4989953370203581498.NamespaceA.NamespaceB.EnumInNestedNS {
var offset = this.bb!.__offset(this.bb_pos, 6); var offset = this.bb!.__offset(this.bb_pos, 6);
return offset ? /** @type {NamespaceA.NamespaceB.EnumInNestedNS} */ (this.bb!.readInt8(this.bb_pos + offset)) : NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS.A; return offset ? /** @type {NamespaceA.NamespaceB.EnumInNestedNS} */ (this.bb!.readInt8(this.bb_pos + offset)) : NS4989953370203581498.NamespaceA.NamespaceB.EnumInNestedNS.A;
}; };
/** /**
* @param {NamespaceA.NamespaceB.EnumInNestedNS} value * @param {NamespaceA.NamespaceB.EnumInNestedNS} value
* @returns {boolean} * @returns {boolean}
*/ */
mutate_foo_enum(value:NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS):boolean { mutate_foo_enum(value:NS4989953370203581498.NamespaceA.NamespaceB.EnumInNestedNS):boolean {
var offset = this.bb!.__offset(this.bb_pos, 6); var offset = this.bb!.__offset(this.bb_pos, 6);
if (offset === 0) { if (offset === 0) {
...@@ -71,9 +71,9 @@ mutate_foo_enum(value:NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS ...@@ -71,9 +71,9 @@ mutate_foo_enum(value:NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS
* @param {NamespaceA.NamespaceB.StructInNestedNS=} obj * @param {NamespaceA.NamespaceB.StructInNestedNS=} obj
* @returns {NamespaceA.NamespaceB.StructInNestedNS|null} * @returns {NamespaceA.NamespaceB.StructInNestedNS|null}
*/ */
fooStruct(obj?:NS9459827973991502386.NamespaceA.NamespaceB.StructInNestedNS):NS9459827973991502386.NamespaceA.NamespaceB.StructInNestedNS|null { fooStruct(obj?:NS4989953370203581498.NamespaceA.NamespaceB.StructInNestedNS):NS4989953370203581498.NamespaceA.NamespaceB.StructInNestedNS|null {
var offset = this.bb!.__offset(this.bb_pos, 8); var offset = this.bb!.__offset(this.bb_pos, 8);
return offset ? (obj || new NS9459827973991502386.NamespaceA.NamespaceB.StructInNestedNS).__init(this.bb_pos + offset, this.bb!) : null; return offset ? (obj || new NS4989953370203581498.NamespaceA.NamespaceB.StructInNestedNS).__init(this.bb_pos + offset, this.bb!) : null;
}; };
/** /**
...@@ -95,8 +95,8 @@ static addFooTable(builder:flatbuffers.Builder, fooTableOffset:flatbuffers.Offse ...@@ -95,8 +95,8 @@ static addFooTable(builder:flatbuffers.Builder, fooTableOffset:flatbuffers.Offse
* @param {flatbuffers.Builder} builder * @param {flatbuffers.Builder} builder
* @param {NamespaceA.NamespaceB.EnumInNestedNS} fooEnum * @param {NamespaceA.NamespaceB.EnumInNestedNS} fooEnum
*/ */
static addFooEnum(builder:flatbuffers.Builder, fooEnum:NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS) { static addFooEnum(builder:flatbuffers.Builder, fooEnum:NS4989953370203581498.NamespaceA.NamespaceB.EnumInNestedNS) {
builder.addFieldInt8(1, fooEnum, NS9459827973991502386.NamespaceA.NamespaceB.EnumInNestedNS.A); builder.addFieldInt8(1, fooEnum, NS4989953370203581498.NamespaceA.NamespaceB.EnumInNestedNS.A);
}; };
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment