diff --git a/changelog.md b/changelog.md index 10e41dd..0854685 100644 --- a/changelog.md +++ b/changelog.md @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Template of models (container and component) - Icons size to fit into the new models +### Fixed + +- Parsing error when having a component with object inside object, [bug link](https://github.com/ditrit/terrator-plugin/issues/41). + ## [0.1.8] - 2023/01/16 ### Changed diff --git a/src/parser/TerraformListener.js b/src/parser/TerraformListener.js index 3a37b07..03458b7 100644 --- a/src/parser/TerraformListener.js +++ b/src/parser/TerraformListener.js @@ -19,6 +19,7 @@ class TerraformListener extends antlr4.tree.ParseTreeListener { this.currentField = null; this.currentComplexeField = null; this.currentFile = null; + this.fieldsTree = []; } addComponent() { @@ -26,6 +27,7 @@ class TerraformListener extends antlr4.tree.ParseTreeListener { this.components.push(this.currentComponent); this.currentComponent = null; this.currentBlockType = null; + this.fieldsTree = []; } // Enter a parse tree produced by terraformParser#file. @@ -216,16 +218,29 @@ class TerraformListener extends antlr4.tree.ParseTreeListener { } // Enter a parse tree produced by terraformParser#complexField. - enterComplexField() { - this.currentComplexeField = new ComponentAttribute({ value: [], type: 'Object' }); + enterComplexField(ctx) { + if (this.currentComplexeField !== null) { + this.fieldsTree.push(this.currentComplexeField); + } + + this.currentComplexeField = new ComponentAttribute({ + name: getText(ctx.IDENTIFIER()), + value: [], + type: 'Object', + }); } // Exit a parse tree produced by terraformParser#complexField. - exitComplexField(ctx) { - this.currentComplexeField.name = getText(ctx.IDENTIFIER()); - this.currentComponent.attributes - .push(this.currentComplexeField); - this.currentComplexeField = null; + exitComplexField() { + if (this.fieldsTree.length > 0) { + const field = this.fieldsTree.pop(); + + field.value.push(this.currentComplexeField); + this.currentComplexeField = field; + } else { + this.currentComponent.attributes.push(this.currentComplexeField); + this.currentComplexeField = null; + } } // Enter a parse tree produced by terraformParser#validation. diff --git a/tests/resources/tf/bug41_subObject.tf b/tests/resources/tf/bug41_subObject.tf new file mode 100644 index 0000000..5e90c51 --- /dev/null +++ b/tests/resources/tf/bug41_subObject.tf @@ -0,0 +1,11 @@ +data "aws_ami" "web" { + filter { + name = "state" + test { + value = 8 + test2 { + value = 9 + } + } + } +} diff --git a/tests/unit/parser/TerraformParser.spec.js b/tests/unit/parser/TerraformParser.spec.js index 1a89ccd..b4f7738 100644 --- a/tests/unit/parser/TerraformParser.spec.js +++ b/tests/unit/parser/TerraformParser.spec.js @@ -4,7 +4,6 @@ import { Component, ComponentAttribute, ComponentAttributeDefinition, - ComponentDefinition, ComponentLink, ComponentLinkDefinition, FileInformation, @@ -345,6 +344,66 @@ describe('Test TerraformParser', () => { })]); }); }); + + it('Should parsing object inside object, https://github.com/ditrit/terrator-plugin/issues/41', () => { + const metadata = getTerraformMetadata( + 'aws', + 'src/assets/metadata/aws.json', + ); + metadata.parse(); + metadata.pluginData.initLinkDefinitions(); + const parser = new TerraformParser(metadata.pluginData); + const input = new FileInput({ + path: 'new_file.tf', + content: fs.readFileSync('tests/resources/tf/bug41_subObject.tf', 'utf8'), + }); + + parser.parse([input]); + + expect(metadata.pluginData.components).toEqual([ + new Component({ + id: 'web', + name: 'web', + path: 'new_file.tf', + definition: metadata.pluginData.definitions.components.find(({ type }) => type === 'aws_ami'), + attributes: [ + new ComponentAttribute({ + name: 'filter', + type: 'Object', + value: [ + new ComponentAttribute({ + name: 'name', + type: 'String', + value: 'state', + }), + new ComponentAttribute({ + name: 'test', + type: 'Object', + value: [ + new ComponentAttribute({ + name: 'value', + type: 'Number', + value: 8, + }), + new ComponentAttribute({ + name: 'test2', + type: 'Object', + value: [ + new ComponentAttribute({ + name: 'value', + type: 'Number', + value: 9, + }), + ], + }), + ], + }), + ], + }), + ], + }), + ]); + }); }); }); });