From 1775589b965eb19b6ca0aec946d3d1a128b074c0 Mon Sep 17 00:00:00 2001 From: wangjin Date: Sun, 29 Sep 2024 21:24:21 +0800 Subject: [PATCH] update custom grammar api --- Makefile | 11 +- log.txt | 7 - src/grammar/doc.go | 315 ++++++ src/grammar/gendoc.go | 40 + src/grammar/grammar.go | 983 ++++++++++++++++-- website/docs/api/latest/command_line.mdx | 4 - website/docs/api/preview/grammar.mdx | 1176 +++++++++++++++++++++- website/src/pages/index.tsx | 4 +- 8 files changed, 2398 insertions(+), 142 deletions(-) delete mode 100644 log.txt create mode 100644 src/grammar/doc.go create mode 100644 src/grammar/gendoc.go diff --git a/Makefile b/Makefile index ae8e994..6670c75 100644 --- a/Makefile +++ b/Makefile @@ -25,9 +25,10 @@ ifeq (, $(shell which stringer)) @go install golang.org/x/tools/cmd/stringer@latest endif -.PHONY: go/generate -go/generate: deps/stringer +.PHONY: autogen +autogen: deps/stringer @echo "Running go generate..." + @cd src/grammar && go run gendoc.go -o doc.go @go generate ./... .PHONY: go/vet @@ -36,7 +37,7 @@ go/vet: @go vet ./... .PHONY: build -build: go/generate go/vet +build: autogen go/vet @echo "Building ${BUILD_BIN_DIR}/next..." @mkdir -p ${BUILD_DIR} @mkdir -p ${BUILD_BIN_DIR} @@ -74,7 +75,7 @@ define release_js endef .PHONY: release -release: go/generate go/vet +release: autogen go/vet @rm -f ${BUILD_DIR}/next.*.tar.gz ${BUILD_DIR}/next.*.zip ${BUILD_DIR}/*.wasm $(call release_unix,darwin,amd64) $(call release_unix,darwin,arm64) @@ -87,7 +88,7 @@ release: go/generate go/vet $(call release_js) .PHONY: test/src -test/src: go/generate go/vet +test/src: autogen go/vet @echo "Running tests..." @go test -v ./... diff --git a/log.txt b/log.txt deleted file mode 100644 index 81ee3e5..0000000 --- a/log.txt +++ /dev/null @@ -1,7 +0,0 @@ -Running go generate... -Markdown file generated successfully. -Markdown file generated successfully. -Running go vet... -Building ./build/bin/next... -Installing to /usr/local/bin/next... -Running template tests... diff --git a/src/grammar/doc.go b/src/grammar/doc.go new file mode 100644 index 0000000..10c427c --- /dev/null +++ b/src/grammar/doc.go @@ -0,0 +1,315 @@ +// Code generated by gendoc.go; DO NOT EDIT. + +package grammar + +// @api(Grammar.default) represents the default grammar for the next files. +// +//
+// default-grammar.json +// +// ```json +// { +// "Package": { +// "Annotations": [ +// { +// "Name": "next", +// "Description": "Built-in annotation for the next compiler.", +// "Parameters": [ +// { +// "Name": "available", +// "Description": "Sets the available target languages.", +// "Type": "bool" +// }, +// { +// "Name": "*_package", +// "Description": "Sets the package name for target languages.", +// "Type": "string", +// "Validators": [ +// { +// "Name": "LangPackageMustNotBeEmpty", +// "Expression": "{{ne .Name ``}}", +// "Message": "must not be empty" +// } +// ] +// }, +// { +// "Name": "*_imports", +// "Description": "Sets the import declarations for target languages.", +// "Type": "string" +// } +// ] +// }, +// { +// "Name": "deprecated", +// "Description": "Sets the declaration as deprecated.", +// "Parameters": [ +// { +// "Name": "message", +// "Description": "Sets the deprecation message.", +// "Type": "string" +// } +// ] +// } +// ] +// }, +// "Import": {}, +// "Const": { +// "Types": [ +// "bool", +// "int", +// "float", +// "string" +// ], +// "Annotations": [ +// { +// "Name": "next", +// "Description": "Built-in annotation for the next compiler.", +// "Parameters": [ +// { +// "Name": "available", +// "Description": "Sets the available target languages.", +// "Type": "bool" +// } +// ] +// }, +// { +// "Name": "deprecated", +// "Description": "Sets the declaration as deprecated.", +// "Parameters": [ +// { +// "Name": "message", +// "Description": "Sets the deprecation message.", +// "Type": "string" +// } +// ] +// } +// ] +// }, +// "Enum": { +// "Annotations": [ +// { +// "Name": "next", +// "Description": "Built-in annotation for the next compiler.", +// "Parameters": [ +// { +// "Name": "available", +// "Description": "Sets the available target languages.", +// "Type": "bool" +// }, +// { +// "Name": "type", +// "Description": "Sets the type for enum members.", +// "Type": "type" +// } +// ] +// }, +// { +// "Name": "deprecated", +// "Description": "Sets the declaration as deprecated.", +// "Parameters": [ +// { +// "Name": "message", +// "Description": "Sets the deprecation message.", +// "Type": "string" +// } +// ] +// } +// ], +// "Member": { +// "Types": [ +// "int", +// "float", +// "string" +// ], +// "Annotations": [ +// { +// "Name": "next", +// "Description": "Built-in annotation for the next compiler.", +// "Parameters": [ +// { +// "Name": "available", +// "Description": "Sets the available target languages.", +// "Type": "bool" +// } +// ] +// }, +// { +// "Name": "deprecated", +// "Description": "Sets the declaration as deprecated.", +// "Parameters": [ +// { +// "Name": "message", +// "Description": "Sets the deprecation message.", +// "Type": "string" +// } +// ] +// } +// ] +// } +// }, +// "Struct": { +// "Annotations": [ +// { +// "Name": "next", +// "Description": "Built-in annotation for the next compiler.", +// "Parameters": [ +// { +// "Name": "available", +// "Description": "Sets the available target languages.", +// "Type": "bool" +// }, +// { +// "Name": "*_alias", +// "Description": "Sets the alias name for target languages.", +// "Type": "string" +// } +// ] +// }, +// { +// "Name": "deprecated", +// "Description": "Sets the declaration as deprecated.", +// "Parameters": [ +// { +// "Name": "message", +// "Description": "Sets the deprecation message.", +// "Type": "string" +// } +// ] +// } +// ], +// "Field": { +// "Annotations": [ +// { +// "Name": "next", +// "Description": "Built-in annotation for the next compiler.", +// "Parameters": [ +// { +// "Name": "available", +// "Description": "Sets the available target languages.", +// "Type": "bool" +// } +// ] +// }, +// { +// "Name": "deprecated", +// "Description": "Sets the declaration as deprecated.", +// "Parameters": [ +// { +// "Name": "message", +// "Description": "Sets the deprecation message.", +// "Type": "string" +// } +// ] +// }, +// { +// "Name": "required", +// "Description": "Sets the field as required." +// }, +// { +// "Name": "optional", +// "Description": "Sets the field as optional." +// } +// ] +// } +// }, +// "Interface": { +// "Annotations": [ +// { +// "Name": "next", +// "Description": "Built-in annotation for the next compiler.", +// "Parameters": [ +// { +// "Name": "available", +// "Description": "Sets the available target languages.", +// "Type": "bool" +// }, +// { +// "Name": "*_alias", +// "Description": "Sets the alias name for target languages.", +// "Type": "string" +// } +// ] +// }, +// { +// "Name": "deprecated", +// "Description": "Sets the declaration as deprecated.", +// "Parameters": [ +// { +// "Name": "message", +// "Description": "Sets the deprecation message.", +// "Type": "string" +// } +// ] +// } +// ], +// "Method": { +// "Annotations": [ +// { +// "Name": "next", +// "Description": "Built-in annotation for the next compiler.", +// "Parameters": [ +// { +// "Name": "available", +// "Description": "Sets the available target languages.", +// "Type": "bool" +// }, +// { +// "Name": "mut", +// "Description": "Sets object or parameter as mutable.", +// "Type": "bool" +// }, +// { +// "Name": "error", +// "Description": "Indicates the method returns an error.", +// "Type": "bool" +// } +// ] +// }, +// { +// "Name": "deprecated", +// "Description": "Sets the declaration as deprecated.", +// "Parameters": [ +// { +// "Name": "message", +// "Description": "Sets the deprecation message.", +// "Type": "string" +// } +// ] +// } +// ], +// "Parameter": { +// "Annotations": [ +// { +// "Name": "next", +// "Description": "Built-in annotation for the next compiler.", +// "Parameters": [ +// { +// "Name": "available", +// "Description": "Sets the available target languages.", +// "Type": "bool" +// }, +// { +// "Name": "mut", +// "Description": "Sets object or parameter as mutable.", +// "Type": "bool" +// } +// ] +// }, +// { +// "Name": "deprecated", +// "Description": "Sets the declaration as deprecated.", +// "Parameters": [ +// { +// "Name": "message", +// "Description": "Sets the deprecation message.", +// "Type": "string" +// } +// ] +// } +// ] +// } +// } +// } +// } +// ``` +//
diff --git a/src/grammar/gendoc.go b/src/grammar/gendoc.go new file mode 100644 index 0000000..d9bdc51 --- /dev/null +++ b/src/grammar/gendoc.go @@ -0,0 +1,40 @@ +//go:build ignore + +// usage: go run gendoc.go -o doc.go + +package main + +import ( + "encoding/json" + "flag" + "fmt" + "os" + + "github.com/next/next/src/grammar" +) + +var filename = flag.String("o", "doc.go", "The filename to write the default API documentation to.") + +func main() { + flag.Parse() + + // Generate the default API + content, err := json.MarshalIndent(grammar.Default, "//\t", " ") + if err != nil { + panic(err) + } + os.WriteFile(*filename, []byte(fmt.Sprintf(`// Code generated by gendoc.go; DO NOT EDIT. + +package grammar + +// @api(Grammar.default) represents the default grammar for the next files. +// +//
+// default-grammar.json +// +// %s +// %s +// %s +//
+`, "```json", string(content), "```")), 0644) +} diff --git a/src/grammar/grammar.go b/src/grammar/grammar.go index 89b1093..63bbbb5 100644 --- a/src/grammar/grammar.go +++ b/src/grammar/grammar.go @@ -1,116 +1,138 @@ //go:generate go run github.com/gopherd/tools/cmd/docgen@v0.0.8 -ext .mdx -I ./ -o ../../website/docs/api/preview -level 0 -M "---" -M "pagination_prev: null" -M "pagination_next: null" -M "---" package grammar +const ( + Bool = "bool" + Int = "int" + Float = "float" + String = "string" + Type = "type" +) + // @api(Grammar) represents the custom grammar for the next files. // // The grammar is used to define a subset of the next files. It can limit the features of the next code according // by your requirements. The grammar is a JSON object that contains rules. type Grammar struct { - // @api(Grammar.Package) represents the [Package](#Grammar/Package) grammar rules for the package declaration. - // - // Example: - // - // ```json - // { - // "Package": { - // } - // } - // ``` - // - // See [Package](#Grammar/Package) for more details. - Package Package - - Import struct { - Off bool // import declaration is off - Annotations []Annotation - } - Const struct { - Off bool // const declaration is off - Types []string // type names: bool, int, float, string - Annotations []Annotation - } - Enum struct { - Off bool // enum declaration is off - Types []string // type names: int, float, string - Annotations []Annotation - Member struct { - Annotations []Annotation - ValueRequired bool // value is required - OffValueExpr bool // value expression is off - OffIota bool // iota is off - Validators []Validator - } - } - Struct struct { - Off bool // struct declaration is off - Annotations []Annotation - Field struct { - Annotations []Annotation - Validators []Validator - } - } - Interface struct { - Off bool // interface declaration is off - Annotations []Annotation - Method struct { - Annotations []Annotation - Validators []Validator - Param struct { - Annotations []Annotation - Validators []Validator - } - } - } + Package Package + Import Import + Const Const + Enum Enum + Struct Struct + Interface Interface } -// @api(Grammar/Validator) represents the validator for the grammar rules. +// @api(Grammar/Common/Validator) represents the validator for the grammar rules. type Validator struct { - // @api(Grammar/Validator.Name) represents the validator name. + // @api(Grammar/Common/Validator.Name) represents the validator name. Name string - // @api(Grammar/Validator.Expression) represents the validator expression. + // @api(Grammar/Common/Validator.Expression) represents the validator expression. // The expression is a template string that can access the data by the `.` operator. The expression // must return a boolean value. // // The data is the current context object. For example, **package** object for the package validator. Expression string - // @api(Grammar/Validator.Message) represents the error message when the validator is failed. + // @api(Grammar/Common/Validator.Message) represents the error message when the validator is failed. Message string } -// @api(Grammar/Annotation) represents the annotation grammar rules. +// @api(Grammar/Common/Annotation) represents the annotation grammar rules. // Only the built-in annotations are supported if no annotations are defined in the grammar. // -// :::warning +// Example: +// +// ```json +// { +// "Struct": { +// "Annotations": [ +// { +// "Name": "message", +// "Description": "Sets the struct as a message.", +// "Parameters": [ +// { +// "Name": "type", +// "Description": "Sets the message type id.", +// "Type": "int", +// "Required": true +// "Validators": [ +// { +// "Name": "MessageTypeMustBePositive", +// "Expression": "{{gt . 0}}", +// "Message": "message type must be positive" +// } +// ] +// } +// ] +// } +// ] +// } +// } +// ``` // -// You **CAN NOT** define the built-in annotations in the grammar. +// ```next +// package demo; // -// ::: +// // Good +// @message(type=1) +// struct User { +// int id; +// string name; +// } +// +// // This will error +// @message +// struct User { +// int id; +// string name; +// } +// // Error: message type is required +// +// // This will error +// @message(type) +// struct User { +// int id; +// string name; +// } +// // Error: message type must be an integer +// +// // This will error +// @message(type=-1) +// struct User { +// int id; +// string name; +// } +// // Error: message type must be positive +// ``` type Annotation struct { - // @api(Grammar/Annotation.Name) represents the annotation name. + // @api(Grammar/Common/Annotation.Name) represents the annotation name pattern. Name string - // @api(Grammar/Annotation.Description) represents the annotation description. + // @api(Grammar/Common/Annotation.Description) represents the annotation description. Description string - // @api(Grammar/Annotation.Required) represents the annotation is required or not. - Required bool - - // @api(Grammar/Annotation.Validators) represents the [Validator](#Grammar/Validator) for the annotation. - Validators []Validator - - // @api(Grammar/Annotation.Parameters) represents the annotation parameters. - Parameters []AnnotationParameter + // @api(Grammar/Common/Annotation.Parameters) represents the annotation parameters. + Parameters []AnnotationParameter `json:",omitempty"` } -// @api(Grammar/Annotation/Parameter) represents the annotation parameter grammar rules. +// @api(Grammar/Common/AnnotationParameter) represents the annotation parameter grammar rules. // If no parameters are defined, the annotation does not have any parameters. type AnnotationParameter struct { - // @api(Grammar/Annotation/Parameter.Name) represents the parameter name. + // @api(Grammar/Common/AnnotationParameter.Name) represents the parameter name pattern. + // The name pattern is a regular expression that can be used to match the annotation parameter name. + // + // Example: + // + // - "**type**": matches the annotation name `type` + // - "**x|y**": matches the annotation name `x` or `y` + // - "**\*_package**": matches the annotation name that ends with `_package`, for example, `cpp_package`, `java_package`, etc. Name string - // @api(Grammar/Annotation/Parameter.Type) represents the parameter type. + // @api(Grammar/Common/AnnotationParameter.Description) represents the parameter description. + Description string + + // @api(Grammar/Common/AnnotationParameter.Type) represents the parameter type. // The type is a string that can be one of the following types: // // - **bool**: boolean type, the value can be `true` or `false` @@ -120,20 +142,19 @@ type AnnotationParameter struct { // - **type**: any type name, for example, `int`, `float`, `string`, etc. Custom type names are supported. Type string - // @api(Grammar/Annotation/Parameter.Required) represents the parameter is required or not. - Required bool + // @api(Grammar/Common/AnnotationParameter.Required) represents the parameter is required or not. + Required bool `json:",omitempty"` - // @api(Grammar/Annotation/Parameter.Validators) represents the [Validator](#Grammar/Validator) for the annotation parameter. - Validators []Validator + // @api(Grammar/Common/AnnotationParameter.Validators) represents the [Validator](#Grammar/Common/Validator) for the annotation parameter. + Validators []Validator `json:",omitempty"` } // @api(Grammar/Package) represents the grammar rules for the package declaration. type Package struct { - // @api(Grammar/Package.Annotations) represents the [AnnotationGrammar](#Grammar/Annotation) rules for the package declaration. - // It extends the built-in annotations. - Annotations []Annotation + // @api(Grammar/Package.Annotations) represents the [Annotation](#Grammar/Common/Annotation) grammar rules for the package declaration. + Annotations []Annotation `json:",omitempty"` - // @api(Grammar/Package.Validators) represents the [Validator](#Grammar/Validator) for the package declaration. + // @api(Grammar/Package.Validators) represents the [Validator](#Grammar/Common/Validator) for the package declaration. // It's used to validate the package name. For example, You can limit the package name must be // not start with a "_" character. The validator expression is a template string that can access // package name by `.Name`. @@ -159,5 +180,797 @@ type Package struct { // package _test; // // Error: package name must not start with an underscore // ``` - Validators []Validator + Validators []Validator `json:",omitempty"` +} + +// @api(Grammar/Import) represents the grammar rules for the import declaration. +type Import struct { + // @api(Grammar/Import.Off) represents the import declaration is off or not. + // If the import declaration is off, the import declaration is not allowed in the next files. + // + // Example: + // + // ```json + // { + // "Import": { + // "Off": true + // } + // } + // ``` + // + // ```next + // package demo; + // + // // This will error + // import "other.next"; + // // Error: import declaration is not allowed + // ``` + Off bool `json:",omitempty"` +} + +// @api(Grammar/Const) represents the grammar rules for the const declaration. +type Const struct { + // @api(Grammar/Const.Off) represents the const declaration is off or not. + // If the const declaration is off, the const declaration is not allowed in the next files. + // + // Example: + // + // ```json + // { + // "Const": { + // "Off": true + // } + // } + // ``` + // + // ```next + // package demo; + // + // // This will error + // const x = 1; + // // Error: const declaration is not allowed + // ``` + Off bool `json:",omitempty"` + + // @api(Grammar/Const.Types) represents a list of type names that are supported in the const declaration. + // If no types are defined, the const declaration supports all types. Otherwise, the const declaration + // only supports the specified types. + // + // Currently, each type name can be one of the following types: + // + // - **bool**: boolean type, the value can be `true` or `false` + // - **int**: integer type, the value can be a positive or negative integer, for example, `123` + // - **float**: float type, the value can be a positive or negative float, for example, `1.23` + // - **string**: string type, the value can be a string, for example, `"hello"` + // + // Example: + // + // ```json + // { + // "Const": { + // "Types": ["int", "float"] + // } + // } + // ``` + // + // ```next + // package demo; + // + // const x = 1; // Good + // const y = 1.23; // Good + // + // // This will error + // const z = "hello"; + // // Error: string type is not allowed in the const declaration + // ``` + Types []string `json:",omitempty"` + + // @api(Grammar/Const.Annotations) represents the [Annotation](#Grammar/Common/Annotation) grammar rules for the const declaration. + Annotations []Annotation `json:",omitempty"` + + // @api(Grammar/Const.Validators) represents the [Validator](#Grammar/Common/Validator) for the const declaration. + // It's used to validate the const name. You can access the const name by `.Name`. + // + // Example: + // + // ```json + // { + // "Const": { + // "Validators": [ + // { + // "Name": "ConstNameMustBeCapitalized", + // "Expression": "{{eq .Name (.Name | capitalize)}}", + // "Message": "const name must be capitalized" + // } + // ] + // } + // } + // ``` + // + // ```next + // package demo; + // + // const Hello = 1; // Good + // + // // This will error + // const world = 1; + // // Error: const name must be capitalized, expected: World + // ``` + Validators []Validator `json:",omitempty"` +} + +// @api(Grammar/Enum) represents the grammar rules for the enum declaration. +type Enum struct { + // @api(Grammar/Enum.Off) represents the enum declaration is off or not. + // If the enum declaration is off, the enum declaration is not allowed in the next files. + // + // Example: + // + // ```json + // { + // "Enum": { + // "Off": true + // } + // } + // ``` + // + // ```next + // package demo; + // + // // This will error + // enum Color { + // Red; + // Green; + // Blue; + // } + // // Error: enum declaration is not allowed + // ``` + Off bool `json:",omitempty"` + + // @api(Grammar/Enum.Annotations) represents the [Annotation](#Grammar/Common/Annotation) grammar rules for the enum declaration. + Annotations []Annotation `json:",omitempty"` + + // @api(Grammar/Enum.Validators) represents the [Validator](#Grammar/Common/Validator) for the enum declaration. + // It's used to validate the enum name. You can access the enum name by `.Name`. + // + // Example: + // + // ```json + // { + // "Enum": { + // "Validators": [ + // { + // "Name": "EnumNameMustBeCapitalized", + // "Expression": "{{eq .Name (.Name | capitalize)}}", + // "Message": "enum name must be capitalized" + // } + // ] + // } + // } + // ``` + // + // ```next + // package demo; + // + // // Good + // enum Color { + // Red; + // Green; + // Blue; + // } + // + // // This will error + // enum size { + // Small; + // Medium; + // Large; + // } + // // Error: enum name must be capitalized, expected: Size + // ``` + Validators []Validator `json:",omitempty"` + + // @api(Grammar/Enum.Member) represents the [EnumMember](#Grammar/EnumMember) grammar rules for the enum declaration. + Member EnumMember +} + +// @api(Grammar/EnumMember) represents the grammar rules for the enum member declaration. +type EnumMember struct { + // @api(Grammar/EnumMember.OffValueExpr) represents the enum member value expression is off or not. + // If the enum member value expression is off, the enum member value expression is not allowed in the next files. + // + // Example: + // + // ```json + // { + // "Enum": { + // "Member": { + // "OffValueExpr": true + // } + // } + // } + // ``` + // + // ```next + // package demo; + // + // enum Size { + // Small; + // Medium; + // // This will error + // Large = Small + Medium; + // // Error: enum member value expression is not allowed + // } + // ``` + OffValueExpr bool `json:",omitempty"` + + // @api(Grammar/EnumMember.OffIota) represents the enum member iota value is off or not. + // If the enum member iota value is off, the enum member iota value is not allowed in the next files. + // + // Example: + // + // ```json + // { + // "Enum": { + // "Member": { + // "OffIota": true + // } + // } + // } + // ``` + // + // ```next + // package demo; + // + // enum Size { + // // This will error + // Small = iota; + // // Error: enum member iota value is not allowed + // Medium; + // Large; + // } + // ``` + OffIota bool `json:",omitempty"` + + // @api(Grammar/EnumMember.Types) represents a list of type names that are supported in the enum declaration. + // + // If no types are defined, the enum declaration supports all types. Otherwise, the enum declaration + // only supports the specified types. + // + // Currently, each type name can be one of the following types: + // + // - **int**: integer type, the value can be a positive or negative integer, for example, `123` + // - **float**: float type, the value can be a positive or negative float, for example, `1.23` + // - **string**: string type, the value can be a string, for example, `"hello"` + // + // Example: + // + // ```json + // { + // "Enum": { + // "Member": { + // "Types": ["int"] + // } + // } + // } + // ``` + // + // ```next + // package demo; + // + // // Good + // enum Color { + // Red = 1, + // Green = 2, + // Blue = 3 + // } + // + // // This will error + // enum Size { + // Small = "small", + // Medium = "medium", + // Large = "large" + // } + // // Error: string type is not allowed in the enum declaration + // ``` + Types []string `json:",omitempty"` + + // @api(Grammar/EnumMember.ValueRequired) represents the enum member value is required or not. + // If the enum member value is required, the enum member value must be specified in the next files. + // + // Example: + // + // ```json + // { + // "Enum": { + // "Member": { + // "ValueRequired": true + // } + // } + // } + // ``` + // + // ```next + // package demo; + // + // enum Size { + // Small = 1, + // Medium = 2; + // // This will error + // Large; + // // Error: enum member value is required + // } + // ``` + ValueRequired bool `json:",omitempty"` + + // @api(Grammar/EnumMember.ZeroRequired) represents the enum member zero value for integer types is required or not. + // + // If the enum member zero value is required, the enum member zero value must be specified in the next files. + // + // Example: + // + // ```json + // { + // "Enum": { + // "Member": { + // "ZeroRequired": true + // } + // } + // } + // ``` + // + // ```next + // package demo; + // + // // This will error + // enum Size { + // Small = 1, + // Medium = 2, + // Large = 3; + // } + // // Error: enum member zero value is required, for example: + // // enum Size { + // // Small = 0, + // // Medium = 1, + // // Large = 2 + // // } + // ``` + ZeroRequired bool `json:",omitempty"` + + // @api(Grammar/EnumMember.Annotations) represents the [Annotation](#Grammar/Common/Annotation) grammar rules for the enum member declaration. + Annotations []Annotation `json:",omitempty"` + + // @api(Grammar/EnumMember.Validators) represents the [Validator](#Grammar/Common/Validator) for the enum member declaration. + // + // It's used to validate the enum member name. You can access the enum member name by `.Name`. + // + // Example: + // + // ```json + // { + // "Enum": { + // "Member": { + // "Validators": [ + // { + // "Name": "EnumMemberNameMustBeCapitalized", + // "Expression": "{{eq .Name (.Name | capitalize)}}", + // "Message": "enum member name must be capitalized" + // } + // ] + // } + // } + // } + // ``` + // + // ```next + // package demo; + // + // enum Size { + // Small = 1, + // Medium = 2, + // // This will error + // large = 3; + // // Error: enum member name must be capitalized, expected: Large + // } + // ``` + Validators []Validator `json:",omitempty"` +} + +// @api(Grammar/Struct) represents the grammar rules for the struct declaration. +type Struct struct { + // @api(Grammar/Struct.Off) represents the struct declaration is off or not. + // If the struct declaration is off, the struct declaration is not allowed in the next files. + // + // Example: + // + // ```json + // { + // "Struct": { + // "Off": true + // } + // } + // ``` + // + // ```next + // package demo; + // + // // This will error + // struct User { + // ID int; + // Name string; + // } + // // Error: struct declaration is not allowed + // ``` + Off bool `json:",omitempty"` + + // @api(Grammar/Struct.Annotations) represents the [Annotation](#Grammar/Common/Annotation) grammar rules for the struct declaration. + Annotations []Annotation `json:",omitempty"` + + // @api(Grammar/Struct.Validators) represents the [Validator](#Grammar/Common/Validator) for the struct declaration. + // It's used to validate the struct name. You can access the struct name by `.Name`. + // + // Example: + // + // ```json + // { + // "Struct": { + // "Validators": [ + // { + // "Name": "StructNameMustBeCapitalized", + // "Expression": "{{eq .Name (.Name | capitalize)}}", + // "Message": "struct name must be capitalized" + // } + // ] + // } + // } + // ``` + // + // ```next + // package demo; + // + // // Good + // struct User { + // int id; + // string name; + // } + // + // // This will error + // struct point { + // int x; + // int y; + // } + // // Error: struct name must be capitalized, expected: Point + // ``` + Validators []Validator `json:",omitempty"` + + // @api(Grammar/Struct.Field) represents the [StructField](#Grammar/StructField) grammar rules for the struct declaration. + Field StructField +} + +// @api(Grammar/StructField) represents the grammar rules for the struct field declaration. +type StructField struct { + // @api(Grammar/StructField.Annotations) represents the [Annotation](#Grammar/Common/Annotation) grammar rules for the struct field declaration. + Annotations []Annotation `json:",omitempty"` + + // @api(Grammar/StructField.Validators) represents the [Validator](#Grammar/Common/Validator) for the struct field declaration. + // It's used to validate the struct field name. You can access the struct field name by `.Name`. + // + // Example: + // + // ```json + // { + // "Struct": { + // "Field": { + // "Validators": [ + // { + // "Name": "StructFieldNameMustNotBeCapitalized", + // "Expression": "{{ne .Name (capitalize .Name)}}", + // "Message": "struct field name must not be capitalized" + // } + // ] + // } + // } + // } + // ``` + // + // ```next + // package demo; + // + // struct User { + // int id; + // // This will error + // string Name; + // // Error: struct field name must not be capitalized, expected: name + // } + // ``` + Validators []Validator `json:",omitempty"` +} + +// @api(Grammar/Interface) represents the grammar rules for the interface declaration. +type Interface struct { + // @api(Grammar/Interface.Off) represents the interface declaration is off or not. + // If the interface declaration is off, the interface declaration is not allowed in the next files. + // + // Example: + // + // ```json + // { + // "Interface": { + // "Off": true + // } + // } + // ``` + // + // ```next + // package demo; + // + // // This will error + // interface User { + // GetID() int; + // } + // // Error: interface declaration is not allowed + // ``` + Off bool `json:",omitempty"` + + // @api(Grammar/Interface.Annotations) represents the [Annotation](#Grammar/Common/Annotation) grammar rules for the interface declaration. + Annotations []Annotation `json:",omitempty"` + + // @api(Grammar/Interface.Validators) represents the [Validator](#Grammar/Common/Validator) for the interface declaration. + // It's used to validate the interface name. You can access the interface name by `.Name`. + // + // Example: + // + // ```json + // { + // "Interface": { + // "Validators": [ + // { + // "Name": "InterfaceNameMustBeCapitalized", + // "Expression": "{{eq .Name (.Name | capitalize)}}", + // "Message": "interface name must be capitalized" + // } + // ] + // } + // } + // ``` + // + // ```next + // package demo; + // + // // Good + // interface User { + // GetID() int; + // } + // + // // This will error + // interface user { + // GetName() string; + // } + // // Error: interface name must be capitalized, expected: User + // ``` + Validators []Validator `json:",omitempty"` + + // @api(Grammar/Interface.Method) represents the [InterfaceMethod](#Grammar/InterfaceMethod) grammar rules for the interface declaration. + Method InterfaceMethod +} + +// @api(Grammar/InterfaceMethod) represents the grammar rules for the interface method declaration. +// +// Example: +// +// ```json +// { +// "Interface": { +// "Method": { +// "Annotations": [ +// { +// "Name": "http", +// "Description": "Sets the method as an HTTP handler.", +// "Parameters": [ +// { +// "Name": "method", +// "Description": "Sets the HTTP method.", +// "Type": "string", +// "Required": true +// "Validators": [ +// { +// "Name": "HTTPMethodMustBeValid", +// "Expression": "{{includes (list `GET` `POST` `PUT` `DELETE` `PATCH` `HEAD` `OPTIONS` `TRACE` `CONNECT`) .}}", +// "Message": "http method must be valid" +// } +// ] +// } +// ] +// } +// ], +// "Validators": [ +// { +// "Name": "MethodNameMustBeCapitalized", +// "Expression": "{{eq .Name (.Name | capitalize)}}", +// "Message": "method name must be capitalized" +// } +// ] +// } +// } +// } +// ``` +type InterfaceMethod struct { + // @api(Grammar/InterfaceMethod.Annotations) represents the [Annotation](#Grammar/Common/Annotation) grammar rules for the interface method declaration. + Annotations []Annotation `json:",omitempty"` + + // @api(Grammar/InterfaceMethod.Validators) represents the [Validator](#Grammar/Common/Validator) for the interface method declaration. + Validators []Validator `json:",omitempty"` + + // @api(Grammar/InterfaceMethod/Parameter) represents the grammar rules for the interface method parameter declaration. + Parameter struct { + // @api(Grammar/InterfaceMethod/Parameter.Annotations) represents the [Annotation](#Grammar/Common/Annotation) grammar rules for the interface method parameter declaration. + Annotations []Annotation `json:",omitempty"` + // @api(Grammar/InterfaceMethod/Parameter.Validators) represents the [Validator](#Grammar/Common/Validator) for the interface method parameter declaration. + Validators []Validator `json:",omitempty"` + } +} + +const notEmpty = "{{ne .Name ``}}" + +func next(parameters ...AnnotationParameter) Annotation { + return Annotation{ + Name: "next", + Description: "Built-in annotation for the next compiler.", + Parameters: parameters, + } +} + +func deprecated() Annotation { + return Annotation{ + Name: "deprecated", + Description: "Sets the declaration as deprecated.", + Parameters: []AnnotationParameter{ + { + Name: "message", + Description: "Sets the deprecation message.", + Type: String, + }, + }, + } +} + +func required() Annotation { + return Annotation{ + Name: "required", + Description: "Sets the field as required.", + } +} + +func optional() Annotation { + return Annotation{ + Name: "optional", + Description: "Sets the field as optional.", + } +} + +func available() AnnotationParameter { + return AnnotationParameter{ + Name: "available", + Description: "Sets the available target languages.", + Type: Bool, + } +} + +func mut() AnnotationParameter { + return AnnotationParameter{ + Name: "mut", + Description: "Sets object or parameter as mutable.", + Type: Bool, + } +} + +func error() AnnotationParameter { + return AnnotationParameter{ + Name: "error", + Description: "Indicates the method returns an error.", + Type: Bool, + } +} + +func type_() AnnotationParameter { + return AnnotationParameter{ + Name: "type", + Description: "Sets the type for enum members.", + Type: Type, + } +} + +func star_package() AnnotationParameter { + return AnnotationParameter{ + Name: "*_package", + Description: "Sets the package name for target languages.", + Type: String, + Validators: []Validator{ + { + Name: "LangPackageMustNotBeEmpty", + Expression: notEmpty, + Message: "must not be empty", + }, + }, + } +} + +func star_imports() AnnotationParameter { + return AnnotationParameter{ + Name: "*_imports", + Description: "Sets the import declarations for target languages.", + Type: String, + } +} + +func star_alias() AnnotationParameter { + return AnnotationParameter{ + Name: "*_alias", + Description: "Sets the alias name for target languages.", + Type: String, + } +} + +// Default represents the default grammar for the next files. +var Default = Grammar{ + Package: Package{ + Annotations: []Annotation{ + next(available(), star_package(), star_imports()), + deprecated(), + }, + }, + Const: Const{ + Types: []string{Bool, Int, Float, String}, + Annotations: []Annotation{ + next(available()), + deprecated(), + }, + }, + Enum: Enum{ + Annotations: []Annotation{ + next(available(), type_()), + deprecated(), + }, + Member: EnumMember{ + Types: []string{Int, Float, String}, + Annotations: []Annotation{ + next(available()), + deprecated(), + }, + }, + }, + Struct: Struct{ + Annotations: []Annotation{ + next(available(), star_alias()), + deprecated(), + }, + Field: StructField{ + Annotations: []Annotation{ + next(available()), + deprecated(), + required(), + optional(), + }, + }, + }, + Interface: Interface{ + Annotations: []Annotation{ + next(available(), star_alias()), + deprecated(), + }, + Method: InterfaceMethod{ + Annotations: []Annotation{ + next(available(), mut(), error()), + deprecated(), + }, + Parameter: struct { + Annotations []Annotation `json:",omitempty"` + Validators []Validator `json:",omitempty"` + }{ + Annotations: []Annotation{ + next(available(), mut()), + deprecated(), + }, + }, + }, + }, } diff --git a/website/docs/api/latest/command_line.mdx b/website/docs/api/latest/command_line.mdx index dd3d198..9a01950 100644 --- a/website/docs/api/latest/command_line.mdx +++ b/website/docs/api/latest/command_line.mdx @@ -102,10 +102,6 @@ In the example above, the `message-type-allocator` is a custom annotation solver ::: -### -grammar {#user-content-CommandLine_Flag_-grammar} - -`-grammar` represents the custom grammar for the next source code. - ### -header {#user-content-CommandLine_Flag_-header} `-header` represents the header comment for generated code. The value is a string that represents the header comment for generated code. The default value is an empty string, which means default header comment is used. diff --git a/website/docs/api/preview/grammar.mdx b/website/docs/api/preview/grammar.mdx index 7df3b73..06f4bbf 100644 --- a/website/docs/api/preview/grammar.mdx +++ b/website/docs/api/preview/grammar.mdx @@ -8,104 +8,1096 @@ pagination_next: null The grammar is used to define a subset of the next files. It can limit the features of the next code according by your requirements. The grammar is a JSON object that contains rules. -###### .Package {#user-content-Grammar__Package} +###### .default {#user-content-Grammar__default}
-`.Package` represents the [Package](#user-content-Grammar_Package) grammar rules for the package declaration. +`.default` represents the default grammar for the next files. -Example: +
+default-grammar.json ```json { "Package": { + "Annotations": [ + { + "Name": "next", + "Description": "Built-in annotation for the next compiler.", + "Parameters": [ + { + "Name": "available", + "Description": "Sets the available target languages.", + "Type": "bool" + }, + { + "Name": "*_package", + "Description": "Sets the package name for target languages.", + "Type": "string", + "Validators": [ + { + "Name": "LangPackageMustNotBeEmpty", + "Expression": "{{ne .Name ``}}", + "Message": "must not be empty" + } + ] + }, + { + "Name": "*_imports", + "Description": "Sets the import declarations for target languages.", + "Type": "string" + } + ] + }, + { + "Name": "deprecated", + "Description": "Sets the declaration as deprecated.", + "Parameters": [ + { + "Name": "message", + "Description": "Sets the deprecation message.", + "Type": "string" + } + ] + } + ] + }, + "Import": {}, + "Const": { + "Types": [ + "bool", + "int", + "float", + "string" + ], + "Annotations": [ + { + "Name": "next", + "Description": "Built-in annotation for the next compiler.", + "Parameters": [ + { + "Name": "available", + "Description": "Sets the available target languages.", + "Type": "bool" + } + ] + }, + { + "Name": "deprecated", + "Description": "Sets the declaration as deprecated.", + "Parameters": [ + { + "Name": "message", + "Description": "Sets the deprecation message.", + "Type": "string" + } + ] + } + ] + }, + "Enum": { + "Annotations": [ + { + "Name": "next", + "Description": "Built-in annotation for the next compiler.", + "Parameters": [ + { + "Name": "available", + "Description": "Sets the available target languages.", + "Type": "bool" + }, + { + "Name": "type", + "Description": "Sets the type for enum members.", + "Type": "type" + } + ] + }, + { + "Name": "deprecated", + "Description": "Sets the declaration as deprecated.", + "Parameters": [ + { + "Name": "message", + "Description": "Sets the deprecation message.", + "Type": "string" + } + ] + } + ], + "Member": { + "Types": [ + "int", + "float", + "string" + ], + "Annotations": [ + { + "Name": "next", + "Description": "Built-in annotation for the next compiler.", + "Parameters": [ + { + "Name": "available", + "Description": "Sets the available target languages.", + "Type": "bool" + } + ] + }, + { + "Name": "deprecated", + "Description": "Sets the declaration as deprecated.", + "Parameters": [ + { + "Name": "message", + "Description": "Sets the deprecation message.", + "Type": "string" + } + ] + } + ] + } + }, + "Struct": { + "Annotations": [ + { + "Name": "next", + "Description": "Built-in annotation for the next compiler.", + "Parameters": [ + { + "Name": "available", + "Description": "Sets the available target languages.", + "Type": "bool" + }, + { + "Name": "*_alias", + "Description": "Sets the alias name for target languages.", + "Type": "string" + } + ] + }, + { + "Name": "deprecated", + "Description": "Sets the declaration as deprecated.", + "Parameters": [ + { + "Name": "message", + "Description": "Sets the deprecation message.", + "Type": "string" + } + ] + } + ], + "Field": { + "Annotations": [ + { + "Name": "next", + "Description": "Built-in annotation for the next compiler.", + "Parameters": [ + { + "Name": "available", + "Description": "Sets the available target languages.", + "Type": "bool" + } + ] + }, + { + "Name": "deprecated", + "Description": "Sets the declaration as deprecated.", + "Parameters": [ + { + "Name": "message", + "Description": "Sets the deprecation message.", + "Type": "string" + } + ] + }, + { + "Name": "required", + "Description": "Sets the field as required." + }, + { + "Name": "optional", + "Description": "Sets the field as optional." + } + ] + } + }, + "Interface": { + "Annotations": [ + { + "Name": "next", + "Description": "Built-in annotation for the next compiler.", + "Parameters": [ + { + "Name": "available", + "Description": "Sets the available target languages.", + "Type": "bool" + }, + { + "Name": "*_alias", + "Description": "Sets the alias name for target languages.", + "Type": "string" + } + ] + }, + { + "Name": "deprecated", + "Description": "Sets the declaration as deprecated.", + "Parameters": [ + { + "Name": "message", + "Description": "Sets the deprecation message.", + "Type": "string" + } + ] + } + ], + "Method": { + "Annotations": [ + { + "Name": "next", + "Description": "Built-in annotation for the next compiler.", + "Parameters": [ + { + "Name": "available", + "Description": "Sets the available target languages.", + "Type": "bool" + }, + { + "Name": "mut", + "Description": "Sets object or parameter as mutable.", + "Type": "bool" + }, + { + "Name": "error", + "Description": "Indicates the method returns an error.", + "Type": "bool" + } + ] + }, + { + "Name": "deprecated", + "Description": "Sets the declaration as deprecated.", + "Parameters": [ + { + "Name": "message", + "Description": "Sets the deprecation message.", + "Type": "string" + } + ] + } + ], + "Parameter": { + "Annotations": [ + { + "Name": "next", + "Description": "Built-in annotation for the next compiler.", + "Parameters": [ + { + "Name": "available", + "Description": "Sets the available target languages.", + "Type": "bool" + }, + { + "Name": "mut", + "Description": "Sets object or parameter as mutable.", + "Type": "bool" + } + ] + }, + { + "Name": "deprecated", + "Description": "Sets the declaration as deprecated.", + "Parameters": [ + { + "Name": "message", + "Description": "Sets the deprecation message.", + "Type": "string" + } + ] + } + ] + } + } } } ``` - -See [Package](#user-content-Grammar_Package) for more details. +
-## Annotation {#user-content-Grammar_Annotation} +## Common {#user-content-Grammar_Common} +### Annotation {#user-content-Grammar_Common_Annotation} `Annotation` represents the annotation grammar rules. Only the built-in annotations are supported if no annotations are defined in the grammar. -:::warning +Example: + +```json +{ + "Struct": { + "Annotations": [ + { + "Name": "message", + "Description": "Sets the struct as a message.", + "Parameters": [ + { + "Name": "type", + "Description": "Sets the message type id.", + "Type": "int", + "Required": true + "Validators": [ + { + "Name": "MessageTypeMustBePositive", + "Expression": "{{gt . 0}}", + "Message": "message type must be positive" + } + ] + } + ] + } + ] + } +} +``` -You **CAN NOT** define the built-in annotations in the grammar. +```next +package demo; -::: +// Good +@message(type=1) +struct User { + int id; + string name; +} -###### .Description {#user-content-Grammar_Annotation__Description} +// This will error +@message +struct User { + int id; + string name; +} +// Error: message type is required + +// This will error +@message(type) +struct User { + int id; + string name; +} +// Error: message type must be an integer + +// This will error +@message(type=-1) +struct User { + int id; + string name; +} +// Error: message type must be positive +``` + +###### .Description {#user-content-Grammar_Common_Annotation__Description}
`.Description` represents the annotation description.
-###### .Name {#user-content-Grammar_Annotation__Name} +###### .Name {#user-content-Grammar_Common_Annotation__Name}
-`.Name` represents the annotation name. +`.Name` represents the annotation name pattern.
-###### .Parameters {#user-content-Grammar_Annotation__Parameters} +###### .Parameters {#user-content-Grammar_Common_Annotation__Parameters}
`.Parameters` represents the annotation parameters.
-###### .Required {#user-content-Grammar_Annotation__Required} +### AnnotationParameter {#user-content-Grammar_Common_AnnotationParameter} + +`AnnotationParameter` represents the annotation parameter grammar rules. If no parameters are defined, the annotation does not have any parameters. + +###### .Description {#user-content-Grammar_Common_AnnotationParameter__Description}
-`.Required` represents the annotation is required or not. +`.Description` represents the parameter description.
-###### .Validators {#user-content-Grammar_Annotation__Validators} +###### .Name {#user-content-Grammar_Common_AnnotationParameter__Name}
-`.Validators` represents the [Validator](#user-content-Grammar_Validator) for the annotation. +`.Name` represents the parameter name pattern. The name pattern is a regular expression that can be used to match the annotation parameter name. + +Example: + +- "**type**": matches the annotation name `type` +- "**x|y**": matches the annotation name `x` or `y` +- "**\*_package**": matches the annotation name that ends with `_package`, for example, `cpp_package`, `java_package`, etc.
-### Parameter {#user-content-Grammar_Annotation_Parameter} +###### .Required {#user-content-Grammar_Common_AnnotationParameter__Required} +
-`Parameter` represents the annotation parameter grammar rules. If no parameters are defined, the annotation does not have any parameters. +`.Required` represents the parameter is required or not. + +
-###### .Name {#user-content-Grammar_Annotation_Parameter__Name} +###### .Type {#user-content-Grammar_Common_AnnotationParameter__Type}
-`.Name` represents the parameter name. +`.Type` represents the parameter type. The type is a string that can be one of the following types: + +- **bool**: boolean type, the value can be `true` or `false` +- **int**: integer type, the value can be a positive or negative integer, for example, `123` +- **float**: float type, the value can be a positive or negative float, for example, `1.23` +- **string**: string type, the value can be a string, for example, `"hello"` +- **type**: any type name, for example, `int`, `float`, `string`, etc. Custom type names are supported.
-###### .Required {#user-content-Grammar_Annotation_Parameter__Required} +###### .Validators {#user-content-Grammar_Common_AnnotationParameter__Validators}
-`.Required` represents the parameter is required or not. +`.Validators` represents the [Validator](#user-content-Grammar_Common_Validator) for the annotation parameter.
-###### .Type {#user-content-Grammar_Annotation_Parameter__Type} +### Validator {#user-content-Grammar_Common_Validator} + +`Validator` represents the validator for the grammar rules. + +###### .Expression {#user-content-Grammar_Common_Validator__Expression}
-`.Type` represents the parameter type. The type is a string that can be one of the following types: +`.Expression` represents the validator expression. The expression is a template string that can access the data by the `.` operator. The expression must return a boolean value. + +The data is the current context object. For example, **package** object for the package validator. + +
+ +###### .Message {#user-content-Grammar_Common_Validator__Message} +
+ +`.Message` represents the error message when the validator is failed. + +
+ +###### .Name {#user-content-Grammar_Common_Validator__Name} +
+ +`.Name` represents the validator name. + +
+ +## Const {#user-content-Grammar_Const} + +`Const` represents the grammar rules for the const declaration. + +###### .Annotations {#user-content-Grammar_Const__Annotations} +
+ +`.Annotations` represents the [Annotation](#user-content-Grammar_Common_Annotation) grammar rules for the const declaration. + +
+ +###### .Off {#user-content-Grammar_Const__Off} +
+ +`.Off` represents the const declaration is off or not. If the const declaration is off, the const declaration is not allowed in the next files. + +Example: + +```json +{ + "Const": { + "Off": true + } +} +``` + +```next +package demo; + +// This will error +const x = 1; +// Error: const declaration is not allowed +``` + +
+ +###### .Types {#user-content-Grammar_Const__Types} +
+ +`.Types` represents a list of type names that are supported in the const declaration. If no types are defined, the const declaration supports all types. Otherwise, the const declaration only supports the specified types. + +Currently, each type name can be one of the following types: - **bool**: boolean type, the value can be `true` or `false` - **int**: integer type, the value can be a positive or negative integer, for example, `123` - **float**: float type, the value can be a positive or negative float, for example, `1.23` - **string**: string type, the value can be a string, for example, `"hello"` -- **type**: any type name, for example, `int`, `float`, `string`, etc. Custom type names are supported. + +Example: + +```json +{ + "Const": { + "Types": ["int", "float"] + } +} +``` + +```next +package demo; + +const x = 1; // Good +const y = 1.23; // Good + +// This will error +const z = "hello"; +// Error: string type is not allowed in the const declaration +```
-###### .Validators {#user-content-Grammar_Annotation_Parameter__Validators} +###### .Validators {#user-content-Grammar_Const__Validators}
-`.Validators` represents the [Validator](#user-content-Grammar_Validator) for the annotation parameter. +`.Validators` represents the [Validator](#user-content-Grammar_Common_Validator) for the const declaration. It's used to validate the const name. You can access the const name by `.Name`. + +Example: + +```json +{ + "Const": { + "Validators": [ + { + "Name": "ConstNameMustBeCapitalized", + "Expression": "{{eq .Name (.Name | capitalize)}}", + "Message": "const name must be capitalized" + } + ] + } +} +``` + +```next +package demo; + +const Hello = 1; // Good + +// This will error +const world = 1; +// Error: const name must be capitalized, expected: World +``` + +
+ +## Enum {#user-content-Grammar_Enum} + +`Enum` represents the grammar rules for the enum declaration. + +###### .Annotations {#user-content-Grammar_Enum__Annotations} +
+ +`.Annotations` represents the [Annotation](#user-content-Grammar_Common_Annotation) grammar rules for the enum declaration. + +
+ +###### .Member {#user-content-Grammar_Enum__Member} +
+ +`.Member` represents the [EnumMember](#user-content-Grammar_EnumMember) grammar rules for the enum declaration. + +
+ +###### .Off {#user-content-Grammar_Enum__Off} +
+ +`.Off` represents the enum declaration is off or not. If the enum declaration is off, the enum declaration is not allowed in the next files. + +Example: + +```json +{ + "Enum": { + "Off": true + } +} +``` + +```next +package demo; + +// This will error +enum Color { + Red; + Green; + Blue; +} +// Error: enum declaration is not allowed +``` + +
+ +###### .Validators {#user-content-Grammar_Enum__Validators} +
+ +`.Validators` represents the [Validator](#user-content-Grammar_Common_Validator) for the enum declaration. It's used to validate the enum name. You can access the enum name by `.Name`. + +Example: + +```json +{ + "Enum": { + "Validators": [ + { + "Name": "EnumNameMustBeCapitalized", + "Expression": "{{eq .Name (.Name | capitalize)}}", + "Message": "enum name must be capitalized" + } + ] + } +} +``` + +```next +package demo; + +// Good +enum Color { + Red; + Green; + Blue; +} + +// This will error +enum size { + Small; + Medium; + Large; +} +// Error: enum name must be capitalized, expected: Size +``` + +
+ +## EnumMember {#user-content-Grammar_EnumMember} + +`EnumMember` represents the grammar rules for the enum member declaration. + +###### .Annotations {#user-content-Grammar_EnumMember__Annotations} +
+ +`.Annotations` represents the [Annotation](#user-content-Grammar_Common_Annotation) grammar rules for the enum member declaration. + +
+ +###### .OffIota {#user-content-Grammar_EnumMember__OffIota} +
+ +`.OffIota` represents the enum member iota value is off or not. If the enum member iota value is off, the enum member iota value is not allowed in the next files. + +Example: + +```json +{ + "Enum": { + "Member": { + "OffIota": true + } + } +} +``` + +```next +package demo; + +enum Size { + // This will error + Small = iota; + // Error: enum member iota value is not allowed + Medium; + Large; +} +``` + +
+ +###### .OffValueExpr {#user-content-Grammar_EnumMember__OffValueExpr} +
+ +`.OffValueExpr` represents the enum member value expression is off or not. If the enum member value expression is off, the enum member value expression is not allowed in the next files. + +Example: + +```json +{ + "Enum": { + "Member": { + "OffValueExpr": true + } + } +} +``` + +```next +package demo; + +enum Size { + Small; + Medium; + // This will error + Large = Small + Medium; + // Error: enum member value expression is not allowed +} +``` + +
+ +###### .Types {#user-content-Grammar_EnumMember__Types} +
+ +`.Types` represents a list of type names that are supported in the enum declaration. + +If no types are defined, the enum declaration supports all types. Otherwise, the enum declaration only supports the specified types. + +Currently, each type name can be one of the following types: + +- **int**: integer type, the value can be a positive or negative integer, for example, `123` +- **float**: float type, the value can be a positive or negative float, for example, `1.23` +- **string**: string type, the value can be a string, for example, `"hello"` + +Example: + +```json +{ + "Enum": { + "Member": { + "Types": ["int"] + } + } +} +``` + +```next +package demo; + +// Good +enum Color { + Red = 1, + Green = 2, + Blue = 3 +} + +// This will error +enum Size { + Small = "small", + Medium = "medium", + Large = "large" +} +// Error: string type is not allowed in the enum declaration +``` + +
+ +###### .Validators {#user-content-Grammar_EnumMember__Validators} +
+ +`.Validators` represents the [Validator](#user-content-Grammar_Common_Validator) for the enum member declaration. + +It's used to validate the enum member name. You can access the enum member name by `.Name`. + +Example: + +```json +{ + "Enum": { + "Member": { + "Validators": [ + { + "Name": "EnumMemberNameMustBeCapitalized", + "Expression": "{{eq .Name (.Name | capitalize)}}", + "Message": "enum member name must be capitalized" + } + ] + } + } +} +``` + +```next +package demo; + +enum Size { + Small = 1, + Medium = 2, + // This will error + large = 3; + // Error: enum member name must be capitalized, expected: Large +} +``` + +
+ +###### .ValueRequired {#user-content-Grammar_EnumMember__ValueRequired} +
+ +`.ValueRequired` represents the enum member value is required or not. If the enum member value is required, the enum member value must be specified in the next files. + +Example: + +```json +{ + "Enum": { + "Member": { + "ValueRequired": true + } + } +} +``` + +```next +package demo; + +enum Size { + Small = 1, + Medium = 2; + // This will error + Large; + // Error: enum member value is required +} +``` + +
+ +###### .ZeroRequired {#user-content-Grammar_EnumMember__ZeroRequired} +
+ +`.ZeroRequired` represents the enum member zero value for integer types is required or not. + +If the enum member zero value is required, the enum member zero value must be specified in the next files. + +Example: + +```json +{ + "Enum": { + "Member": { + "ZeroRequired": true + } + } +} +``` + +```next +package demo; + +// This will error +enum Size { + Small = 1, + Medium = 2, + Large = 3; +} +// Error: enum member zero value is required, for example: +// enum Size { +// Small = 0, +// Medium = 1, +// Large = 2 +// } +``` + +
+ +## Import {#user-content-Grammar_Import} + +`Import` represents the grammar rules for the import declaration. + +###### .Off {#user-content-Grammar_Import__Off} +
+ +`.Off` represents the import declaration is off or not. If the import declaration is off, the import declaration is not allowed in the next files. + +Example: + +```json +{ + "Import": { + "Off": true + } +} +``` + +```next +package demo; + +// This will error +import "other.next"; +// Error: import declaration is not allowed +``` + +
+ +## Interface {#user-content-Grammar_Interface} + +`Interface` represents the grammar rules for the interface declaration. + +###### .Annotations {#user-content-Grammar_Interface__Annotations} +
+ +`.Annotations` represents the [Annotation](#user-content-Grammar_Common_Annotation) grammar rules for the interface declaration. + +
+ +###### .Method {#user-content-Grammar_Interface__Method} +
+ +`.Method` represents the [InterfaceMethod](#user-content-Grammar_InterfaceMethod) grammar rules for the interface declaration. + +
+ +###### .Off {#user-content-Grammar_Interface__Off} +
+ +`.Off` represents the interface declaration is off or not. If the interface declaration is off, the interface declaration is not allowed in the next files. + +Example: + +```json +{ + "Interface": { + "Off": true + } +} +``` + +```next +package demo; + +// This will error +interface User { + GetID() int; +} +// Error: interface declaration is not allowed +``` + +
+ +###### .Validators {#user-content-Grammar_Interface__Validators} +
+ +`.Validators` represents the [Validator](#user-content-Grammar_Common_Validator) for the interface declaration. It's used to validate the interface name. You can access the interface name by `.Name`. + +Example: + +```json +{ + "Interface": { + "Validators": [ + { + "Name": "InterfaceNameMustBeCapitalized", + "Expression": "{{eq .Name (.Name | capitalize)}}", + "Message": "interface name must be capitalized" + } + ] + } +} +``` + +```next +package demo; + +// Good +interface User { + GetID() int; +} + +// This will error +interface user { + GetName() string; +} +// Error: interface name must be capitalized, expected: User +``` + +
+ +## InterfaceMethod {#user-content-Grammar_InterfaceMethod} + +`InterfaceMethod` represents the grammar rules for the interface method declaration. + +Example: + +```json +{ + "Interface": { + "Method": { + "Annotations": [ + { + "Name": "http", + "Description": "Sets the method as an HTTP handler.", + "Parameters": [ + { + "Name": "method", + "Description": "Sets the HTTP method.", + "Type": "string", + "Required": true + "Validators": [ + { + "Name": "HTTPMethodMustBeValid", + "Expression": "{{includes (list `GET` `POST` `PUT` `DELETE` `PATCH` `HEAD` `OPTIONS` `TRACE` `CONNECT`) .}}", + "Message": "http method must be valid" + } + ] + } + ] + } + ], + "Validators": [ + { + "Name": "MethodNameMustBeCapitalized", + "Expression": "{{eq .Name (.Name | capitalize)}}", + "Message": "method name must be capitalized" + } + ] + } + } +} +``` + +###### .Annotations {#user-content-Grammar_InterfaceMethod__Annotations} +
+ +`.Annotations` represents the [Annotation](#user-content-Grammar_Common_Annotation) grammar rules for the interface method declaration. + +
+ +###### .Validators {#user-content-Grammar_InterfaceMethod__Validators} +
+ +`.Validators` represents the [Validator](#user-content-Grammar_Common_Validator) for the interface method declaration. + +
+ +### Parameter {#user-content-Grammar_InterfaceMethod_Parameter} + +`Parameter` represents the grammar rules for the interface method parameter declaration. + +###### .Annotations {#user-content-Grammar_InterfaceMethod_Parameter__Annotations} +
+ +`.Annotations` represents the [Annotation](#user-content-Grammar_Common_Annotation) grammar rules for the interface method parameter declaration. + +
+ +###### .Validators {#user-content-Grammar_InterfaceMethod_Parameter__Validators} +
+ +`.Validators` represents the [Validator](#user-content-Grammar_Common_Validator) for the interface method parameter declaration.
@@ -116,14 +1108,14 @@ You **CAN NOT** define the built-in annotations in the grammar. ###### .Annotations {#user-content-Grammar_Package__Annotations}
-`.Annotations` represents the [AnnotationGrammar](#user-content-Grammar_Annotation) rules for the package declaration. It extends the built-in annotations. +`.Annotations` represents the [Annotation](#user-content-Grammar_Common_Annotation) grammar rules for the package declaration.
###### .Validators {#user-content-Grammar_Package__Validators}
-`.Validators` represents the [Validator](#user-content-Grammar_Validator) for the package declaration. It's used to validate the package name. For example, You can limit the package name must be not start with a "_" character. The validator expression is a template string that can access package name by `.Name`. +`.Validators` represents the [Validator](#user-content-Grammar_Common_Validator) for the package declaration. It's used to validate the package name. For example, You can limit the package name must be not start with a "_" character. The validator expression is a template string that can access package name by `.Name`. Example: @@ -149,30 +1141,136 @@ package _test;
-## Validator {#user-content-Grammar_Validator} +## Struct {#user-content-Grammar_Struct} -`Validator` represents the validator for the grammar rules. +`Struct` represents the grammar rules for the struct declaration. -###### .Expression {#user-content-Grammar_Validator__Expression} +###### .Annotations {#user-content-Grammar_Struct__Annotations}
-`.Expression` represents the validator expression. The expression is a template string that can access the data by the `.` operator. The expression must return a boolean value. +`.Annotations` represents the [Annotation](#user-content-Grammar_Common_Annotation) grammar rules for the struct declaration. -The data is the current context object. For example, **package** object for the package validator. +
+ +###### .Field {#user-content-Grammar_Struct__Field} +
+ +`.Field` represents the [StructField](#user-content-Grammar_StructField) grammar rules for the struct declaration.
-###### .Message {#user-content-Grammar_Validator__Message} +###### .Off {#user-content-Grammar_Struct__Off}
-`.Message` represents the error message when the validator is failed. +`.Off` represents the struct declaration is off or not. If the struct declaration is off, the struct declaration is not allowed in the next files. + +Example: + +```json +{ + "Struct": { + "Off": true + } +} +``` + +```next +package demo; + +// This will error +struct User { + ID int; + Name string; +} +// Error: struct declaration is not allowed +```
-###### .Name {#user-content-Grammar_Validator__Name} +###### .Validators {#user-content-Grammar_Struct__Validators}
-`.Name` represents the validator name. +`.Validators` represents the [Validator](#user-content-Grammar_Common_Validator) for the struct declaration. It's used to validate the struct name. You can access the struct name by `.Name`. + +Example: + +```json +{ + "Struct": { + "Validators": [ + { + "Name": "StructNameMustBeCapitalized", + "Expression": "{{eq .Name (.Name | capitalize)}}", + "Message": "struct name must be capitalized" + } + ] + } +} +``` + +```next +package demo; + +// Good +struct User { + int id; + string name; +} + +// This will error +struct point { + int x; + int y; +} +// Error: struct name must be capitalized, expected: Point +``` + +
+ +## StructField {#user-content-Grammar_StructField} + +`StructField` represents the grammar rules for the struct field declaration. + +###### .Annotations {#user-content-Grammar_StructField__Annotations} +
+ +`.Annotations` represents the [Annotation](#user-content-Grammar_Common_Annotation) grammar rules for the struct field declaration. + +
+ +###### .Validators {#user-content-Grammar_StructField__Validators} +
+ +`.Validators` represents the [Validator](#user-content-Grammar_Common_Validator) for the struct field declaration. It's used to validate the struct field name. You can access the struct field name by `.Name`. + +Example: + +```json +{ + "Struct": { + "Field": { + "Validators": [ + { + "Name": "StructFieldNameMustNotBeCapitalized", + "Expression": "{{ne .Name (capitalize .Name)}}", + "Message": "struct field name must not be capitalized" + } + ] + } + } +} +``` + +```next +package demo; + +struct User { + int id; + // This will error + string Name; + // Error: struct field name must not be capitalized, expected: name +} +```
diff --git a/website/src/pages/index.tsx b/website/src/pages/index.tsx index d11a401..1c350be 100644 --- a/website/src/pages/index.tsx +++ b/website/src/pages/index.tsx @@ -66,8 +66,8 @@ export default function Home(): JSX.Element { const { siteConfig } = useDocusaurusContext(); return (