CxCodeUnit

Description

sealed class Tinman.Core.Cx.CxCodeUnit

Derived from

CxNode abstract

Represents a Code-X unit:

// Comment

using Usings.First;
using Usings.Second;
...

namespace Name
{
  class Declaration
  {
    ...
  }
}

The Tinman 3D SDK is developed and maintained in Code-X, which is a subset of the C# Language Specification Version 5.0 (see https://www.microsoft.com/en-us/download/details.aspx?id=7029), with additional syntactic and semantic rules and concepts (see https://manual.tinman3d.com/STABLE-PREVIEW/software-architecture.html#_code_concepts). The syntax of a Code-X source code unit is defined by the following Grammar:

#                := ws | lb ;
root             := code-unit ;

!code-unit       := comment? usings? namespace ;

!namespace       := 'namespace' (id .. '.') '{' decl '}' ;
usings           := using using* ;

!decl            := xmldoc? attribs? modifiers (class | delegate | enum | interface
                    | struct) ;
!using           := 'using' name ';' ;

!class           := 'class' name-id type-params? base-types? constraints? regions ;
!delegate        := 'delegate' var-decl type-params? params constraints? ';' ;
!enum            := 'enum' name-id '{' (item .. comma) '}' ;
!interface       := 'interface' name-id type-params? base-types? constraints? regions ;
!struct          := 'struct' name-id type-params? base-types? constraints? regions ;

base-types       := ':' (type .. comma) ;
item             := xmldoc? name-id '=' expr ;
regions          := '{' region* '}' ;

region           := '#region' ws ~lb+ lb member* '#endregion' ;

member           := xmldoc? attribs? modifiers (constant | constructor | field
                    | method | property) ;

!constant        := 'const' var-def ';' ;
!constructor     := name-id params (':' 'base' '(' (expr .. comma)? ')')? stat-block ;
!field           := var ';' ;
!method          := var-decl type-params? params constraints? (stat-block | ';') ;
modifiers        := 'public'? 'protected'? 'internal'? 'new'? 'abstract'? 'virtual'?
                    'override'? 'sealed'? 'static'? 'readonly'? 'volatile'?
                    'partial'? ;
!property        := var-decl '{' getter? setter? '}' ;
!xmldoc          := (ws* xmldoc-line)+ ;

constraints      := constraint constraint* ;
getter           := 'get' (';' | stat-block) ;
params           := '(' (param .. comma)? ')' ;
setter           := 'set' (';' | stat-block) ;
type-params      := '<' (type-param .. comma) '>' ;
xmldoc-line      := '///' (ws ~lb*)? lb ;

constraint       := 'where' name-id ':' (constraint-item .. comma)? ;
param            := attribs? ('ref' | 'out' | 'this')? var ;
type-param       := ('in' | 'out')? name-id ;

attribs          := '[' (attrib .. comma) ']' ;
constraint-item  := 'class' | 'struct' | 'new()' | type-generic ;
var              := type name-id ('=' expr)? ;

attrib           := name-id ('(' (expr .. comma) ')')? ;

!arg             := ('out' | 'ref')? expr ;
expr             := expr-assign ;
!expr-add        := expr-mul !> (expr-add-op expr-mul)+ ;
!expr-assign     := expr-cond !> (expr-assign-op expr-cond)+ ;
!expr-brace      := '(' expr ')' ;
!expr-cond       := expr-cond-or !> '?' expr-cond ':' expr-cond ;
!expr-cond-and   := expr-logic-or !> ('&&' expr-logic-or)+ ;
!expr-cond-or    := expr-cond-and !> ('||' expr-cond-and)+ ;
!expr-equal      := expr-relate !> expr-equal-op expr-relate ;
!expr-generic    := expr-name !> '<' (type .. comma) '>' ;
!expr-logic-and  := expr-equal !> ('&' expr-equal)+ ;
!expr-logic-or   := expr-logic-xor !> ('|' expr-logic-xor)+ ;
!expr-logic-xor  := expr-logic-and !> ('^' expr-logic-and)+ ;
!expr-mul        := expr-unary !> (expr-mul-op expr-unary)+ ;
!expr-new        := 'new' type (expr-new-object | expr-new-array1 | expr-new-array2) ;
!expr-new-array1 := '{' (expr .. comma)? '}' ;
!expr-new-array2 := '[' expr ']' '[]'* ;
!expr-new-object := '(' (expr .. comma)? ')' ;
!expr-primary    := expr-brace | expr-new | expr-literal | expr-generic ;
!expr-relate     := expr-shift !> expr-relate-op expr-shift ;
!expr-shift      := expr-add !> (expr-shift-op expr-add)+ ;
!expr-suffix     := expr-primary !> expr-suffix-op+ ;
expr-suffix-op   := '(' (arg .. comma)? ')' | '.' expr-generic | '[' expr ']' | '++'
                    | '--' ;
!expr-unary      := expr-unary-op+ <! expr-suffix ;
expr-unary-op    := '++' | '+' | '--' | '-' \ literal-number | '!' | '~'
                    | '(' type ')' <expr> ;
for-cond         := expr ;
for-next         := expr (comma expr)* ;
stat             := stat-block | stat-debug | stat-do | stat-for | stat-if
                    | stat-native | stat-return | stat-simple | stat-switch
                    | stat-throw | stat-try | stat-while | stat-variable | stat-expr
                    | stat-comment ;
!stat-block      := '{' stat* '}' ;
!stat-debug      := '#if' 'DEBUG' stat* '#endif' ;
!stat-do         := 'do' stat-block 'while' '(' expr ')' ';' ;
stat-expr        := expr ';' ;
!stat-for        := 'for' '(' var-def? ';' for-cond ';' for-next? ')' stat ;
!stat-if         := 'if' '(' expr ')' stat ('else' stat)? ;
!stat-return     := 'return' expr? ';' ;
!stat-switch     := 'switch' '(' expr ')' '{' switch-case* switch-default? '}' ;
!stat-throw      := 'throw' expr? ';' ;
!stat-try        := 'try' stat-block try-catch? try-finally? ;
!stat-variable   := var-decl ';' ;
!stat-while      := 'while' '(' expr ')' stat ;
switch-case      := 'case' expr ':' stat* ;
switch-default   := 'default:' stat* ;
try-catch        := 'catch' '(' type name-id? ')' stat-block ;
try-finally      := 'finally' stat-block ;
!type            := type-no-array !> '[]'+ ;
type-generic     := type-name !> '<' (type .. comma) '>' ;
type-no-array    := type-simple | type-generic ;
var-decl         := type name-id ;
var-def          := type name-id '=' expr ;

!expr-literal    := literal ;

literal          := literal-simple | literal-string | literal-char | literal-hex
                    | literal-number ;
type-name        := name ;

!expr-name       := id ;
!literal-char    := '\'' (escape | ]\\'[) '\'' ;
!literal-string  := '"' (escape | ]"\\[ \ '\\"')* '"' | '@"' ('""' | ]"[)* '"' ;
name             := 'global::'? (id .. '.') ;
name-id          := id ;
!stat-comment    := comment ;
!stat-native     := '#region' ws 'Native' ws '{' guid '}' lb ~native-end* native-end
                    lb ;

comment          := comment-line comment-line* ;
escape           := '\\"' | '\\0' | '\\\'' | '\\\\' | '\\b' | '\\f' | '\\n' | '\\r'
                    | '\\t' | '\\u' hex-digit[4] ;
!guid            := hex-digit[8] ('-' hex-digit[4])[3] '-' hex-digit[12] ;
!id              := letter id-char* ;
!literal-hex     := @'0x' hex-digit+ @'L'? ;
!literal-simple  := ('null' | 'this' | 'base' | 'true' | 'false') >id-char< ;
!type-simple     := ('bool' | 'sbyte' | 'char' | 'short' | 'int' | 'long' | 'float'
                    | 'double' | 'string' | 'object' | 'void') >id-char< ;

!comment-line    := '//' \ '///' ws? ~lb* lb ;
hex-digit        := dec-digit | 'a'..'f' | 'A'..'F' ;
id-char          := letter | dec-digit ;
!literal-number  := '-'? dec-digit+ ('.' dec-digit+)? (@'E' ('-' | '+')? dec-digit+)?
                    [FflL]? ;
native-end       := lb ws* '#endregion' ;

comma            := ',' ;
dec-digit        := '0'..'9' ;
expr-add-op      := '+' | '-' ;
expr-assign-op   := '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>='
                    | '&=' | '^=' | '|=' ;
expr-equal-op    := '==' | '!=' ;
expr-mul-op      := '*' | '/' \ '//' | '%' ;
expr-relate-op   := '<=' | '<' | '>=' | '>' | 'is' | 'as' ;
expr-shift-op    := '<<' | '>>' ;
lb               := '\r' '\n'? | '\n' ;
letter           := 'a'..'z' | 'A'..'Z' | '_' ;
!stat-simple     := ('break' | 'continue') ';' ;
ws               := '\t' | ' ' ;

The CxNode class represents a single node of the program structure information (PSI) model of a Code-X unit. To obtain a CxNode from source code, use one of the following parse methods:

Alternatively, a PSI model may be created by instantiating CxNode classes directly. To obtain parseable source code from CxNode objects, use ICodeOutput.WriteSourceCode or - as a shortcut - object.ToString.

Public / Constructors

CxCodeUnit


public constructor CxCodeUnit → (4)

comment in : Text

See Comment.

name in : CxName

See Name.

declaration in : CxDeclaration

[not-null]
See Declaration.

usings opt : IBagConst<CxName> = null

The using directive list or null for an empty list. See Usings.

Creates a new instance of CxCodeUnit.

FromFile


public static method FromFile → (1)

file in : Path

[not-null]
Path to the source code file.

returns → CxCodeUnit

The parsed Code-X unit.

Parses the given Code-X unit.

ValidatingException

If the syntax of file in is invalid.

IOException

If an I/O error has occurred.

FromSource


public static method FromSource → (1)

source in : string

[not-null]
The source code.

returns → CxCodeUnit

The parsed Code-X unit.

Parses the given Code-X unit.

ValidatingException

If the syntax of source in is invalid.

Public / Attributes

Comment


public attribute Comment → (get)

value : Text

The header comment or null if there is none.

Returns the header comment of this code unit.

Declaration


public attribute Declaration → (get)

value : CxDeclaration

[not-null]
The type declaration.

Returns the type declaration of this code unit.

Name


public attribute Name → (get)

value : CxName

The namespace.

Returns the namespace of this code unit.

Usings


public attribute Usings → (get)

value : IVectorConst<CxName>

[not-null]
The using directive list.

Returns the using directives of this code unit.