Skip to content

Commit

Permalink
chore(*): port v3 fixes to v4 (#818)
Browse files Browse the repository at this point in the history
* fix(build): include unions in index

Signed-off-by: Matt Roberts <[email protected]>

* chore(deps): upgrade codegen to latest release

Signed-off-by: Matt Roberts <[email protected]>

---------

Signed-off-by: Matt Roberts <[email protected]>

* fix(class): throw error when class is extending itself (#767)

* fix(parser): throw error when concept is extending itself in CTO

Signed-off-by: Stefan Blaginov <[email protected]>
Signed-off-by: Stefan Blaginov <[email protected]>

* fix(parser): throw error when concept is extending itself in JSON metamodel form

Signed-off-by: Stefan Blaginov <[email protected]>
Signed-off-by: Stefan Blaginov <[email protected]>

* fix(parser): throw error when concept is extending itself in the AST

Signed-off-by: Stefan Blaginov <[email protected]>
Signed-off-by: Stefan Blaginov <[email protected]>

* refactor(validation): alphabetical rearrangement

Signed-off-by: Stefan Blaginov <[email protected]>
Signed-off-by: Stefan Blaginov <[email protected]>

* test(self-extending): remove redundant tests (codepath covered in concerto-cto)

Signed-off-by: Stefan Blaginov <[email protected]>
Signed-off-by: Stefan Blaginov <[email protected]>

* test(fix): remove unneeded import

Signed-off-by: Stefan Blaginov <[email protected]>
Signed-off-by: Stefan Blaginov <[email protected]>

---------

Signed-off-by: Stefan Blaginov <[email protected]>
Signed-off-by: Stefan Blaginov <[email protected]>
Co-authored-by: Stefan Blaginov <[email protected]>

* fix(class-declaration): throw with undefined ast properties (#771)

Signed-off-by: Ertugrul Karademir <[email protected]>

* fix(error): adding type to error in string validator in introspect (#773)

* fix(error): adding type to error in string validator in introspect

Signed-off-by: Santanu Roy <[email protected]>
Co-authored-by: Santanu Roy <[email protected]>

* refactor(declarations): move declaration uniqueness check to model file (#794)

* refactor(declarations): Move unique name check to model file.

Signed-off-by: Ertugrul Karademir <[email protected]>

* refactor(test): move validation checks for duplicate class to model file

Signed-off-by: Ertugrul Karademir <[email protected]>

* test: empty commit to trigger test

Signed-off-by: Ertugrul Karademir <[email protected]>

---------

Signed-off-by: Ertugrul Karademir <[email protected]>

* perf(core): don't use arrays to check uniqueness (#802)

refactor: don't use arrays to check uniqueness

Signed-off-by: Ertugrul Karademir <[email protected]>

* perf(core): remove usage of arrays while forming duplicate item errors (#804)

* refactor: don't use arrays to check uniqueness

Signed-off-by: Ertugrul Karademir <[email protected]>

* refactor: also refactor unique property name check

Signed-off-by: Ertugrul Karademir <[email protected]>

* refactor: remove array for decorator uniqueness check

Signed-off-by: Ertugrul Karademir <[email protected]>

* refactor: remove uniqueness check from scalar declarations as well

Signed-off-by: Ertugrul Karademir <[email protected]>

---------

Signed-off-by: Ertugrul Karademir <[email protected]>

---------

Signed-off-by: Matt Roberts <[email protected]>
Signed-off-by: Stefan Blaginov <[email protected]>
Signed-off-by: Stefan Blaginov <[email protected]>
Signed-off-by: Ertugrul Karademir <[email protected]>
Signed-off-by: Santanu Roy <[email protected]>
Co-authored-by: Stefan Blaginov <[email protected]>
Co-authored-by: Stefan Blaginov <[email protected]>
Co-authored-by: Ertugrul Karademir <[email protected]>
Co-authored-by: Santanu Roy <[email protected]>
Co-authored-by: Santanu Roy <[email protected]>
  • Loading branch information
6 people authored Mar 11, 2024
1 parent 6b696c7 commit 3b4bdec
Show file tree
Hide file tree
Showing 26 changed files with 362 additions and 59 deletions.
95 changes: 95 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 34 additions & 32 deletions packages/concerto-core/src/introspect/classdeclaration.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ class ClassDeclaration extends Declaration {
}
}

if (!Array.isArray(this.ast.properties)) {
let formatter = Globalize.messageFormatter('classdeclaration-validate-undefined-properties');
throw new IllegalModelException(formatter({
'class':this.name
}), this.modelFile, this.ast.location);
}

for (let n = 0; n < this.ast.properties.length; n++) {
let thing = this.ast.properties[n];

Expand Down Expand Up @@ -194,23 +201,21 @@ class ClassDeclaration extends Declaration {
validate() {
super.validate();

const declarations = this.getModelFile().getAllDeclarations();
const declarationNames = declarations.map(
d => d.getFullyQualifiedName()
);
const uniqueNames = new Set(declarationNames);

if (uniqueNames.size !== declarations.length) {
const duplicateElements = declarationNames.filter(
(item, index) => declarationNames.indexOf(item) !== index
);
throw new IllegalModelException(
`Duplicate class name ${duplicateElements[0]}`
);
}

// if we have a super type make sure it exists
if (this.superType !== null) {
// and make sure that the class isn't extending itself
// (an exemption is made for the core classes)
if (
this.superType === this.name &&
![
'Asset', 'Concept', 'Event', 'Participant', 'Transaction',
].includes(this.superType)
) {
let formatter = Globalize('en').messageFormatter('classdeclaration-validate-selfextending');
throw new IllegalModelException(formatter({
'class': this.name,
}), this.modelFile, this.ast.location);
}
this._resolveSuperType();
}

Expand Down Expand Up @@ -269,24 +274,21 @@ class ClassDeclaration extends Declaration {
}
// we also have to check fields defined in super classes
const properties = this.getProperties();
const propertyFieldNames = properties.map(
d => d.getName()
);
const uniquePropertyFieldNames = new Set(propertyFieldNames);

if (uniquePropertyFieldNames.size !== properties.length) {
const duplicateElements = propertyFieldNames
.filter(
(item, index) => propertyFieldNames.indexOf(item) !== index
const uniquePropertyNames = new Set();
properties.forEach(p => {
const propertyName = p.getName();
if (!uniquePropertyNames.has(propertyName)) {
uniquePropertyNames.add(propertyName);
} else {
const formatter = Globalize('en').messageFormatter(
'classdeclaration-validate-duplicatefieldname'
);
const formatter = Globalize('en').messageFormatter(
'classdeclaration-validate-duplicatefieldname'
);
throw new IllegalModelException(formatter({
'class': this.name,
'fieldName': duplicateElements[0]
}), this.modelFile, this.ast.location);
}
throw new IllegalModelException(formatter({
'class': this.name,
'fieldName': propertyName
}), this.modelFile, this.ast.location);
}
});

for (let n = 0; n < properties.length; n++) {
let field = properties[n];
Expand Down
29 changes: 13 additions & 16 deletions packages/concerto-core/src/introspect/decorated.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,20 @@ class Decorated extends ModelElement {
}

// check we don't have this decorator twice
const decoratorNames = this.decorators.map(
d => d.getName()
);
const uniqueDecoratorNames = new Set(decoratorNames);

if (uniqueDecoratorNames.size !== this.decorators.length) {
const duplicateElements = decoratorNames
.filter(
(item, index) => decoratorNames.indexOf(item) !== index
const uniqueDecoratorNames = new Set();
this.decorators.forEach(d => {
const decoratorName = d.getName();
if(!uniqueDecoratorNames.has(decoratorName)) {
uniqueDecoratorNames.add(decoratorName);
} else {
const modelFile = this.getModelFile();
throw new IllegalModelException(
`Duplicate decorator ${decoratorName}`,
modelFile,
this.ast.location,
);
const modelFile = this.getModelFile();
throw new IllegalModelException(
`Duplicate decorator ${duplicateElements[0]}`,
modelFile,
this.ast.location,
);
}
}
});
}
}

Expand Down
16 changes: 16 additions & 0 deletions packages/concerto-core/src/introspect/modelfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,22 @@ class ModelFile {
});

// Validate all of the types in this model file.
// Check if names of the declarations are unique.
const uniqueNames = new Set();
this.declarations.forEach(
d => {
const fqn = d.getFullyQualifiedName();
if (!uniqueNames.has(fqn)) {
uniqueNames.add(fqn);
} else {
throw new IllegalModelException(
`Duplicate class name ${fqn}`
);
}
}
);

// Run validations on class declarations
for(let n=0; n < this.declarations.length; n++) {
let classDeclaration = this.declarations[n];
classDeclaration.validate();
Expand Down
3 changes: 2 additions & 1 deletion packages/concerto-core/src/introspect/stringvalidator.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

'use strict';

const { ErrorCodes } = require('@accordproject/concerto-util');
const { isNull } = require('../util');
const Validator = require('./validator');

Expand Down Expand Up @@ -70,7 +71,7 @@ class StringValidator extends Validator{
this.regex = new CustomRegExp(validator.pattern, validator.flags);
}
catch(exception) {
this.reportError(field.getName(), exception.message);
this.reportError(field.getName(), exception.message, ErrorCodes.REGEX_VALIDATOR_EXCEPTION);
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions packages/concerto-core/src/introspect/validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

'use strict';

const { BaseException, ErrorCodes } = require('@accordproject/concerto-util');
// Types needed for TypeScript generation.
/* eslint-disable no-unused-vars */
/* istanbul ignore next */
Expand Down Expand Up @@ -46,10 +47,11 @@ class Validator {
/**
* @param {string} id the identifier of the instance
* @param {string} msg the exception message
* @param {string} errorType the type of error
* @throws {Error} throws an error to report the message
*/
reportError(id, msg) {
throw new Error( 'Validator error for field `' + id + '`. ' + this.getFieldOrScalarDeclaration().getFullyQualifiedName() + ': ' + msg );
reportError(id, msg, errorType=ErrorCodes.DEFAULT_VALIDATOR_EXCEPTION) {
throw new BaseException('Validator error for field `' + id + '`. ' + this.getFieldOrScalarDeclaration().getFullyQualifiedName() + ': ' + msg, undefined, errorType);
}

/**
Expand Down
2 changes: 2 additions & 0 deletions packages/concerto-core/src/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
"classdeclaration-validate-identifiernotstring": "Class \"{class}\" is identified by field \"{idField}\", but the type of the field is not \"String\".",
"classdeclaration-validate-duplicatefieldname": "Class \"{class}\" has more than one field named \"{fieldName}\".",
"classdeclaration-validate-missingidentifier" : "Class \"{class}\" is not declared as \"abstract\". It must define an identifying field.",
"classdeclaration-validate-selfextending": "Class \"{class}\" cannot extend itself.",
"classdeclaration-validate-undefined-properties": "Properties of Class \"{class}\" has to be defined.",

"modelfile-constructor-unrecmodelelem": "Unrecognised model element \"{type}\".",
"modelfile-resolvetype-undecltype": "Undeclared type \"{type}\" in \"{context}\".",
Expand Down
7 changes: 4 additions & 3 deletions packages/concerto-core/src/typenotfoundexception.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

'use strict';

const { BaseException } = require('@accordproject/concerto-util');
const { BaseException, ErrorCodes } = require('@accordproject/concerto-util');
const Globalize = require('./globalize');

/**
Expand All @@ -31,16 +31,17 @@ class TypeNotFoundException extends BaseException {
* @param {string} typeName - fully qualified type name.
* @param {string|undefined} message - error message.
* @param {string} component - the optional component which throws this error
* @param {string} errorType - the error code related to the error
*/
constructor(typeName, message, component) {
constructor(typeName, message, component, errorType = ErrorCodes.TYPE_NOT_FOUND_EXCEPTION) {
if (!message) {
const formatter = Globalize.messageFormatter('typenotfounderror-defaultmessage');
message = formatter({
typeName: typeName
});
}

super(message, component);
super(message, component, errorType);
this.typeName = typeName;
}

Expand Down
1 change: 0 additions & 1 deletion packages/concerto-core/test/introspect/classdeclaration.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ describe('ClassDeclaration', () => {
});
}).should.throw(/Invalid model element name '2nd'/);
});

});

describe('#validate', () => {
Expand Down
Loading

0 comments on commit 3b4bdec

Please sign in to comment.