Bug 1497446 - Porting binsource generator to binjs_meta 0.4.3 r=Yoric
authorDavid Teller <dteller@mozilla.com>
Wed, 10 Oct 2018 16:27:26 +0200
changeset 496884 15b1e744df851da63468b58b4a465944342ec8c9
parent 496883 7cbf19248394a63dbbdb707d31e8b265c8a5aca3
child 496885 133dc138e8718879f17efebdce753d99938b5d4e
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersYoric
bugs1497446
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1497446 - Porting binsource generator to binjs_meta 0.4.3 r=Yoric Since binjs_meta 0.4.* introduces PropertyKey and IdentifierName, we now handle these variants of strings.
js/src/frontend/BinSource-auto.cpp
js/src/frontend/BinSource.webidl_
js/src/frontend/BinToken.h
js/src/frontend/binsource/Cargo.toml
js/src/frontend/binsource/src/main.rs
--- a/js/src/frontend/BinSource-auto.cpp
+++ b/js/src/frontend/BinSource-auto.cpp
@@ -2082,17 +2082,17 @@ BinASTParser<Tok>::parseInterfaceAsserte
     }
     auto result = Ok();
     return result;
 }
 
 
 /*
  interface AssertedBoundName : Node {
-    IdentifierName name;
+    [IdentifierName] string name;
     bool isCaptured;
  }
 */
 template<typename Tok> JS::Result<Ok>
 BinASTParser<Tok>::parseAssertedBoundName(
         AssertedScopeKind scopeKind)
 {
     BinKind kind;
@@ -2119,17 +2119,17 @@ BinASTParser<Tok>::parseInterfaceAsserte
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Name, BinField::IsCaptured };
     MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
 #endif // defined(DEBUG)
 
     RootedAtom name(cx_);
-    MOZ_TRY_VAR(name, tokenizer_->readAtom());
+    MOZ_TRY_VAR(name, tokenizer_->readIdentifierName());
 
     BINJS_MOZ_TRY_DECL(isCaptured, tokenizer_->readBool());
     ParseContext::Scope* scope;
     DeclarationKind declKind;
     MOZ_TRY(getBoundScope(scopeKind, scope, declKind));
     MOZ_TRY(addScopeName(scopeKind, name, scope, declKind, isCaptured));
     auto result = Ok();
     return result;
@@ -2187,17 +2187,17 @@ BinASTParser<Tok>::parseInterfaceAsserte
     }
     auto result = Ok();
     return result;
 }
 
 
 /*
  interface AssertedDeclaredName : Node {
-    IdentifierName name;
+    [IdentifierName] string name;
     AssertedDeclaredKind kind;
     bool isCaptured;
  }
 */
 template<typename Tok> JS::Result<Ok>
 BinASTParser<Tok>::parseAssertedDeclaredName(
         AssertedScopeKind scopeKind)
 {
@@ -2225,17 +2225,17 @@ BinASTParser<Tok>::parseInterfaceAsserte
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[3] = { BinField::Name, BinField::Kind, BinField::IsCaptured };
     MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
 #endif // defined(DEBUG)
 
     RootedAtom name(cx_);
-    MOZ_TRY_VAR(name, tokenizer_->readAtom());
+    MOZ_TRY_VAR(name, tokenizer_->readIdentifierName());
 
     BINJS_MOZ_TRY_DECL(kind_, parseAssertedDeclaredKind());
 
     BINJS_MOZ_TRY_DECL(isCaptured, tokenizer_->readBool());
     ParseContext::Scope* scope;
     DeclarationKind declKind;
     MOZ_TRY(getDeclaredScope(scopeKind, kind_, scope, declKind));
     MOZ_TRY(addScopeName(scopeKind, name, scope, declKind, isCaptured));
@@ -2252,17 +2252,17 @@ BinASTParser<Tok>::parseInterfaceAsserte
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Name, BinField::IsCaptured };
     MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
 #endif // defined(DEBUG)
 
     RootedAtom name(cx_);
-    MOZ_TRY_VAR(name, tokenizer_->readAtom());
+    MOZ_TRY_VAR(name, tokenizer_->readIdentifierName());
 
     BINJS_MOZ_TRY_DECL(isCaptured, tokenizer_->readBool());
     ParseContext::Scope* scope;
     DeclarationKind declKind;
     MOZ_TRY(getBoundScope(scopeKind, scope, declKind));
     MOZ_TRY(addScopeName(scopeKind, name, scope, declKind, isCaptured));
     auto result = Ok();
     return result;
@@ -2339,17 +2339,17 @@ BinASTParser<Tok>::parseInterfaceAsserte
 #if defined(DEBUG)
     const BinField expected_fields[3] = { BinField::Index, BinField::Name, BinField::IsCaptured };
     MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
 #endif // defined(DEBUG)
 
     BINJS_MOZ_TRY_DECL(index, tokenizer_->readUnsignedLong());
 
     RootedAtom name(cx_);
-    MOZ_TRY_VAR(name, tokenizer_->readAtom());
+    MOZ_TRY_VAR(name, tokenizer_->readIdentifierName());
     // FIXME: The following checks should be performed inside
     // checkPositionalParameterIndices to match the spec's order
     // (bug 1490976).
     if (index >= positionalParams.get().length()) {
         return raiseError("AssertedPositionalParameterName.length out of range");
     }
     if (positionalParams.get()[index]) {
         return raiseError("AssertedPositionalParameterName has duplicate entry for the same index");
@@ -2373,17 +2373,17 @@ BinASTParser<Tok>::parseInterfaceAsserte
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[2] = { BinField::Name, BinField::IsCaptured };
     MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
 #endif // defined(DEBUG)
 
     RootedAtom name(cx_);
-    MOZ_TRY_VAR(name, tokenizer_->readAtom());
+    MOZ_TRY_VAR(name, tokenizer_->readIdentifierName());
 
     BINJS_MOZ_TRY_DECL(isCaptured, tokenizer_->readBool());
     ParseContext::Scope* scope;
     DeclarationKind declKind;
     MOZ_TRY(getBoundScope(scopeKind, scope, declKind));
     MOZ_TRY(addScopeName(scopeKind, name, scope, declKind, isCaptured));
     auto result = Ok();
     return result;
@@ -2514,17 +2514,17 @@ BinASTParser<Tok>::parseInterfaceAssignm
 
     BINJS_TRY_DECL(result, factory_.newAssignment(ParseNodeKind::Assign, binding, expression));
     return result;
 }
 
 
 /*
  interface AssignmentTargetIdentifier : Node {
-    Identifier name;
+    [IdentifierName] string name;
  }
 */
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseAssignmentTargetIdentifier()
 {
     BinKind kind;
     BinFields fields(cx_);
     AutoTaggedTuple guard(*tokenizer_);
@@ -2547,17 +2547,17 @@ BinASTParser<Tok>::parseInterfaceAssignm
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[1] = { BinField::Name };
     MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
 #endif // defined(DEBUG)
 
     RootedAtom name(cx_);
-    MOZ_TRY_VAR(name, tokenizer_->readAtom());
+    MOZ_TRY_VAR(name, tokenizer_->readIdentifierName());
 
     if (!IsIdentifier(name)) {
         return raiseError("Invalid identifier");
     }
     BINJS_TRY(usedNames_.noteUse(cx_, name, parseContext_->scriptId(), parseContext_->innermostScope()->id()));
     BINJS_TRY_DECL(result, factory_.newName(name->asPropertyName(), tokenizer_->pos(start), cx_));
     return result;
 }
@@ -2697,17 +2697,17 @@ BinASTParser<Tok>::parseInterfaceBinaryE
         result = list;
     }
     return result;
 }
 
 
 /*
  interface BindingIdentifier : Node {
-    Identifier name;
+    [IdentifierName] string name;
  }
 */
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseBindingIdentifier()
 {
     BinKind kind;
     BinFields fields(cx_);
     AutoTaggedTuple guard(*tokenizer_);
@@ -2730,17 +2730,17 @@ BinASTParser<Tok>::parseInterfaceBinding
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[1] = { BinField::Name };
     MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
 #endif // defined(DEBUG)
 
     RootedAtom name(cx_);
-    MOZ_TRY_VAR(name, tokenizer_->readAtom());
+    MOZ_TRY_VAR(name, tokenizer_->readIdentifierName());
 
     if (!IsIdentifier(name)) {
         return raiseError("Invalid identifier");
     }
     BINJS_TRY_DECL(result, factory_.newName(name->asPropertyName(), tokenizer_->pos(start), cx_));
     return result;
 }
 
@@ -3536,18 +3536,18 @@ template<typename Tok> JS::Result<ParseN
 BinASTParser<Tok>::parseInterfaceExportFrom(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ExportFrom)");
 }
 
 
 /*
  interface ExportFromSpecifier : Node {
-    IdentifierName name;
-    IdentifierName? exportedName;
+    [IdentifierName] string name;
+    [IdentifierName] string? exportedName;
  }
 */
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseExportFromSpecifier()
 {
     BinKind kind;
     BinFields fields(cx_);
     AutoTaggedTuple guard(*tokenizer_);
@@ -3568,17 +3568,17 @@ BinASTParser<Tok>::parseInterfaceExportF
 {
     return raiseError("FIXME: Not implemented yet (ExportFromSpecifier)");
 }
 
 
 /*
  interface ExportLocalSpecifier : Node {
     IdentifierExpression name;
-    IdentifierName? exportedName;
+    [PropertyKey] string? exportedName;
  }
 */
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseExportLocalSpecifier()
 {
     BinKind kind;
     BinFields fields(cx_);
     AutoTaggedTuple guard(*tokenizer_);
@@ -3975,17 +3975,17 @@ BinASTParser<Tok>::parseInterfaceGetterC
     *bodyOut = body;
     auto result = Ok();
     return result;
 }
 
 
 /*
  interface IdentifierExpression : Node {
-    Identifier name;
+    [IdentifierName] string name;
  }
 */
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseIdentifierExpression()
 {
     BinKind kind;
     BinFields fields(cx_);
     AutoTaggedTuple guard(*tokenizer_);
@@ -4008,17 +4008,17 @@ BinASTParser<Tok>::parseInterfaceIdentif
     BINJS_TRY(CheckRecursionLimit(cx_));
 
 #if defined(DEBUG)
     const BinField expected_fields[1] = { BinField::Name };
     MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
 #endif // defined(DEBUG)
 
     RootedAtom name(cx_);
-    MOZ_TRY_VAR(name, tokenizer_->readAtom());
+    MOZ_TRY_VAR(name, tokenizer_->readIdentifierName());
 
     if (!IsIdentifier(name)) {
         return raiseError("Invalid identifier");
     }
     BINJS_TRY(usedNames_.noteUse(cx_, name, parseContext_->scriptId(), parseContext_->innermostScope()->id()));
     BINJS_TRY_DECL(result, factory_.newName(name->asPropertyName(), tokenizer_->pos(start), cx_));
     return result;
 }
@@ -4054,17 +4054,17 @@ template<typename Tok> JS::Result<ParseN
 BinASTParser<Tok>::parseInterfaceImportNamespace(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet (ImportNamespace)");
 }
 
 
 /*
  interface ImportSpecifier : Node {
-    IdentifierName? name;
+    [PropertyKey] string? name;
     BindingIdentifier binding;
  }
 */
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseImportSpecifier()
 {
     BinKind kind;
     BinFields fields(cx_);
@@ -4595,17 +4595,17 @@ BinASTParser<Tok>::parseInterfaceStaticM
     MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
 #endif // defined(DEBUG)
     size_t nameStart;
 
     BINJS_MOZ_TRY_DECL(object, parseExpressionOrSuper());
     RootedAtom property(cx_);
     {
         nameStart = tokenizer_->offset();
-        MOZ_TRY_VAR(property, tokenizer_->readAtom());
+        MOZ_TRY_VAR(property, tokenizer_->readPropertyKey());
 
     }
 
     BINJS_TRY_DECL(name, factory_.newPropertyName(property->asPropertyName(), tokenizer_->pos(nameStart)));
     BINJS_TRY_DECL(result, factory_.newPropertyAccess(object, name));
     return result;
 }
 
@@ -4620,17 +4620,17 @@ BinASTParser<Tok>::parseInterfaceStaticM
     MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
 #endif // defined(DEBUG)
     size_t nameStart;
 
     BINJS_MOZ_TRY_DECL(object, parseExpressionOrSuper());
     RootedAtom property(cx_);
     {
         nameStart = tokenizer_->offset();
-        MOZ_TRY_VAR(property, tokenizer_->readAtom());
+        MOZ_TRY_VAR(property, tokenizer_->readPropertyKey());
 
     }
 
     BINJS_TRY_DECL(name, factory_.newPropertyName(property->asPropertyName(), tokenizer_->pos(nameStart)));
     BINJS_TRY_DECL(result, factory_.newPropertyAccess(object, name));
     return result;
 }
 
--- a/js/src/frontend/BinSource.webidl_
+++ b/js/src/frontend/BinSource.webidl_
@@ -1,14 +1,15 @@
 // Type aliases and enums.
 
 typedef FrozenArray<(SpreadElement or Expression)> Arguments;
 typedef DOMString string;
 typedef string Identifier;
 typedef string IdentifierName;
+typedef string PropertyKey;
 typedef string Label;
 
 enum VariableDeclarationKind {
   "var",
   "let",
   "const"
 };
 
--- a/js/src/frontend/BinToken.h
+++ b/js/src/frontend/BinToken.h
@@ -213,21 +213,23 @@ namespace frontend {
     F(OptionalAssignmentTarget, "OptionalAssignmentTarget") \
     F(OptionalBinding, "OptionalBinding") \
     F(OptionalBindingIdentifier, "OptionalBindingIdentifier") \
     F(OptionalBindingOrBindingWithInitializer, "OptionalBindingOrBindingWithInitializer") \
     F(OptionalCatchClause, "OptionalCatchClause") \
     F(OptionalExpression, "OptionalExpression") \
     F(OptionalIdentifierName, "OptionalIdentifierName") \
     F(OptionalLabel, "OptionalLabel") \
+    F(OptionalPropertyKey, "OptionalPropertyKey") \
     F(OptionalSpreadElementOrExpression, "OptionalSpreadElementOrExpression") \
     F(OptionalStatement, "OptionalStatement") \
     F(OptionalVariableDeclarationOrExpression, "OptionalVariableDeclarationOrExpression") \
     F(Parameter, "Parameter") \
     F(Program, "Program") \
+    F(PropertyKey, "PropertyKey") \
     F(PropertyName, "PropertyName") \
     F(ReturnStatement, "ReturnStatement") \
     F(Script, "Script") \
     F(Setter, "Setter") \
     F(SetterContents, "SetterContents") \
     F(ShorthandProperty, "ShorthandProperty") \
     F(SimpleAssignmentTarget, "SimpleAssignmentTarget") \
     F(SpreadElement, "SpreadElement") \
@@ -262,17 +264,17 @@ namespace frontend {
 
 enum class BinKind {
 #define EMIT_ENUM(name, _) name,
     FOR_EACH_BIN_KIND(EMIT_ENUM)
 #undef EMIT_ENUM
 };
 
 // The number of distinct values of BinKind.
-const size_t BINKIND_LIMIT = 198;
+const size_t BINKIND_LIMIT = 200;
 
 
 
 
 /**
  * The different variants of Binary AST string enums, as per
  * the specifications of Binary AST, as a single macro and
  * `enum class`.
--- a/js/src/frontend/binsource/Cargo.toml
+++ b/js/src/frontend/binsource/Cargo.toml
@@ -1,13 +1,13 @@
 [package]
-name = "binsource"
-version = "0.1.0"
+name = "binast"
+version = "0.1.1"
 authors = ["David Teller <D.O.Teller@gmail.com>"]
 
 [dependencies]
-binjs_meta = "^0.3.10"
+binjs_meta = "^0.4.3"
 clap = "^2"
 env_logger = "^0.5.6"
 itertools = "^0.7.6"
 log = "0.4"
 yaml-rust = "^0.4"
-webidl = "^0.6.0"
+webidl = "^0.8"
--- a/js/src/frontend/binsource/src/main.rs
+++ b/js/src/frontend/binsource/src/main.rs
@@ -544,17 +544,17 @@ struct CPPExporter {
 impl CPPExporter {
     fn new(syntax: Spec, rules: GlobalRules) -> Self {
         let mut list_parsers_to_generate = vec![];
         let mut option_parsers_to_generate = vec![];
         for (parser_node_name, typedef) in syntax.typedefs_by_name() {
             if typedef.is_optional() {
                 let content_name = TypeName::type_spec(typedef.spec());
                 let content_node_name = syntax.get_node_name(&content_name)
-                    .unwrap_or_else(|| panic!("While generating an option parser, could not find node name {}", content_name))
+                    .unwrap_or_else(|| panic!("While generating an option parser, could not find node name \"{}\"", content_name))
                     .clone();
                 debug!(target: "generate_spidermonkey", "CPPExporter::new adding optional typedef {:?} => {:?} => {:?}",
                     parser_node_name,
                     content_name,
                     content_node_name);
                 option_parsers_to_generate.push(OptionParserData {
                     name: parser_node_name.clone(),
                     elements: content_node_name
@@ -708,16 +708,20 @@ impl CPPExporter {
                         _ => {}
                     }
                 },
                 _ => {}
             }
             refgraph.insert(string_from_nodename(&parser.name), edges);
         }
 
+        // 6. Primitive values.
+        refgraph.insert(Rc::new("IdentifierName".to_string()), HashSet::new());
+        refgraph.insert(Rc::new("PropertyKey".to_string()), HashSet::new());
+
         self.refgraph = refgraph;
     }
 
     /// Trace the reference graph from the node with `name and mark all nodes
     /// as used. `name` is the name of the method, without leading "parse".
     fn trace(&mut self, name: Rc<String>) {
         self.refgraph.trace(name)
     }
@@ -1471,16 +1475,75 @@ impl CPPExporter {
 }}
 
 ",
                                 first_line = first_line,
                                 build = build_result,
                             ));
                         }
                     }
+                    &TypeSpec::IdentifierName => {
+                        let build_result = rules_for_this_node.init.reindent("    ");
+                        let first_line = self.get_method_definition_start(&parser.name, "", "",
+                                                                          &extra_params);
+                        if build_result.len() == 0 {
+                            buffer.push_str(&format!("{first_line}
+{{
+    return raiseError(\"FIXME: Not implemented yet ({kind})\");
+}}
+
+",
+                                first_line = first_line,
+                                kind = parser.name.to_str()));
+                        } else {
+                            buffer.push_str(&format!("{first_line}
+{{
+    BINJS_MOZ_TRY_DECL(result, tokenizer_->readMaybeIdentifierName());
+
+{build}
+
+    return result;
+}}
+
+",
+                                first_line = first_line,
+                                build = build_result,
+                            ));
+                        }
+                    }
+                    &TypeSpec::PropertyKey => {
+                        debug!(target: "generate_spidermonkey", "Generating method for PropertyKey: {:?}", parser.name);
+                        let build_result = rules_for_this_node.init.reindent("    ");
+                        let first_line = self.get_method_definition_start(&parser.name, "", "",
+                                                                          &extra_params);
+                        if build_result.len() == 0 {
+                            buffer.push_str(&format!("{first_line}
+{{
+    return raiseError(\"FIXME: Not implemented yet ({kind})\");
+}}
+
+",
+                                first_line = first_line,
+                                kind = parser.name.to_str()));
+                        } else {
+                            buffer.push_str(&format!("{first_line}
+{{
+    BINJS_MOZ_TRY_DECL(result, tokenizer_->readMaybePropertyKey());
+
+{build}
+
+    return result;
+}}
+
+",
+                                first_line = first_line,
+                                build = build_result,
+                            ));
+                        }
+                    }
                     _else => unimplemented!("{:?}", _else)
                 }
             }
             NamedType::StringEnum(_) => {
                 unimplemented!()
             }
         }
     }
@@ -1599,16 +1662,36 @@ impl CPPExporter {
                     warn!("Internal error: We shouldn't have any `void` types at this stage.");
                     (Some(format!("// Skipping void field {}", field.name().to_str())),
                         None)
                 }
                 Some(IsNullable { is_nullable: false, content: Primitive::String }) => {
                     (Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)),
                         Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readAtom());", var_name = var_name)))
                 }
+                Some(IsNullable { is_nullable: false, content: Primitive::IdentifierName }) => {
+                    (Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)),
+                        Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readIdentifierName());", var_name = var_name)))
+                }
+                Some(IsNullable { is_nullable: false, content: Primitive::PropertyKey }) => {
+                    (Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)),
+                        Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readPropertyKey());", var_name = var_name)))
+                }
+                Some(IsNullable { is_nullable: true, content: Primitive::String }) => {
+                    (Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)),
+                        Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readMaybeAtom());", var_name = var_name)))
+                }
+                Some(IsNullable { is_nullable: true, content: Primitive::IdentifierName }) => {
+                    (Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)),
+                        Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readMaybeIdentifierName());", var_name = var_name)))
+                }
+                Some(IsNullable { is_nullable: true, content: Primitive::PropertyKey }) => {
+                    (Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)),
+                        Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readMaybePropertyKey());", var_name = var_name)))
+                }
                 _else => {
                     let typename = TypeName::type_(field.type_());
                     let name = self.syntax.get_node_name(typename.to_str())
                         .expect("NodeName for the field type should exist.");
                     let field_extra_args = rules_for_this_field.extra_args;
 
                     let (decl_var, call_kind) = if needs_block {
                         (Some(format!("{typename} {var_name};",
@@ -1621,17 +1704,16 @@ impl CPPExporter {
                     };
 
                     (decl_var,
                      Some(self.get_method_call(var_name.to_str(),
                                                &name, "", "", &field_extra_args,
                                                call_kind)))
                 }
             };
-
             let rendered = {
                 if rules_for_this_field.replace.is_some() {
                     for &(condition, rule_name) in &[
                         (rules_for_this_field.before_field.is_some(), "before:"),
                         (rules_for_this_field.after_field.is_some(), "after:"),
                         (rules_for_this_field.declare.is_some(), "declare:"),
                     ] {
                         if condition {