From 39fa4c2acf35acd7c42376cedecd4fde2a751cf7 Mon Sep 17 00:00:00 2001 From: Yan Chen <48968912+chenyan-dfinity@users.noreply.github.com> Date: Tue, 12 Dec 2023 16:15:41 -0800 Subject: [PATCH 1/4] spec: allow import to merge service definitions --- spec/Candid.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/spec/Candid.md b/spec/Candid.md index c96c38fd..08e26834 100644 --- a/spec/Candid.md +++ b/spec/Candid.md @@ -1,8 +1,8 @@ # Candid Specification -Version: 0.1.6 +Version: 0.1.7 -Date: August 29, 2023 +Date: Dec 12, 2024 ## Motivation @@ -64,7 +64,7 @@ The purpose of an IDL is defining the signature, and thereby the *type* of an ac This is a summary of the grammar proposed: ``` ::= ;* ? - ::= type = | import + ::= type = | import | import* ::= service ? : ( ->)? ( | ) ;? ::= { ;* } @@ -519,20 +519,25 @@ type B = A; // error: cyclic type definition In order to allow splitting interface definitions up into multiple files or share common definitions between multiple interfaces, *import* declarations are provided. ``` - ::= ... | import + ::= ... | import | import* ``` -An import refers to another interface file by URL. The semantics is that of textual inclusion, except that definitions from the imported file must not refer to definitions from the importing file. +There are two forms of import: `import` and `import*`. Both `import` and `import*` refer to another interface file by URL. The type definitions from the imported file are textually included in the importing file. The definitions from the imported file must not refer to definitions from the importing file. + +In addition, `import*` includes the main service from the imported file and merges the service definition with the main service in the importing file. The methods in the imported file must not have the same name as the importing file. + +`import` ignores the main service definition from the imported file. ##### Example File `A.did`: ``` type A = service { f : () -> () }; +service : A ``` File `B.did`: ``` -import "A.did" +import "A.did"; // Cannot use import* because of method name duplication service B : A ; ``` From 63145efe02cc0d48ed7c2298a8a18a05e005bfb9 Mon Sep 17 00:00:00 2001 From: Yan Chen <48968912+chenyan-dfinity@users.noreply.github.com> Date: Wed, 13 Dec 2023 12:03:00 -0800 Subject: [PATCH 2/4] rename to import_service, and disallow service constructor --- spec/Candid.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/spec/Candid.md b/spec/Candid.md index 08e26834..cfb9ce20 100644 --- a/spec/Candid.md +++ b/spec/Candid.md @@ -64,7 +64,7 @@ The purpose of an IDL is defining the signature, and thereby the *type* of an ac This is a summary of the grammar proposed: ``` ::= ;* ? - ::= type = | import | import* + ::= type = | import | import_service ::= service ? : ( ->)? ( | ) ;? ::= { ;* } @@ -519,15 +519,18 @@ type B = A; // error: cyclic type definition In order to allow splitting interface definitions up into multiple files or share common definitions between multiple interfaces, *import* declarations are provided. ``` - ::= ... | import | import* + ::= ... | import | import_service ``` -There are two forms of import: `import` and `import*`. Both `import` and `import*` refer to another interface file by URL. The type definitions from the imported file are textually included in the importing file. The definitions from the imported file must not refer to definitions from the importing file. - -In addition, `import*` includes the main service from the imported file and merges the service definition with the main service in the importing file. The methods in the imported file must not have the same name as the importing file. +There are two forms of import: `import` and `import_service`. Both `import` and `import_service` refer to another interface file by URL. The type definitions from the imported file are textually included in the importing file. The definitions from the imported file must not refer to definitions from the importing file. `import` ignores the main service definition from the imported file. +`import_service` includes the main service from the imported file and merges the service definition with the main service in the importing file. There are two constraints with the main service definition in the imported file: + +* The main service cannot be a service constructor. +* The methods from the imported file must not have the same method name as the importing file. + ##### Example File `A.did`: @@ -537,7 +540,7 @@ service : A ``` File `B.did`: ``` -import "A.did"; // Cannot use import* because of method name duplication +import "A.did"; // Cannot use import_service because of method name duplication service B : A ; ``` From abdc405bca8d2e519c2b022df87626e89402b925 Mon Sep 17 00:00:00 2001 From: Yan Chen <48968912+chenyan-dfinity@users.noreply.github.com> Date: Thu, 14 Dec 2023 10:33:08 -0800 Subject: [PATCH 3/4] rename to import service --- spec/Candid.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/spec/Candid.md b/spec/Candid.md index cfb9ce20..d08754c1 100644 --- a/spec/Candid.md +++ b/spec/Candid.md @@ -64,7 +64,7 @@ The purpose of an IDL is defining the signature, and thereby the *type* of an ac This is a summary of the grammar proposed: ``` ::= ;* ? - ::= type = | import | import_service + ::= type = | import service? ::= service ? : ( ->)? ( | ) ;? ::= { ;* } @@ -519,14 +519,12 @@ type B = A; // error: cyclic type definition In order to allow splitting interface definitions up into multiple files or share common definitions between multiple interfaces, *import* declarations are provided. ``` - ::= ... | import | import_service + ::= ... | import service? ``` -There are two forms of import: `import` and `import_service`. Both `import` and `import_service` refer to another interface file by URL. The type definitions from the imported file are textually included in the importing file. The definitions from the imported file must not refer to definitions from the importing file. +An import refers to another interface file by URL. The type definitions from the imported file are textually included in the importing file. The definitions from the imported file must not refer to definitions from the importing file. -`import` ignores the main service definition from the imported file. - -`import_service` includes the main service from the imported file and merges the service definition with the main service in the importing file. There are two constraints with the main service definition in the imported file: +`import` ignores the main service definition from the imported file, while `import service` includes the main service from the imported file and merges the service definition with the main service in the importing file. There are two constraints with the main service definition in the imported file: * The main service cannot be a service constructor. * The methods from the imported file must not have the same method name as the importing file. From 65d21a39cdb93c92e69e85fda2dd5ba24bf58b90 Mon Sep 17 00:00:00 2001 From: Yan Chen <48968912+chenyan-dfinity@users.noreply.github.com> Date: Fri, 15 Dec 2023 10:03:23 -0800 Subject: [PATCH 4/4] Update spec/Candid.md Co-authored-by: Claudio Russo --- spec/Candid.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/Candid.md b/spec/Candid.md index d08754c1..e0329eea 100644 --- a/spec/Candid.md +++ b/spec/Candid.md @@ -538,7 +538,7 @@ service : A ``` File `B.did`: ``` -import "A.did"; // Cannot use import_service because of method name duplication +import "A.did"; // Cannot use `import service` because of method name duplication service B : A ; ```