module diode.license;
//! This is the license for the diode.
enum license;
global licenseArray: string[];
fn __ctor() { }
//! Code to format vdoc objects as code.Hmm
module diode.vdoc.as_code;
//! Formats a vdoc module into code.
class FormatAsCode : Value
{
public:
this(d: Driver, e: Engine, root: VdocRoot, v: Value, type: string) { }
fn toText(n: ir.Node, sink: scope (Sink)) { }
}
struct State
{
public:
drv: Driver;
mod: Parent;
root: VdocRoot;
engine: Engine;
parent: Parent;
tabs: string;
tabsProt: string;
lastKind: Kind;
lastAccess: Access;
hasProt: bool;
public:
fn setup(drv: Driver, engine: Engine, root: VdocRoot, mod: Parent, parent: Parent) { }
fn setup(oldState: State, parent: Parent) { }
}
fn flushaProtAndNewLine(s: State, access: Access, kind: Kind, spacing: string, sink: scope (Sink)) { }
fn drawName(s: State, named: Named, htmlClass: string, sink: scope (Sink)) { }
fn drawName(s: State, named: Named, name: string, htmlClass: string, sink: scope (Sink)) { }
fn drawModule(s: State, sink: scope (Sink)) { }
fn drawChildren(s: State, sink: scope (Sink)) { }
fn drawBrief(s: State, n: Named, sink: scope (Sink)) { }
fn drawParentList(sink: scope (Sink), parents: scope (scope (string)[])) { }
fn drawImports(s: State, access: Access, sink: scope (Sink)) { }
fn drawEnums(s: State, access: Access, sink: scope (Sink)) { }
fn drawEnum(s: State, c: Parent, sink: scope (Sink)) { }
fn drawAliases(s: State, access: Access, sink: scope (Sink)) { }
fn drawAlias(s: State, c: Alias, sink: scope (Sink)) { }
fn drawEnumDecls(s: State, access: Access, sink: scope (Sink)) { }
fn drawEnumDecl(s: State, c: EnumDecl, sink: scope (Sink)) { }
fn drawFields(s: State, access: Access, sink: scope (Sink)) { }
fn drawLocals(s: State, access: Access, sink: scope (Sink)) { }
fn drawGlobals(s: State, access: Access, sink: scope (Sink)) { }
fn drawVariables(s: State, access: Access, storage: Storage, sink: scope (Sink)) { }
fn drawFns(s: State, access: Access, sink: scope (Sink)) { }
fn drawCtors(s: State, access: Access, sink: scope (Sink)) { }
fn drawMembers(s: State, access: Access, sink: scope (Sink)) { }
fn drawCtor(s: State, f: Function, sink: scope (Sink)) { }
fn drawFn(s: State, f: Function, prefix: string, sink: scope (Sink)) { }
fn drawInterfaces(s: State, access: Access, sink: scope (Sink)) { }
fn drawInterface(s: State, c: Parent, sink: scope (Sink)) { }
fn drawClasses(s: State, access: Access, sink: scope (Sink)) { }
fn drawClass(s: State, c: Parent, sink: scope (Sink)) { }
fn drawUnions(s: State, access: Access, sink: scope (Sink)) { }
fn drawStructs(s: State, access: Access, sink: scope (Sink)) { }
fn drawAggrs(s: State, access: Access, kind: Kind, prefix: string, sink: scope (Sink)) { }
fn drawAggr(s: State, c: Parent, prefix: string, sink: scope (Sink)) { }
//! Code handle vdoc filters.
module diode.vdoc.filter;
//! Helper class for Filters.
class FilterValue : Value
{
public:
html: bool;
named: Named;
public:
this(named: Named, html: bool) { }
}
//! Filter for brief.
class FilterBrief : FilterValue
{
public:
this(named: Named) { }
fn toText(n: ir.Node, sink: scope (Sink)) { }
}
//! Filter for brief.
class FilterProto : FilterValue
{
public:
this(named: Named) { }
fn toText(n: ir.Node, sink: scope (Sink)) { }
}
//! Filter for formating of content of DocComments into HTML.
class FilterContent : FilterValue
{
public:
this(named: Named, html: bool) { }
fn toText(n: ir.Node, sink: scope (Sink)) { }
}
//! Filter for formating of full DocComments into HTML.
class FilterFull : FilterValue
{
public:
this(named: Named) { }
fn toText(n: ir.Node, sink: scope (Sink)) { }
}
fn handleDocCommentFilter(d: Driver, e: Engine, root: VdocRoot, v: Value, filter: string, type: string) Value { }
//! Print the brief as regular text.
fn drawBriefText(named: Named, sink: scope (Sink)) { }
//! Print the raw content as markdown.
fn drawContentMD(named: Named, sink: scope (Sink)) { }
//! Print the content as html as processed by markdown.
fn drawContentHTML(named: Named, sink: scope (Sink)) { }
//! Print the full content as HTML.
fn drawFullHTML(named: Named, sink: scope (Sink)) { }
//! Print extra function doccomments, like return and parameters.
fn drawFullFunctionHTML(func: Function, sink: scope (Sink)) { }
//! Print the content as html as processed by markdown.
fn drawProtoHTML(named: Named, sink: scope (Sink)) { }
fn drawProtoNameHTML(sink: scope (Sink), name: string) { }
fn drawProtoPrefixAndNameHTML(sink: scope (Sink), prefix: string, name: string) { }
fn drawProtoAggr(named: Named, sink: scope (Sink), prefix: string) { }
fn drawProtoVar(named: Named, sink: scope (Sink)) { }
fn drawProtoFunc(named: Named, sink: scope (Sink)) { }
module diode.vdoc;
//! Type of doc object.
enum Kind
{
Invalid,
Arg,
Enum,
EnumDecl,
Alias,
Class,
Union,
Group,
Import,
Return,
Struct,
Module,
Member,
Function,
Variable,
Interface,
Destructor,
Constructor,
}
//! Access of a symbool.
enum Access
{
Public,
Protected,
Private,
}
//! Storage of a variable.
enum Storage
{
Field,
Global,
Local,
}
//! The object that templates accesses the rest of the documentation nodes
//! from.
class VdocRoot : Value
{
public:
//! Current thing that a vdoc template is rendering.
current: Value;
//! Set holding config data.
set: Set;
public:
this() { }
fn modules() Parent[] { }
fn groups() Parent[] { }
fn ident(n: ir.Node, key: string) Value { }
//! Return a named object of the given name.
fn findNamed(name: string) Named { }
//! Add a group, mostly used to create groups implicitly.
fn addGroup(name: string, title: string, raw: string) Parent { }
//! Sets the children and does any upfront processing needed.
fn setChildren(children: Value[]) { }
}
//! Base class for all doc objects.
class Base : Value
{
public:
kind: Kind;
public:
this() { }
}
//! Base class for all doc objects that can have names.
class Named : Base
{
public:
//! Printable name of this object.
name: string;
//! Ident for looking up this Named thing.
search: string;
//! Access of this named object.
access: Access;
//! Raw doccomment string.
raw: string;
//! Where to find the per thing documentation page, if any.
url: string;
//! A unique identifier for this object.
tag: string;
//! The content of the doccomment, in markdown form.
content: string;
//! The brief in text form.
brief: string;
//! The groups this named is in.
ingroup: Value[];
//! The sa commands for this Named thing.
sa: string[];
//! The throw commands for this Named thing.
_throw: string[];
//! The se commands for this Named thing.
se: string[];
//! The parsed name of parent class to the class.
parentStr: string;
//! The full name of parent class to the class.
parentFullStr: string;
//! The parsed name of the interface(s) to the class or interface.
interfacesStr: string[];
//! The full name of the interface(s) to the class or interface.
interfacesFullStr: string[];
public:
this() { }
fn ident(n: ir.Node, key: string) Value { }
}
//! Regular imports and bound imports.
class Import : Named
{
public:
//! Is this import bound to a name.
bind: string;
public:
this() { }
fn ident(n: ir.Node, key: string) Value { }
}
//! A single freestanding enum or value part of a enum.
class EnumDecl : Named
{
public:
//! Is this a enum
isStandalone: bool;
public:
this() { }
fn ident(n: ir.Node, key: string) Value { }
}
//! Base class for things with children, like Module, Class, Structs.
class Parent : Named
{
public:
//! The children of this Named thing.
children: Value[];
public:
this() { }
fn ident(n: ir.Node, key: string) Value { }
}
//! Argument to a function.
class Arg : Base
{
public:
name: string;
type: string;
typeFull: string;
//! The doccomment content for this argument.
content: string;
public:
this() { }
fn ident(n: ir.Node, key: string) Value { }
}
//! Return from a function.
class Return : Base
{
public:
type: string;
typeFull: string;
//! The doccomment content for this return.
content: string;
public:
this() { }
fn ident(n: ir.Node, key: string) Value { }
}
//! A variable or field on a aggregate.
class Variable : Named
{
public:
type: string;
typeFull: string;
storage: Storage;
public:
this() { }
fn ident(n: ir.Node, key: string) Value { }
}
//! An alias declaration.
class Alias : Named
{
public:
type: string;
typeFull: string;
public:
this() { }
fn ident(n: ir.Node, key: string) Value { }
}
//! A function or constructor, destructor or method on a aggreegate.
class Function : Named
{
public:
args: Value[];
rets: Value[];
linkage: string;
hasBody: bool;
forceLabel: bool;
isFinal: bool;
isScope: bool;
isAbstract: bool;
isProperty: bool;
isOverride: bool;
public:
this() { }
fn ident(n: ir.Node, key: string) Value { }
}
//! A special array that you can access fields on to filter the members.
class Collection : Array
{
public:
this(vals: Value[]) { }
fn ident(n: ir.Node, key: string) Value { }
public:
static fn make(vals: Value[], key: string) Value { }
}
fn accessToString(access: Access) string { }
//! Create a text Value, nil if string is empty.
fn makeNilOrText(text: string) Value { }
//! Create a array Value, nil if string is empty.
fn makeNilOrArray(array: Value[]) Value { }
module diode.vdoc.parser;
//! Parser for getting defgroup name and title.
class DocCommentDefGroup : vdoc.DocSink
{
public:
groupName: string;
groupTitle: string;
public:
this() { }
fn parseRaw(raw: string, defgroup: string, title: string) { }
fn defgroup(sink: scope (Sink), group: string, text: string) { }
fn start(sink: scope (Sink)) { }
fn end(sink: scope (Sink)) { }
fn briefStart(sink: scope (Sink)) { }
fn briefEnd(sink: scope (Sink)) { }
fn sectionStart(sink: scope (Sink), sec: vdoc.DocSection) { }
fn sectionEnd(sink: scope (Sink), sec: vdoc.DocSection) { }
fn paramStart(sink: scope (Sink), direction: string, arg: string) { }
fn paramEnd(sink: scope (Sink)) { }
fn p(sink: scope (Sink), state: vdoc.DocState, d: string) { }
fn link(sink: scope (Sink), state: vdoc.DocState, target: string, text: string) { }
fn content(sink: scope (Sink), state: vdoc.DocState, cnt: string) { }
fn ingroup(sink: scope (Sink), group: string) { }
}
//! Parse the given data and add the vdocRoot.
fn parse(vdocRoot: VdocRoot, data: string) { }
//! Code to generate brief comments from full vdoc doccomments.
module diode.vdoc.brief;
//! A Markdown visitor that removes most of the special formating.
class PlainText : Visitor
{
public:
this(lineLimit: size_t) { }
fn visit(n: Text, sink: scope (Sink)) { }
fn visit(n: Code, sink: scope (Sink)) { }
fn visit(n: Softbreak, sink: scope (Sink)) { }
fn visit(n: Linebreak, sink: scope (Sink)) { }
fn enter(n: Link, sink: scope (Sink)) { }
fn leave(n: Link, sink: scope (Sink)) { }
fn enter(n: BlockQuote, sink: scope (Sink)) { }
fn enter(n: Item, sink: scope (Sink)) { }
fn enter(n: List, sink: scope (Sink)) { }
fn enter(n: Heading, sink: scope (Sink)) { }
fn leave(n: Paragraph, sink: scope (Sink)) { }
fn enter(n: Document, sink: scope (Sink)) { }
fn enter(n: Image, sink: scope (Sink)) { }
fn enter(n: Paragraph, sink: scope (Sink)) { }
fn enter(n: Strong, sink: scope (Sink)) { }
fn enter(n: Emph, sink: scope (Sink)) { }
fn leave(n: Document, sink: scope (Sink)) { }
fn leave(n: Strong, sink: scope (Sink)) { }
fn leave(n: Emph, sink: scope (Sink)) { }
fn leave(n: Image, sink: scope (Sink)) { }
fn leave(n: Heading, sink: scope (Sink)) { }
fn leave(n: Item, sink: scope (Sink)) { }
fn leave(n: List, sink: scope (Sink)) { }
fn leave(n: BlockQuote, sink: scope (Sink)) { }
fn visit(n: HtmlBlock, sink: scope (Sink)) { }
fn visit(n: CodeBlock, sink: scope (Sink)) { }
fn visit(n: ThematicBreak, sink: scope (Sink)) { }
fn visit(n: HtmlInline, sink: scope (Sink)) { }
protected:
//! Have we stopped processing text.
mStopped: bool;
//! Used to insert spaces between words and instead of softbreaks.
mWriteSpace: bool;
//! The current link that has not yet been flushed to the sink.
mNewLink: Link;
//! Link that has been flushed to the sink, and should be closed.
mAppliedLink: Link;
//! The current length of the line we are writing.
mLineLength: size_t;
//! Limit for the number of characters on a line.
mLineLimit: size_t;
protected:
//! Write a string to the sink, will compact whitespace and insert newlines
//! when the line will break the mLineLimit.
fn writeText(str: string, sink: scope (Sink)) { }
//! Flushes spaces and links to the sink.
fn flushThings(sink: scope (Sink)) { }
//! Inserts a newline and resets link.
fn insertNewLine(sink: scope (Sink)) { }
}
fn generateAutoBrief(str: string) string { }
//! Code to process vdoc objects raw doccomments.
module diode.vdoc.processor;
//! Main class for processing vdoc objects.
class Processor : DocCommentParser
{
public:
groups: Parent[string];
public:
this(root: VdocRoot) { }
}
//! A single parameter result.
class DocCommentParam
{
public:
arg: string;
dir: string;
doc: string;
public:
this() { }
}
//! Helper class for DocComments.
class DocCommentParser : DocSink
{
public:
//! For lookups.
root: VdocRoot;
//! The full comment content.
full: StringSink;
//! String sink for params, briefs and more.
temp: StringSink;
//! Current param.
param: DocCommentParam;
//! The result of the processing.
results: DocCommentResult;
//! ` directive been processed.
hasBrief: bool;
public:
this(root: VdocRoot) { }
fn parseRaw(raw: string) { }
fn ingroup(sink: scope (Sink), group: string) { }
fn sectionStart(sink: scope (Sink), sec: DocSection) { }
fn sectionEnd(sink: scope (Sink), sec: DocSection) { }
fn paramStart(sink: scope (Sink), direction: string, arg: string) { }
fn paramEnd(sink: scope (Sink)) { }
fn briefStart(sink: scope (Sink)) { }
fn briefEnd(sink: scope (Sink)) { }
fn p(sink: scope (Sink), state: DocState, d: string) { }
fn link(sink: scope (Sink), state: DocState, target: string, text: string) { }
fn content(sink: scope (Sink), state: DocState, d: string) { }
fn defgroup(sink: scope (Sink), group: string, text: string) { }
fn start(sink: scope (Sink)) { }
fn end(sink: scope (Sink)) { }
}
//! Results from a doccomment parsing.
struct DocCommentResult
{
public:
//! The main content for this doccomment.
content: string;
//! Brief doccomment.
brief: string;
//! The groups this comment is in.
ingroups: string[];
//! Return documentation.
ret: string;
//! Params for functions.
params: DocCommentParam[];
//! See also sections.
sa: string[];
//! Throws sections.
_throw: string[];
//! Side-Effect sections.
se: string[];
//! The doccomment content form the return command.
returnContent: string;
}
//! Processes the given VdocRoot.
fn process(vdocRoot: VdocRoot) { }
//! Small testing harness.
module diode.tester;
//! Single test files are split with this marker.
enum Split;
class Tester : Engine
{
public:
this(env: Set) { }
fn handleError(str: string) { }
}
fn runTest(args: string[]) i32 { }
fn runTest(srcFile: string) i32 { }
fn runTest(srcFile: string, cmpFile: string) i32 { }
fn compileAndCompare(srcText: string, cmpText: string, srcFile: string) i32 { }
fn getTestEnv() Set { }
module diode.driver;
//! Main focal point of Diode.
class DiodeDriver : Driver
{
public:
this(settings: Settings) { }
fn setConfig(source: string, filename: string) { }
fn addBuiltins() { }
fn processDoc() { }
fn addLayout(source: string, filename: string) { }
fn addInclude(source: string, filename: string) { }
fn renderFile(source: string, filename: string, output: string) { }
fn addDoc(source: string, filename: string) { }
fn addDocTemplate(source: string, filename: string) { }
fn verbose(fmt: string) { }
fn info(fmt: string) { }
fn warning(fmt: string) { }
fn addInclude(file: File, filename: string) { }
fn addLayout(file: File, filename: string) { }
fn addDocTemplate(file: File, filename: string) { }
fn renderFileTo(file: File, output: string) { }
protected:
mLayouts: File[string];
mRoot: Set;
mSite: Set;
mVdoc: VdocRoot;
mModules: Array;
mEngine: DriverEngine;
mDocGroup: File;
mDocModule: File;
mDocModules: File;
mVerbose: bool;
mSiteSettings: json.Value;
mPrintUndocumented: bool;
protected:
fn tag(val: Value, parentWithUrl: Parent, prev: Value) { }
fn setUrl(named: Named, parentWithUrl: Named) { }
fn getTag(base: string) string { }
fn getUrl(named: Named, parentWithUrl: Named) string { }
fn getName(dir: string, base: string) string { }
fn createFile(source: string, filename: string) File { }
fn selectType(layout: File, contents: File) Contents { }
fn getAndCheckExt(base: string) File.Ext { }
fn getLayout(key: string) File { }
fn getNeededLayout(file: File) File { }
fn buildRootEnv() { }
}
class DriverEngine : Engine
{
public:
file: File;
public:
this(d: DiodeDriver, root: Set) { }
fn addInclude(f: File, filename: string) { }
fn renderFile(f: File, sink: scope (Sink)) { }
fn handleFilter(n: ir.Node, ident: string, child: Value, args: Value[], sink: scope (Sink)) { }
fn handleInclude(p: ir.Include, e: Set, sink: scope (Sink)) { }
}
//! A file to be rendered. Used for includes and layouts as well.
class File
{
public:
enum Ext
{
HTML,
Markdown,
}
public:
filename: string;
fullName: string;
layout: string;
header: Header;
file: ir.File;
ext: Ext;
public:
this() { }
fn getOption(key: string, def: string) string { }
}
//! Special Value for the contents value.
class Contents : Value
{
public:
engine: DriverEngine;
file: File;
env: Set;
public:
this() { }
fn toText(n: ir.Node, sink: scope (Sink)) { }
}
//! Special Value for Markdown to HTML contents.
class MarkdownContents : Contents
{
public:
this() { }
fn toText(n: ir.Node, sink: scope (Sink)) { }
}
//! Implementation of relative_url filter, appends baseurl.
fn filterRelativeUrl(drv: Driver, str: string) string { }
//! Implementation of absolute_url filter, appends url and baseurl.
fn filterAbsoluteUrl(drv: Driver, str: string) string { }
module diode.errors;
class DiodeException : Exception
{
public:
this(msg: string) { }
}
class EvalException : DiodeException
{
public:
n: ir.Node;
public:
this(n: ir.Node, msg: string) { }
}
fn makeNoExtension(file: string) DiodeException { }
fn makeExtensionNotSupported(file: string) DiodeException { }
fn makeLayoutNotFound(file: string, layout: string) DiodeException { }
fn makeConversionNotSupported(layout: string, contents: string) DiodeException { }
fn makeNoField(n: ir.Node, key: string) EvalException { }
fn makeNotSet(n: ir.Node) EvalException { }
fn makeNotText(n: ir.Node) EvalException { }
fn makeNotArray(n: ir.Node) EvalException { }
module diode.interfaces;
//! Main class driving everything.
class Driver
{
public:
settings: Settings;
public:
this(settings: Settings) { }
fn addBuiltins();
fn processDoc();
fn setConfig(source: string, filename: string);
fn addLayout(source: string, filename: string);
fn addInclude(source: string, filename: string);
fn addDoc(source: string, filename: string);
fn addDocTemplate(source: string, filename: string);
fn renderFile(source: string, filename: string, output: string);
fn verbose(fmt: string);
fn info(fmt: string);
fn warning(fmt: string);
}
//! Holds settings for Diode.
class Settings
{
public:
enum vdocDirDefault;
enum outputDirDefault;
enum layoutDirDefault;
enum includeDirDefault;
public:
sourceDir: string;
vdocDir: string;
outputDir: string;
layoutDir: string;
includeDir: string;
urlFromCommandLine: bool;
url: string;
baseurlFromCommandLine: bool;
baseurl: string;
//! Temporary hack for guru untill we add vdoc cross-reference code.
guruHackSuffix: string;
public:
this() { }
fn fillInDefaults() { }
fn processPath(val: string, def: string) { }
}
//! Holds the main function and some small test code.
module main;
enum ParseState
{
Normal,
Skip,
OutputDir,
SourceDir,
Baseurl,
}
fn main(args: string[]) i32 { }
fn parseArgs(args: string[], s: Settings) string[] { }
fn splitUrl(str: string, server: string, address: string) bool { }
fn test(args: string[]) i32 { }
fn findConfig(d: DiodeDriver) { }
fn addFiles(d: DiodeDriver, files: string[]) { }
fn renderFiles(d: Driver) { }
fn addLayouts(d: Driver) { }
fn addIncludes(d: Driver) { }
fn addVdocTemplates(d: Driver) { }
module diode.parser.frontmatter;
class Header
{
public:
map: string[string];
public:
this() { }
}
fn parse(src: Source, err: ErrorDg) Header { }
//! Does not advance the source, just check if the next 3 chars are
//! dashes.
fn isTripleDash(src: Source) bool { }
//! Does what it says on the tin, yes I felt bad naming this function.
fn skipWhiteAndCheckIfEmptyLine(src: Source) bool { }
fn skipWhiteTillAfterColon(src: Source, err: ErrorDg) { }
fn getIdent(src: Source, err: ErrorDg) string { }
fn getRestOfLine(src: Source) string { }
module diode.parser.errors;
alias ErrorDg = void delegate(string);
fn makeBadHeader(loc: Location, err: ErrorDg) { }
module liquid.eval.engine;
class Engine : ir.Visitor
{
public:
env: Set;
v: Value;
public:
this(env: Set) { }
fn handleFilter(n: ir.Node, ident: string, child: Value, args: Value[], sink: scope (Sink)) { }
fn handleError(str: string) { }
fn handleInclude(i: ir.Include, env: Set, sink: scope (Sink)) { }
fn visit(t: ir.Text, sink: scope (Sink)) Status { }
fn leave(p: ir.Print, sink: scope (Sink)) Status { }
fn enter(i: ir.If, sink: scope (Sink)) Status { }
fn enter(f: ir.For, sink: scope (Sink)) Status { }
fn leave(a: ir.Assign, sink: scope (Sink)) Status { }
fn visit(p: ir.Include, sink: scope (Sink)) Status { }
fn enter(p: ir.BinOp, sink: scope (Sink)) Status { }
fn leave(p: ir.BinOp, sink: scope (Sink)) Status { }
fn enter(p: ir.Index, sink: scope (Sink)) Status { }
fn leave(p: ir.Index, sink: scope (Sink)) Status { }
fn leave(p: ir.Access, sink: scope (Sink)) Status { }
fn enter(p: ir.Filter, sink: scope (Sink)) Status { }
fn visit(p: ir.Ident, sink: scope (Sink)) Status { }
fn visit(p: ir.StringLiteral, sink: scope (Sink)) Status { }
fn visit(p: ir.BoolLiteral, sink: scope (Sink)) Status { }
fn visit(p: ir.NumberLiteral, sink: scope (Sink)) Status { }
fn enter(ir.Assign, scope (Sink)) Status { }
fn enter(ir.File, scope (Sink)) Status { }
fn leave(ir.File, scope (Sink)) Status { }
fn enter(ir.Access, scope (Sink)) Status { }
fn leave(ir.Filter, scope (Sink)) Status { }
fn enter(ir.Print, scope (Sink)) Status { }
fn leave(ir.If, scope (Sink)) Status { }
fn leave(ir.For, scope (Sink)) Status { }
}
//! This module holds code to parse json files into eval sets and values.
module liquid.eval.json;
fn toValue(v: json.Value) Value { }
fn toSet(v: json.Value) Set { }
fn toArray(v: json.Value) Array { }
module liquid.eval.value;
//! Use the IR visitor Sink.
alias Sink = ir.Sink;
class Value
{
public:
this() { }
fn ident(n: ir.Node, key: string) Value { }
fn toText(n: ir.Node, sink: scope (Sink)) { }
fn toArray(n: ir.Node) Value[] { }
fn toBool(n: ir.Node) bool { }
fn toSize(n: ir.Node) Value { }
fn opEquals(other: Value) bool { }
fn opIndex(other: Value) Value { }
fn contains(other: Value) bool { }
fn opCmp(other: Value) i32 { }
}
class Nil : Value
{
public:
this() { }
fn toBool(n: ir.Node) bool { }
fn opEquals(other: Value) bool { }
}
class Number : Value
{
public:
value: f64;
integer: bool;
public:
this(value: f64, integer: bool) { }
fn toText(n: ir.Node, sink: scope (Sink)) { }
fn opEquals(other: Value) bool { }
fn opCmp(otherVal: Value) i32 { }
}
class Bool : Value
{
public:
value: bool;
public:
this(value: bool) { }
fn toText(n: ir.Node, sink: scope (Sink)) { }
fn toBool(n: ir.Node) bool { }
fn opEquals(other: Value) bool { }
}
class Text : Value
{
public:
text: string;
public:
this(text: string) { }
fn toText(n: ir.Node, sink: scope (Sink)) { }
fn toBool(n: ir.Node) bool { }
fn toSize(n: ir.Node) Value { }
fn opEquals(other: Value) bool { }
fn contains(otherVal: Value) bool { }
}
class Array : Value
{
public:
vals: Value[];
public:
this(vals: Value[]) { }
fn toArray(n: ir.Node) Value[] { }
fn toSize(n: ir.Node) Value { }
fn ident(n: ir.Node, key: string) Value { }
fn contains(other: Value) bool { }
fn opIndex(index: Value) Value { }
}
class Set : Value
{
public:
parent: Set;
ctx: Value[string];
public:
this() { }
this(parent: Set) { }
fn ident(n: ir.Node, key: string) Value { }
}
module liquid.eval;
public import liquid.eval.value;
public import liquid.eval.engine;
module liquid.util.build;
fn bFile() ir.File { }
fn bPrint(e: ir.Exp) ir.Print { }
fn bText(str: string) ir.Text { }
fn bAssign(ident: string, exp: ir.Exp) ir.Assign { }
fn bInclude(filename: string, assigns: ir.Assign[]) ir.Include { }
fn bFor(ident: string, exp: ir.Exp, nodes: ir.Node[]) ir.For { }
fn bBinOp(type: ir.BinOp.Type, l: ir.Exp, r: ir.Exp) ir.BinOp { }
fn bIndex(child: ir.Exp, index: ir.Exp) ir.Index { }
fn bIf(invert: bool, exp: ir.Exp, nodes: ir.Node[], elseNodes: ir.Node[]) ir.If { }
fn bAccess(exp: ir.Exp, key: string) ir.Access { }
fn bFilter(exp: ir.Exp, key: string, args: ir.Exp[]) ir.Filter { }
fn bIdent(ident: string) ir.Ident { }
fn bStringLiteral(val: string) ir.StringLiteral { }
fn bNumberLiteral(val: f64, integer: bool) ir.NumberLiteral { }
fn bBoolLiteral(val: bool) ir.BoolLiteral { }
fn bPrintChain(start: string, idents: string[]) ir.Print { }
fn bChain(start: string, idents: string[]) ir.Exp { }
fn bClosingTagNode(name: string) ir.ClosingTagNode { }
module liquid.util.sink;
//! Used as a sink for functions that return multiple nodes.
struct NodeSink
{
public:
fn push(n: ir.Node) { }
fn takeArray() ir.Node[] { }
}
module liquid.parser;
public import liquid.parser.parser;
module liquid.parser.errors;
fn errorExpected(p: Parser, expected: dchar, found: dchar) Status { }
fn errorExpected(p: Parser, expected: string, found: string) Status { }
fn errorExpectedIdentifier(p: Parser) Status { }
fn errorExpectedIncludeName(p: Parser) Status { }
fn errorExpectedEndComment(p: Parser) Status { }
fn errorUnmatchedClosingTag(p: Parser, name: string) Status { }
fn errorMissingTagEOF(p: Parser, tags: string[]) Status { }
fn errorUnknownStatement(p: Parser, name: string) Status { }
module liquid.parser.parser;
enum Status
{
Ok,
Error,
}
class Parser
{
public:
enum State
{
Text,
Print,
Statement,
End,
}
public:
state: State;
src: Source;
sink: StringSink;
//! A description of an error for the user's consumption.
errorMessage: string;
raw: bool;
public:
this(src: Source) { }
//! Given a state in which we expect a two char string, skip it.
fn eatSequence(s: string) Status { }
//! Parse an identifier name into sink.
fn eatIdent() { }
//! If the parser is at the given word, return true. No characters are
//! consumed.
fn atWord(s: string) bool { }
//! Parse a include name into sink.
fn eatIncludeName() { }
//! Get the contents of the sink, and then reset it.
fn getSink() string { }
}
fn parse(src: Source, e: Engine) ir.File { }
//! Parse a liquid file.
fn parseFile(p: Parser, file: ir.File) Status { }
//! Parse nodes until we hit a {% %}. If name is 'elsif', the If node will
//! be placed at the end of nodes.
fn parseNodesUntilTag(p: Parser, nodes: ir.Node[], nameThatEnded: string, names: string[]) Status { }
//! Parse the individual elements of the file until we run out of file.
fn parseNode(p: Parser, node: ir.Node) Status { }
fn atEndRaw(p: Parser) bool { }
//! Parse regular text until we find a tag, or run out of text.
fn parseText(p: Parser, text: ir.Node) Status { }
//! Parse {{ ... }}.
fn parsePrint(p: Parser, print: ir.Node) Status { }
//! Parse an entire Exp expression.
fn parseExp(p: Parser, exp: ir.Exp, justOneExpression: bool) Status { }
fn parseNumberLiteral(p: Parser, exp: ir.Exp) Status { }
fn parseStringLiteral(p: Parser, exp: ir.Exp) Status { }
//! Parse an Access expression.
fn parseAccess(p: Parser, child: ir.Exp, exp: ir.Exp) Status { }
//! Parse a Filter expression.
fn parseFilter(p: Parser, child: ir.Exp, exp: ir.Exp) Status { }
//! Parse Filter arguments (if any).
fn parseFilterArgs(p: Parser, args: ir.Exp[]) Status { }
//! Parse a statement.
fn parseStatement(p: Parser, node: ir.Node) Status { }
fn parseAssign(p: Parser, node: ir.Node) Status { }
fn parseInclude(p: Parser, node: ir.Node) Status { }
fn parseElsIf(p: Parser, node: ir.Node) Status { }
fn parseIf(p: Parser, invert: bool, node: ir.Node) Status { }
fn parseRaw(p: Parser, node: ir.Node) Status { }
fn parseFor(p: Parser, node: ir.Node) Status { }
fn parseComment(p: Parser) Status { }
//! This function parses a ident.
fn parseIdent(p: Parser, name: string) Status { }
//! This function parser a include name.
fn parseIncludeName(p: Parser, name: string) Status { }
//! Parses close statements '%}', handles hyphens.
fn parseCloseStatement(p: Parser) Status { }
//! Parses close statements '%}', handles hyphens.
fn parseClosePrint(p: Parser) Status { }
//! Matches and skips a single char from the source, sets error msg.
fn matchAndSkip(p: Parser, c: dchar) Status { }
//! Returns either a ir.Ident or ir.BoolLiteral.
fn makeIdentOrBool(word: string) ir.Exp { }
//! Returns true if current character is c and skip it.
fn ifAndSkip(p: Parser, c: dchar) bool { }
//! Is the given char a valid character for a include name.
fn isIncludeName(c: dchar) bool { }
//! Is the given char a valid character for a variable name.
fn isIdentName(c: dchar) bool { }
module liquid.ir;
public import liquid.ir.ir;
module liquid.ir.ir;
public import watt.text.sink;
//! Control the flow of the visitor.
enum Status
{
Stop,
Continue,
ContinueParent,
}
//! Base class for all nodes.
class Node
{
public:
this() { }
fn accept(v: Visitor, sink: scope (Sink)) Status;
}
//! Top level container node.
class File : Node
{
public:
nodes: Node[];
public:
this() { }
fn accept(v: Visitor, sink: scope (Sink)) Status { }
}
//! A string of text to be printed out directly.
class Text : Node
{
public:
text: string;
public:
this(text: string) { }
fn accept(v: Visitor, sink: scope (Sink)) Status { }
}
//! A expression to be evaluated and printed.
class Print : Node
{
public:
exp: Exp;
public:
this(exp: Exp) { }
fn accept(v: Visitor, sink: scope (Sink)) Status { }
}
//! Base class for all expressions.
class Exp : Node
{
public:
this() { }
}
//! A single identifier to be looked up in the global scope.
class Ident : Exp
{
public:
ident: string;
public:
this(ident: string) { }
fn accept(v: Visitor, sink: scope (Sink)) Status { }
}
//! A string literal.
class StringLiteral : Exp
{
public:
val: string;
public:
this(val: string) { }
fn accept(v: Visitor, sink: scope (Sink)) Status { }
}
//! A bool literal.
class BoolLiteral : Exp
{
public:
val: bool;
public:
this(val: bool) { }
fn accept(v: Visitor, sink: scope (Sink)) Status { }
}
//! A literal for a number.
class NumberLiteral : Exp
{
public:
val: f64;
integer: bool;
public:
this(val: f64, integer: bool) { }
fn accept(v: Visitor, sink: scope (Sink)) Status { }
}
class BinOp : Exp
{
public:
enum Type
{
Equal,
NotEqual,
GreaterThan,
LessThan,
GreaterThanOrEqual,
LessThanOrEqual,
Or,
And,
Contains,
}
public:
type: Type;
l: Exp;
r: Exp;
public:
this(type: Type, l: Exp, r: Exp) { }
fn accept(v: Visitor, sink: scope (Sink)) Status { }
}
//! Lookup symbol into child expression.
class Access : Exp
{
public:
child: Exp;
ident: string;
public:
this(child: Exp, ident: string) { }
fn accept(v: Visitor, sink: scope (Sink)) Status { }
}
//! Array lookup.
class Index : Exp
{
public:
child: Exp;
index: Exp;
public:
this(child: Exp, index: Exp) { }
fn accept(v: Visitor, sink: scope (Sink)) Status { }
}
//! Filter expression.
class Filter : Exp
{
public:
child: Exp;
ident: string;
args: Exp[];
public:
this(child: Exp, ident: string, args: Exp[]) { }
fn accept(v: Visitor, sink: scope (Sink)) Status { }
}
//! If control statement.
class If : Node
{
public:
thenNodes: Node[];
elseNodes: Node[];
exp: Exp;
invert: bool;
elsif: bool;
public:
this(invert: bool, exp: Exp, thenNodes: Node[], elseNodes: Node[]) { }
fn accept(v: Visitor, sink: scope (Sink)) Status { }
}
//! For loop control statement.
class For : Node
{
public:
var: string;
nodes: Node[];
exp: Exp;
public:
this(var: string, exp: Exp, nodes: Node[]) { }
fn accept(v: Visitor, sink: scope (Sink)) Status { }
}
class Assign : Node
{
public:
ident: string;
exp: Exp;
public:
this(ident: string, exp: Exp) { }
fn accept(v: Visitor, sink: scope (Sink)) Status { }
}
class Include : Node
{
public:
filename: string;
assigns: Assign[];
public:
this(filename: string, assigns: Assign[]) { }
fn accept(v: Visitor, sink: scope (Sink)) Status { }
}
//! Not actually output by the parser. Used for things like %endif%, which
//! mark the end of a list of nodes.
class ClosingTagNode : Node
{
public:
name: string;
public:
this(name: string) { }
fn accept(v: Visitor, sink: scope (Sink)) Status { }
}
//! Base visitor class.
class Visitor
{
public:
alias Status = Status;
alias Stop = Status.Stop;
alias Continue = Status.Continue;
alias ContinueParent = Status.ContinueParent;
public:
this() { }
fn enter(File, scope (Sink)) Status;
fn leave(File, scope (Sink)) Status;
fn visit(Text, scope (Sink)) Status;
fn enter(Print, scope (Sink)) Status;
fn leave(Print, scope (Sink)) Status;
fn enter(If, scope (Sink)) Status;
fn leave(If, scope (Sink)) Status;
fn enter(For, scope (Sink)) Status;
fn leave(For, scope (Sink)) Status;
fn enter(Assign, scope (Sink)) Status;
fn leave(Assign, scope (Sink)) Status;
fn visit(Include, scope (Sink)) Status;
fn enter(Access, scope (Sink)) Status;
fn leave(Access, scope (Sink)) Status;
fn enter(Filter, scope (Sink)) Status;
fn leave(Filter, scope (Sink)) Status;
fn enter(BinOp, scope (Sink)) Status;
fn leave(BinOp, scope (Sink)) Status;
fn enter(Index, scope (Sink)) Status;
fn leave(Index, scope (Sink)) Status;
fn visit(Ident, scope (Sink)) Status;
fn visit(StringLiteral, scope (Sink)) Status;
fn visit(BoolLiteral, scope (Sink)) Status;
fn visit(NumberLiteral, scope (Sink)) Status;
}
//! Filter out continue parent and turn that into a continue.
fn filterParent(s: Status) Status { }