Skip to content

Commit 032bd75

Browse files
feat: alias Import rules added (#855)
* feat: Alias Import rules added * Rules for AliasedIdentifier and Types added. * aliasedTypes filtered in callback of ImportTypes Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat: Grammar rules updated - as token defined for aliasing types in the import statements - as is defined local reserved word - AST made backward compatible Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat: Printer updated - Printer now handles the aliased types. - Test case added for parser and printer. Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias import): Printer and parser test cases - Test case added containing alias import Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias import): test cases for updated grammar - test cases added for both parser and printer - bad test cases added as well for the parser Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias import): PR changes - renamed the Types rule to IdentifierTypeExpression - Indentation fixed - Extra white spaces removed Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias): Minor fixes - Code changes made on suggestion. Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias): disabled aliasing to primitive types Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias): handle pr comments - Test cases added - pr comments handled Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias): variables renamed and code cleaned Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias import): printer code refactored - printer code refactored - coverage 100% tested locally Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias import): Updated concerto-metamodel version Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias import): Pr suggestion : code refactor Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias):package-lock.json fixed Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias): fixing pr Signed-off-by: Jaskeerat Singh Saluja <[email protected]> --------- Signed-off-by: Jaskeerat Singh Saluja <[email protected]>
1 parent 731b2f1 commit 032bd75

File tree

8 files changed

+858
-559
lines changed

8 files changed

+858
-559
lines changed

packages/concerto-cto/lib/parser.js

Lines changed: 661 additions & 550 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/concerto-cto/lib/parser.pegjs

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@
9797
namespace: split.join('.')
9898
};
9999
}
100+
function isPrimitiveType(typeName) {
101+
const primitiveTypes = ['Boolean', 'String', 'DateTime', 'Double', 'Integer', 'Long'];
102+
return (primitiveTypes.indexOf(typeName) >= 0);
103+
}
100104
}
101105

102106
Start
@@ -419,6 +423,7 @@ FalseToken = "false" !IdentifierPart
419423
ImportToken = "import" !IdentifierPart
420424
NullToken = "null" !IdentifierPart
421425
TrueToken = "true" !IdentifierPart
426+
AsToken = "as" !IdentifierPart
422427

423428
/* Skipped */
424429

@@ -1711,22 +1716,46 @@ ImportType
17111716
}
17121717
17131718
ImportTypes
1714-
= ImportToken __ ns:QualifiedNamespaceDeclaration ".{" _ types:commaSeparatedIdentifiers _ "}" __ u:FromUri? {
1719+
= ImportToken __ ns:QualifiedNamespaceDeclaration ".{" _ types:commaSeparatedTypes _ "}" __ u:FromUri? {
1720+
const { aliasedTypes, typesNames } = types.reduce((acc, type) => {
1721+
if (type.$class === "concerto.metamodel@1.0.0.AliasedType") {
1722+
acc.aliasedTypes.push(type);
1723+
acc.typesNames.push(type.name);
1724+
} else {
1725+
acc.typesNames.push(type);
1726+
}
1727+
return acc;
1728+
}, { aliasedTypes: [], typesNames: [] });
17151729
const result = {
17161730
$class: "concerto.metamodel@1.0.0.ImportTypes",
17171731
namespace: ns,
1718-
types,
1732+
types:typesNames,
1733+
... aliasedTypes.length >0 && {aliasedTypes},
1734+
17191735
};
17201736
u && (result.uri = u);
17211737
return result;
17221738
}
17231739
1724-
commaSeparatedIdentifiers
1725-
= head:$Identifier _ tail:(',' _ @$Identifier _ )*
1726-
{
1727-
return [head, ...tail];
1728-
}
1740+
AliasedIdentifier
1741+
= name:$Identifier _ $AsToken _ aliasedName:$Identifier{
1742+
if(isPrimitiveType(aliasedName)){
1743+
throw new Error(`A type cannot be aliased to a Primitive type, here "${name}" is being aliased as "${aliasedName}".`);
1744+
}
1745+
return {
1746+
"$class":"concerto.metamodel@1.0.0.AliasedType",
1747+
name,
1748+
aliasedName
1749+
};
1750+
}
17291751
1752+
IdentifierTypeExpression
1753+
= AliasedIdentifier / $Identifier
1754+
1755+
commaSeparatedTypes
1756+
= head:IdentifierTypeExpression _ tail:(',' _ IdentifierTypeExpression)* {
1757+
return [head, ...tail.map(t => t[2])];
1758+
}
17301759
Import
17311760
= ImportTypes /
17321761
ImportAll /

packages/concerto-cto/lib/printer.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,9 +387,25 @@ function toCTO(metaModel) {
387387
case `${MetaModelNamespace}.ImportAllFrom`:
388388
result += `\nimport ${imp.namespace}.*`;
389389
break;
390-
case `${MetaModelNamespace}.ImportTypes`:
391-
result += `\nimport ${imp.namespace}.{${imp.types.join(',')}}`;
390+
case `${MetaModelNamespace}.ImportTypes`: {
391+
const aliasedTypes = imp.aliasedTypes
392+
? new Map(
393+
imp.aliasedTypes.map(({ name, aliasedName }) => [
394+
name,
395+
aliasedName,
396+
])
397+
)
398+
: new Map();
399+
const commaSeparatedTypesString = imp.types
400+
.map((type) =>
401+
aliasedTypes.has(type)
402+
? `${type} as ${aliasedTypes.get(type)}`
403+
: type
404+
)
405+
.join(',');
406+
result += `\nimport ${imp.namespace}.{${commaSeparatedTypesString}}`;
392407
break;
408+
}
393409
default:
394410
throw new Error('Unrecognized import');
395411
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace test.aliasing
2+
3+
import org.accordproject.{doc1 as d1,doc2 as d2}
4+
import org.accordproject.files.{file1,file2 as f2,file3}
5+
import [email protected].{baz1 as bar1}
6+
import [email protected].{baz2 as bar2} from https://com.example.co.uk/models/com.example.foo.cto
7+
import [email protected].{tee,baz as bar,lorem,ipsum,dolor as freq}
8+
import [email protected].{As as as,as as as}
9+
import [email protected].{baz}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
{
2+
"$class": "[email protected]",
3+
"decorators": [],
4+
"namespace": "test.aliasing",
5+
"imports": [
6+
{
7+
"$class": "[email protected]",
8+
"namespace": "org.accordproject",
9+
"types": ["doc1", "doc2"],
10+
"aliasedTypes": [
11+
{
12+
"$class": "[email protected]",
13+
"name": "doc1",
14+
"aliasedName": "d1"
15+
},
16+
{
17+
"$class": "[email protected]",
18+
"name": "doc2",
19+
"aliasedName": "d2"
20+
}
21+
]
22+
},
23+
{
24+
"$class": "[email protected]",
25+
"namespace": "org.accordproject.files",
26+
"types": ["file1", "file2", "file3"],
27+
"aliasedTypes": [
28+
{
29+
"$class": "[email protected]",
30+
"name": "file2",
31+
"aliasedName": "f2"
32+
}
33+
]
34+
},
35+
{
36+
"$class": "[email protected]",
37+
"namespace": "[email protected]",
38+
"types": ["baz1"],
39+
"aliasedTypes": [
40+
{
41+
"$class": "[email protected]",
42+
"name": "baz1",
43+
"aliasedName": "bar1"
44+
}
45+
]
46+
},
47+
{
48+
"$class": "[email protected]",
49+
"namespace": "[email protected]",
50+
"types": ["baz2"],
51+
"aliasedTypes": [
52+
{
53+
"$class": "[email protected]",
54+
"name": "baz2",
55+
"aliasedName": "bar2"
56+
}
57+
],
58+
"uri": "https://com.example.co.uk/models/com.example.foo.cto"
59+
},
60+
{
61+
"$class": "[email protected]",
62+
"namespace": "[email protected]",
63+
"types": ["tee", "baz", "lorem", "ipsum", "dolor"],
64+
"aliasedTypes": [
65+
{
66+
"$class": "[email protected]",
67+
"name": "baz",
68+
"aliasedName": "bar"
69+
},
70+
{
71+
"$class": "[email protected]",
72+
"name": "dolor",
73+
"aliasedName": "freq"
74+
}
75+
]
76+
},
77+
{
78+
"$class": "[email protected]",
79+
"namespace": "[email protected]",
80+
"types": ["As", "as"],
81+
"aliasedTypes": [
82+
{
83+
"$class": "[email protected]",
84+
"name": "As",
85+
"aliasedName": "as"
86+
},
87+
{
88+
"$class": "[email protected]",
89+
"name": "as",
90+
"aliasedName": "as"
91+
}
92+
]
93+
},
94+
{
95+
"$class": "[email protected]",
96+
"namespace": "[email protected]",
97+
"types": ["baz"]
98+
}
99+
],
100+
"declarations": []
101+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
3+
import ns.{doc as}
4+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
3+
//Bad Import : without paranthesis
4+
import [email protected] as bar

packages/concerto-cto/test/parserMain.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,31 @@ describe('parser', () => {
8181
});
8282
});
8383

84+
describe('alias-imports',()=>{
85+
it('Should not parse bad import alias: No parenthesis',()=>{
86+
const content = fs.readFileSync('./test/cto/bad/aliasImport.bad.single.cto','utf-8');
87+
(()=>{
88+
Parser.parse(content);
89+
}).should.throw(/Expected .+ but/);
90+
});
91+
it('Should not parse bad import alias: alias missing',()=>{
92+
const content = fs.readFileSync('./test/cto/bad/aliasImport.bad.alias-missing.cto','utf-8');
93+
(()=>{
94+
Parser.parse(content);
95+
}).should.throw(/Expected .+ but/);
96+
});
97+
it('Should throw when type is alias to a pimitive type',()=>{
98+
const model=`
99+
namespace org.saluja
100+
101+
import org.ece.{doc as String}
102+
`;
103+
(() => {
104+
Parser.parse(model);
105+
}).should.throw(/cannot be aliased to a Primitive type/);
106+
});
107+
});
108+
84109
describe('self-extending', () => {
85110
const declarationTypes = [
86111
'asset',

0 commit comments

Comments
 (0)