Пример #1
0
 private static IList <TypeStatement> GetGenericTypes(
     Node node,
     ClassMetadata classMetadata,
     AbstractSyntaxTree ast,
     TypeOverrideDetails typeOverrideDetails
     )
 {
     if (node.Kind == SyntaxKind.ClassDeclaration &&
         node.TypeParameters != null
         )
     {
         return(node.TypeParameters.Select(
                    typeParam => GenericTypeIdentifier.Identify(
                        typeParam,
                        classMetadata,
                        ast,
                        typeOverrideDetails
                        )
                    ).ToList());
     }
     else if (node.Kind == SyntaxKind.InterfaceDeclaration &&
              node.TypeParameters != null
              )
     {
         return(node.TypeParameters.Select(
                    typeParam => GenericTypeIdentifier.Identify(
                        typeParam,
                        classMetadata,
                        ast,
                        typeOverrideDetails
                        )
                    ).ToList());
     }
     return(new List <TypeStatement>());
 }
Пример #2
0
        private static TypeStatement NormalizeLiteralTypeStatement(
            TypeStatement type,
            ClassMetadata classMetadata,
            AbstractSyntaxTree ast,
            TypeOverrideDetails typeOverrideDetails
            )
        {
            if (type.IsTypeQuery)
            {
                var(found, className, toGenerateNode) = GetNode(
                    type.TypeQuery.Class,
                    ast
                    );

                if (!found)
                {
                    return(type);
                }

                var typeNode = toGenerateNode.Children.FirstOrDefault(
                    a => a.IdentifierStr == type.TypeQuery.Type
                    );
                if (typeNode is not null)
                {
                    var typedType = GenericTypeIdentifier.Identify(
                        typeNode.Last,
                        classMetadata,
                        ast,
                        typeOverrideDetails
                        );
                    return(typedType);
                }
            }

            if (type.IsLiteral)
            {
                type.Name = GenerationIdentifiedTypes.CachedEntity;
            }
            var literalGenericTypes = type.GenericTypes.Where(
                a => a.IsLiteral
                );

            foreach (var genericType in literalGenericTypes)
            {
                genericType.Name = GenerationIdentifiedTypes.CachedEntity;
            }
            return(type);
        }
Пример #3
0
        private JSCachedType GetCachedType(TypeReference type)
        {
            if (!IsCacheable(type))
            {
                return(null);
            }

            bool mapArraysToSystemArray = false;

            while (type is ByReferenceType)
            {
                type = ((ByReferenceType)type).ElementType;
            }

            var resolved = TypeUtil.GetTypeDefinition(type, mapArraysToSystemArray);

            if (resolved == null)
            {
                return(null);
            }

            var at = type as ArrayType;

            TypeDefinition[] arguments;
            var git = type as GenericInstanceType;

            if (git != null)
            {
                arguments = (from a in git.GenericArguments select TypeUtil.GetTypeDefinition(a, mapArraysToSystemArray)).ToArray();
            }
            else
            {
                arguments = new TypeDefinition[0];
            }

            var identifier = new GenericTypeIdentifier(resolved, arguments, (at != null) ? at.Rank : 0);

            CachedTypeRecord record;

            if (!CachedTypes.TryGetValue(identifier, out record))
            {
                CachedTypes.Add(identifier, record = new CachedTypeRecord(type, NextID++));
            }

            return(new JSCachedType(type, record.Index));
        }
 private static IList <TypeStatement> GetGenericTypes(
     Node node,
     ClassMetadata classMetadata,
     TypeScriptAST ast,
     TypeOverrideDetails typeOverrideDetails
     )
 {
     if (node is ClassDeclaration classDeclaration &&
         classDeclaration.TypeParameters != null
         )
     {
         return(classDeclaration.TypeParameters.Select(
                    typeParam => GenericTypeIdentifier.Identify(
                        typeParam,
                        classMetadata,
                        ast,
                        typeOverrideDetails
                        )
                    ).ToList());
     }
Пример #5
0
 /// <summary>
 /// Retourne le nom complet du type potentiel encapsulé par ce jeton.
 /// </summary>
 /// <returns></returns>
 public string GetTypeFullName()
 {
     if (TkType == ExpressionTokenType.GenericType)
     {
         StringBuilder b = new StringBuilder();
         foreach (var arg in GenericTypeArgs.ListTokens)
         {
             b.Append(arg.GetTypeFullName());
             if (arg != GenericTypeArgs.ListTokens.Last())
             {
                 b.Append(",");
             }
         }
         return(GenericTypeIdentifier.GetTypeFullName() + "<" + b.ToString() + ">");
     }
     else if (TkType == ExpressionTokenType.List)
     {
         StringBuilder b = new StringBuilder();
         foreach (var arg in ListTokens)
         {
             b.Append(arg.GetTypeFullName());
             if (arg != ListTokens.Last())
             {
                 b.Append(",");
             }
         }
         return(b.ToString());
     }
     else if (TkType == ExpressionTokenType.Name)
     {
         return(Content);
     }
     else if (TkType == ExpressionTokenType.ArrayType)
     {
         return(ArrayTypeIdentifier.GetTypeFullName() + "[]");
     }
     else
     {
         throw new InvalidOperationException();
     }
 }
Пример #6
0
        private JSCachedType GetCachedType(TypeReference type)
        {
            if (!IsCacheable(type))
            {
                return(null);
            }

            GenericTypeIdentifier?identifier = GenericTypeIdentifier.Create(type);

            if (identifier == null)
            {
                return(null);
            }

            CachedTypeRecord record;

            if (!CachedTypes.TryGetValue(identifier.Value, out record))
            {
                CachedTypes.Add(identifier.Value, record = new CachedTypeRecord(type, NextID++));
            }

            return(new JSCachedType(type, record.Index));
        }
Пример #7
0
        private JSCachedType GetCachedType(TypeReference type)
        {
            if (!IsCacheable(type))
            {
                return(null);
            }

            var resolved = TypeUtil.GetTypeDefinition(type);

            if (resolved == null)
            {
                return(null);
            }

            TypeDefinition[] arguments;
            var git = type as GenericInstanceType;

            if (git != null)
            {
                arguments = (from a in git.GenericArguments select TypeUtil.GetTypeDefinition(a)).ToArray();
            }
            else
            {
                arguments = new TypeDefinition[0];
            }

            var          identifier = new GenericTypeIdentifier(resolved, arguments);
            JSCachedType result;

            if (!CachedTypes.TryGetValue(identifier, out result))
            {
                CachedTypes.Add(identifier, result = MakeCachedType(type));
            }

            return(result);
        }
Пример #8
0
        public static IList <AccessorStatement> FlattenAccessorStatements(
            this IEnumerable <Node> nodes,
            AbstractSyntaxTree ast,
            ClassMetadata classMetadata,
            IDictionary <string, string> typeOverrideMap
            )
        {
            var flattenedAccessorList = nodes.Where(a => IsGetterRule.Check(a)).Select(
                accessor =>
            {
                var name                = accessor.IdentifierStr;
                var isStatic            = IsStaticRule.Check(accessor);
                var typeOverrideDetails = new TypeOverrideDetails
                {
                    IsStatic        = isStatic,
                    TypeOverrideMap = typeOverrideMap,
                };
                var type = GenericTypeIdentifier.Identify(
                    accessor.Last,
                    classMetadata,
                    ast,
                    typeOverrideDetails
                    );
                if (TypeOverrideIdentifier.Identify(
                        TypeOverrideDeclarationIdentifier.Identify(
                            classMetadata,
                            isStatic,
                            name
                            ),
                        typeOverrideMap,
                        type,
                        out var overrideType
                        ))
                {
                    type = overrideType;
                }
                return(new AccessorStatement
                {
                    Name = name,
                    Type = NormalizeLiteralTypeStatement(
                        type,
                        classMetadata,
                        ast,
                        typeOverrideDetails
                        ),
                    IsStatic = isStatic,
                    IsInterfaceResponse = InterfaceResponseTypeIdentifier.Identify(
                        type,
                        ast
                        ),
                    HasSetter = IsSetterRule.Check(accessor),
                    //IsArrayResponse = IsArrayResposneTypeRule.Check(accessor),
                    UsedClassNames = UsedClassNamesIdentifier.Identify(type),
                });
            }
                ).ToList();

            // Loop through Setters and on the setter flat as HasSetter
            foreach (var node in nodes.Where(a => IsSetterRule.Check(a)))
            {
                var getNode = flattenedAccessorList.FirstOrDefault(
                    a => a.Name == node.IdentifierStr
                    );
                if (getNode != null)
                {
                    getNode.HasSetter = true;
                }
            }
            return(flattenedAccessorList);
        }
Пример #9
0
        public static ClassStatement Generate(
            string projectAssembly,
            string classIdentifier,
            AbstractSyntaxTree ast,
            IDictionary <string, string> typeOverrideMap
            )
        {
            var(found, className, toGenerateNode) = GetNode(
                classIdentifier,
                ast
                );
            if (!found)
            {
                return(null);
            }

            var namespaceIdentifier = string.Join(".", GetNamespace(toGenerateNode));
            var classMetadata       = new ClassMetadata
            {
                Namespace = namespaceIdentifier,
                Name      = className,
            };


            var typeOverrideDetails = new TypeOverrideDetails
            {
                IsStatic        = false,
                TypeOverrideMap = typeOverrideMap,
            };
            // Get ExtendedClassNames
            var extendedClassType = ExtendedClassTypesIdentifier.Identify(
                toGenerateNode,
                ast,
                classMetadata,
                typeOverrideDetails
                );
            // Get ImplementedInterfaces
            var implementedInterfaces = ImplementedInterfacesIdentifier.Identify(
                toGenerateNode,
                ast,
                classMetadata,
                typeOverrideDetails
                );

            // Public Properties
            var publicProperties = toGenerateNode
                                   .Children.Where(
                child => IsNotPrivate(child) && IsPropertyType(child, classMetadata)
                );

            // Public Methods/Functions
            var publicMethods = toGenerateNode
                                .Children.Where(
                child => IsNotPrivate(child) && IsMethodType(child, classMetadata)
                );

            // Get/Set Accessors
            var accessorMethods = toGenerateNode
                                  .Children.Where(
                child => IsNotPrivate(child) && IsAccessorType(child)
                );

            // Is Observer Method/Function
            var observalbleMethods = publicProperties.Where(
                a => IsObservablePropertyRule.Check(a)
                ).ToList();

            var classStatement = new ClassStatement
            {
                ProjectAssembly = projectAssembly,
                Namespace       = namespaceIdentifier,
                Name            = DotNetClassNormalizer.Normalize(
                    className
                    ),
                IsInterface = IsInterfaceRule.Check(
                    toGenerateNode
                    ),
                GenericTypes = GetGenericTypes(
                    toGenerateNode,
                    classMetadata,
                    ast,
                    new TypeOverrideDetails
                {
                    IsStatic        = false,
                    TypeOverrideMap = typeOverrideMap,
                }
                    ),
                ExtendedType          = extendedClassType,
                ImplementedInterfaces = implementedInterfaces,
                ConstructorStatement  = new ConstructorStatement
                {
                    Arguments = ConstructorArgumentIdentifier.Identify(
                        toGenerateNode,
                        classMetadata,
                        ast,
                        new TypeOverrideDetails
                    {
                        IsStatic        = false,
                        TypeOverrideMap = typeOverrideMap,
                    }
                        ),
                },
                PublicPropertyStatements = publicProperties.ToList().Select(
                    a =>
                {
                    var name                = a.IdentifierStr;
                    var isStatic            = IsStaticRule.Check(a);
                    var typeOverrideDetails = new TypeOverrideDetails
                    {
                        IsStatic        = isStatic,
                        TypeOverrideMap = typeOverrideMap,
                    };
                    var type = GenericTypeIdentifier.Identify(
                        a.Last,
                        classMetadata,
                        ast,
                        typeOverrideDetails
                        );
                    if (TypeOverrideIdentifier.Identify(
                            TypeOverrideDeclarationIdentifier.Identify(
                                classMetadata,
                                typeOverrideDetails.IsStatic,
                                name
                                ),
                            typeOverrideDetails.TypeOverrideMap,
                            type,
                            out var overrideType
                            ))
                    {
                        type = overrideType;
                    }
                    return(new PublicPropertyStatement
                    {
                        Name = name,
                        Type = NormalizeLiteralTypeStatement(
                            type,
                            classMetadata,
                            ast,
                            typeOverrideDetails
                            ),
                        IsStatic = isStatic,
                        IsInterfaceResponse = InterfaceResponseTypeIdentifier.Identify(
                            type,
                            ast
                            ),
                        //IsArrayResponse = IsArrayResposneTypeRule.Check(a),
                        IsReadonly = IsReadonlyRule.Check(a),
                        UsedClassNames = UsedClassNamesIdentifier.Identify(type),
                    });
                }
                    ).ToList(),
                PublicMethodStatements = publicMethods.ToList().Select(
                    a =>
                {
                    var name                = a.IdentifierStr;
                    var isStatic            = IsStaticRule.Check(a);
                    var typeOverrideDetails = new TypeOverrideDetails
                    {
                        IsStatic        = isStatic,
                        TypeOverrideMap = typeOverrideMap,
                    };
                    var type = GenericTypeIdentifier.Identify(
                        a.Last,
                        classMetadata,
                        ast,
                        typeOverrideDetails
                        );
                    if (TypeOverrideIdentifier.Identify(
                            TypeOverrideDeclarationIdentifier.Identify(
                                classMetadata,
                                typeOverrideDetails.IsStatic,
                                name
                                ),
                            typeOverrideDetails.TypeOverrideMap,
                            type,
                            out var overrideType
                            ))
                    {
                        type = overrideType;
                    }
                    return(new PublicMethodStatement
                    {
                        Name = name,
                        Type = NormalizeLiteralTypeStatement(
                            type,
                            classMetadata,
                            ast,
                            typeOverrideDetails
                            ),
                        GenericTypes = DeclarationGenericTypesIdentifier.Identify(
                            a
                            ),
                        Arguments = ArgumentIdentifier.Identify(
                            a,
                            classMetadata,
                            ast,
                            typeOverrideDetails
                            ),
                        IsStatic = isStatic,
                        IsInterfaceResponse = InterfaceResponseTypeIdentifier.Identify(
                            type,
                            ast
                            ),
                        UsedClassNames = UsedClassNamesIdentifier.Identify(type),
                    });
                }
                    ).Distinct().ToList(),
                AccessorStatements = accessorMethods.FlattenAccessorStatements(
                    ast,
                    classMetadata,
                    typeOverrideMap
                    ),
            };

            classStatement.ConstructorStatement.NeedsInvokableReference = InvokableReferenceIdentifier.Identify(
                classStatement
                );

            return(classStatement);
        }
Пример #10
0
        private JSCachedType GetCachedType(TypeReference type)
        {
            if (!IsCacheable(type))
                return null;

            bool mapArraysToSystemArray = false;

            while (type is ByReferenceType)
                type = ((ByReferenceType)type).ElementType;

            var resolved = TypeUtil.GetTypeDefinition(type, mapArraysToSystemArray);
            if (resolved == null)
                return null;

            var at = type as ArrayType;

            TypeDefinition[] arguments;
            var git = type as GenericInstanceType;

            if (git != null) {
                arguments = (from a in git.GenericArguments select TypeUtil.GetTypeDefinition(a, mapArraysToSystemArray)).ToArray();
            } else {
                arguments = new TypeDefinition[0];
            }

            var identifier = new GenericTypeIdentifier(resolved, arguments, (at != null) ? at.Rank : 0);

            CachedTypeRecord record;
            if (!CachedTypes.TryGetValue(identifier, out record))
                CachedTypes.Add(identifier, record = new CachedTypeRecord(type, NextID++));

            return new JSCachedType(type, record.Index);
        }
Пример #11
0
        private JSCachedType GetCachedType(TypeReference type)
        {
            if (!IsCacheable(type))
                return null;

            var resolved = TypeUtil.GetTypeDefinition(type);
            if (resolved == null)
                return null;

            TypeDefinition[] arguments;
            var git = type as GenericInstanceType;

            if (git != null) {
                arguments = (from a in git.GenericArguments select TypeUtil.GetTypeDefinition(a)).ToArray();
            } else {
                arguments = new TypeDefinition[0];
            }

            var identifier = new GenericTypeIdentifier(resolved, arguments);
            JSCachedType result;
            if (!CachedTypes.TryGetValue(identifier, out result))
                CachedTypes.Add(identifier, result = MakeCachedType(type));

            return result;
        }
Пример #12
0
        /// <summary>
        /// Traduit le jeton en code lisible.
        /// </summary>
        /// <returns></returns>
        public string ToPython()
        {
            Func <string, string> getChildrenCode = delegate(string separator)
            {
                StringBuilder b = new StringBuilder();
                for (int i = 0; i < SubTokens.Count; i++)
                {
                    b.Append(SubTokens[i].ToPython());
                    if (i != SubTokens.Count - 1)
                    {
                        b.Append(separator);
                    }
                }
                return(b.ToString());
            };

            Func <string, string> getChildrenCode2 = delegate(string ending)
            {
                StringBuilder b = new StringBuilder();
                for (int i = 0; i < SubTokens.Count; i++)
                {
                    b.Append(SubTokens[i].ToPython());
                    b.Append(ending);
                }
                return(b.ToString());
            };

            switch (TkType)
            {
            case ExpressionTokenType.BracketList:
                return("[" + getChildrenCode(",") + "]");

            case ExpressionTokenType.FunctionCall:
                return(FunctionCallIdentifier.ToPython() + "(" + FunctionCallArgs.ToPython() + ")");

            case ExpressionTokenType.GenericType:
                return(GenericTypeIdentifier.ToPython());

            case ExpressionTokenType.ArrayType:
                return(ArrayTypeIdentifier.ToPython() + "[" + ArrayTypeArgs.ToPython() + "]");

            case ExpressionTokenType.List:
                return(getChildrenCode(" "));

            case ExpressionTokenType.ArgList:
                return(getChildrenCode(","));

            case ExpressionTokenType.GenericParametersList:
                return("");

            case ExpressionTokenType.Name:
                return(this.Content);

            case ExpressionTokenType.CodeBlock:
                return("{ " + getChildrenCode(",") + " }");

            case ExpressionTokenType.NamedCodeBlock:
                return(SubTokens[0].ToPython() + ":\n" + Tools.StringUtils.Indent(SubTokens[1].ToPython(), 1) + "\n");

            case ExpressionTokenType.FunctionDeclaration:
                return(SubTokens[0].ToPython() + ":\n" + Tools.StringUtils.Indent(SubTokens[1].ToPython(), 1) + "\n");

            case ExpressionTokenType.NamedGenericCodeBlock:
                return(NamedGenericCodeBlockIdentifier.ToPython() +
                       ":\n" + Tools.StringUtils.Indent(NamedGenericCodeBlockInstructions.ToPython(), 1) + "\n");

            case ExpressionTokenType.EndOfInstruction:
                return(this.Content + "\n");

            case ExpressionTokenType.InstructionList:
                if (this.ListTokens.Count == 0)
                {
                    return("pass;");
                }
                return(getChildrenCode2("\n"));

            case ExpressionTokenType.ExpressionGroup:
                if (Operator.IsBinaryOperator)
                {
                    if (Operator.Content == "=" || Operator.Content == ".")
                    {
                        return(Operands1.ToPython() + Operator.ToPython() + Operands2.ToPython());
                    }
                    else
                    {
                        return("(" + Operands1.ToPython() + Operator.ToPython() + Operands2.ToPython() + ")");
                    }
                }
                else
                {
                    return(Operator.ToPython() + Operands1.ToPython());
                }

            case ExpressionTokenType.NumberLiteral:
                return(this.Content);

            case ExpressionTokenType.Operator:
                return(this.Content);

            case ExpressionTokenType.Separator:
                return(this.Content);

            case ExpressionTokenType.StringLiteral:
                return("\"" + this.Content + "\"");

            case ExpressionTokenType.BoolLiteral:
                return(this.Content);

            case ExpressionTokenType.Modifier:
                return(this.Content);

            default:
                return("??");
            }
        }
Пример #13
0
        /// <summary>
        /// Traduit le jeton en code lisible.
        /// </summary>
        /// <returns></returns>
        public string ToXML()
        {
            Func <string, string> i = delegate(string str)
            {
                return(Tools.StringUtils.Indent(str, 1));
            };
            Func <string, string, string> inlineencapsulate = delegate(string str, string delim)
            {
                return("<" + delim + ">" + str + "</" + delim + ">\n");
            };
            Func <string, string, string> encapsulate = delegate(string str, string delim)
            {
                return("<" + delim + ">\n" + i(str) + "\n</" + delim + ">\n");
            };
            Func <string, string> getChildrenCode = delegate(string name)
            {
                StringBuilder b = new StringBuilder();
                b.Append("<" + name + ">\n");
                for (int j = 0; j < SubTokens.Count; j++)
                {
                    b.AppendLine(i(SubTokens[j].ToXML()));
                }
                b.Append("</" + name + ">\n");
                return(b.ToString());
            };

            switch (TkType)
            {
            case ExpressionTokenType.BracketList:
                return(getChildrenCode("BracketList"));

            case ExpressionTokenType.FunctionCall:
                return("<FunctionCall>\n" +
                       i("<Identifier>\n" + i(FunctionCallIdentifier.ToXML()) + "</Identifier>\n") +
                       i(FunctionCallArgs.ToXML()) +
                       "</FunctionCall>");

            case ExpressionTokenType.GenericType:
                return("<GenericType>\n" +
                       i("<Identifier>\n" + i(GenericTypeIdentifier.ToXML()) + "</Identifier>\n") +
                       i(GenericTypeArgs.ToXML()) +
                       "</GenericType>");

            case ExpressionTokenType.ArrayType:
                return("<ArrayType>\n" +
                       i("<Identifier>\n" + i(ArrayTypeIdentifier.ToXML()) + "</Identifier>\n") +
                       i(ArrayTypeArgs.ToXML()) +
                       "</ArrayType>");

            case ExpressionTokenType.NamedCodeBlock:
                return("<NamedCodeBlock>\n" +
                       i("<Identifier>\n" + i(SubTokens[0].ToXML()) + "</Identifier>\n") +
                       i(SubTokens[1].ToXML()) +
                       "</NamedCodeBlock>");

            case ExpressionTokenType.NamedGenericCodeBlock:
                return("<NamedGenericCodeBlock>\n" +
                       i("<Identifier>\n" + i(NamedGenericCodeBlockIdentifier.ToXML()) + "</Identifier>\n") +
                       i(NamedGenericCodeBlockInstructions.ToXML()) +
                       "</NamedGenericCodeBlock>");

            case ExpressionTokenType.FunctionDeclaration:
                return("<FunctionDeclaration>\n" +
                       i("<FuncName>\n" + i(SubTokens[0].ToXML()) + "</FuncName>\n") +
                       i(SubTokens[1].ToXML()) +
                       "</FunctionDeclaration>");

            case ExpressionTokenType.List:
                return(getChildrenCode("List"));

            case ExpressionTokenType.ArgList:
                return(getChildrenCode("ArgList"));

            case ExpressionTokenType.GenericParametersList:
                return(getChildrenCode("GenList"));

            case ExpressionTokenType.Name:
                return(inlineencapsulate(this.Content, "Name"));

            case ExpressionTokenType.CodeBlock:
                return(getChildrenCode("CodeBlock"));

            case ExpressionTokenType.EndOfInstruction:
                return(inlineencapsulate(this.Content, "EndOfInstruction"));

            case ExpressionTokenType.InstructionList:
                return(getChildrenCode("InstructionList"));

            case ExpressionTokenType.ExpressionGroup:
                if (Operator.IsBinaryOperator)
                {
                    return(encapsulate(
                               encapsulate(Operands1.ToXML(), "Operand1") +
                               Operator.ToXML() +
                               encapsulate(Operands2.ToXML(), "Operand2"),
                               "ExpressionGroup"));
                }

                else
                {
                    return(encapsulate(
                               encapsulate(Operands1.ToXML(), "Operand1") +
                               Operator.ToXML(),
                               "ExpressionGroup"));
                }

            case ExpressionTokenType.NumberLiteral:
                return(inlineencapsulate(this.Content, "NumberLiteral"));

            case ExpressionTokenType.Operator:
                return(inlineencapsulate(this.Content, "Operator"));

            case ExpressionTokenType.Separator:
                return(inlineencapsulate(this.Content, "Separator"));

            case ExpressionTokenType.StringLiteral:
                return(inlineencapsulate(this.Content, "StringLiteral"));

            case ExpressionTokenType.BoolLiteral:
                return(inlineencapsulate(this.Content, "BoolLiteral"));

            case ExpressionTokenType.Modifier:
                return(inlineencapsulate(this.Content, "Modifier"));

            default:
                return("??");
            }
        }
Пример #14
0
        /// <summary>
        /// Traduit le jeton en "code" lisible.
        /// </summary>
        /// <returns></returns>
        public string ToDebugCode()
        {
            Func <string, string> getChildrenCode = delegate(string separator)
            {
                StringBuilder b = new StringBuilder();
                for (int i = 0; i < SubTokens.Count; i++)
                {
                    b.Append(SubTokens[i].ToDebugCode());
                    if (i != SubTokens.Count - 1)
                    {
                        b.Append(separator);
                    }
                }
                return(b.ToString());
            };

            switch (TkType)
            {
            case ExpressionTokenType.BracketList:
                return("l[" + getChildrenCode(",") + "]");

            case ExpressionTokenType.FunctionCall:
                return(FunctionCallIdentifier.ToDebugCode() + ".call(" + FunctionCallArgs.ToDebugCode() + ")");

            case ExpressionTokenType.GenericType:
                return(GenericTypeIdentifier.ToDebugCode() + ".gen<" + GenericTypeArgs.ToDebugCode() + ">");

            case ExpressionTokenType.ArrayType:
                return(ArrayTypeIdentifier.ToDebugCode() + ".arr[" + ArrayTypeArgs.ToDebugCode() + "]");

            case ExpressionTokenType.List:
                return("l:(" + getChildrenCode(" _ ") + ")");

            case ExpressionTokenType.ArgList:
                return("args:(" + getChildrenCode(",") + ")");

            case ExpressionTokenType.GenericParametersList:
                return("l<" + getChildrenCode(",") + ">");

            case ExpressionTokenType.Name:
                return(this.Content);

            case ExpressionTokenType.CodeBlock:
                return("{ " + getChildrenCode(",") + "}");

            case ExpressionTokenType.FunctionDeclaration:
                return("decl:" + SubTokens[0].ToDebugCode() + "{\n" + Tools.StringUtils.Indent(SubTokens[1].ToDebugCode(), 1) + "\n}");

            case ExpressionTokenType.EndOfInstruction:
                return("/" + this.Content);

            case ExpressionTokenType.InstructionList:
                return("\ninstruction_list:(\n" + getChildrenCode("?;\n") + ")\n");

            case ExpressionTokenType.ExpressionGroup:
                if (Operator.IsBinaryOperator)
                {
                    return("(" + Operands1.ToDebugCode() + Operator.ToDebugCode() + Operands2.ToDebugCode() + ")");
                }
                else
                {
                    return(Operator.ToDebugCode() + Operands1.ToDebugCode());
                }

            case ExpressionTokenType.NamedCodeBlock:
                return("block:" + SubTokens[0].ToDebugCode() + "{\n" + Tools.StringUtils.Indent(SubTokens[1].ToDebugCode(), 1) + "}\n");

            case ExpressionTokenType.NamedGenericCodeBlock:
                return("gen_block:" + NamedGenericCodeBlockIdentifier.ToDebugCode() +
                       "{\n" + Tools.StringUtils.Indent(NamedGenericCodeBlockInstructions.ToDebugCode(), 1) + "}\n");

            case ExpressionTokenType.NumberLiteral:
                return(this.Content);

            case ExpressionTokenType.Operator:
                return(this.Content);

            case ExpressionTokenType.Separator:
                return("/" + this.Content);

            case ExpressionTokenType.StringLiteral:
                return("\"" + this.Content + "\"");

            case ExpressionTokenType.Modifier:
                return(this.Content);

            case ExpressionTokenType.ConditionalStatement:
                return(this.Content);

            default:
                return("??");
            }
        }