// Copyright Brian Schott (Hackerpilot) 2012. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) module dscanner.astprinter; import dparse.lexer; import dparse.ast; import dparse.formatter; import std.stdio; import std.string; import std.array; /** * AST visitor that outputs an XML representation of the AST to its file. */ class XMLPrinter : ASTVisitor { override void visit(const AddExpression addExpression) { output.writeln(""); output.writeln(""); visit(addExpression.left); output.writeln(""); if (addExpression.right !is null) { output.writeln(""); visit(addExpression.right); output.writeln(""); } output.writeln(""); } override void visit(const AliasDeclaration aliasDeclaration) { output.writeln(""); writeDdoc(aliasDeclaration.comment); aliasDeclaration.accept(this); output.writeln(""); } override void visit(const AlignAttribute alignAttribute) { if (alignAttribute.assignExpression is null) output.writeln(""); else { output.write(""); } } override void visit(const AndAndExpression andAndExpression) { output.writeln(""); output.writeln(""); visit(andAndExpression.left); output.writeln(""); if (andAndExpression.right !is null) { output.writeln(""); visit(andAndExpression.right); output.writeln(""); } output.writeln(""); } override void visit(const AndExpression andExpression) { output.writeln(""); output.writeln(""); visit(andExpression.left); output.writeln(""); if (andExpression.right !is null) { output.writeln(""); visit(andExpression.right); output.writeln(""); } output.writeln(""); } override void visit(const AsmInstruction asmInstruction) { output.writeln(""); if (asmInstruction.hasAlign) { output.writeln(""); visit(asmInstruction.identifierOrIntegerOrOpcode); output.writeln(""); } if (asmInstruction.asmInstruction !is null) { output.writeln(""); } override void visit(const AssertExpression assertExpression) { output.writeln(""); output.writeln(""); assertExpression.assertion.accept(this); output.writeln(""); if (assertExpression.message !is null) { output.writeln(""); assertExpression.message.accept(this); output.writeln(""); } output.writeln(""); } override void visit(const AssignExpression assignExpression) { if (assignExpression.expression is null) output.writeln(""); else output.writeln(""); assignExpression.accept(this); output.writeln(""); } override void visit(const AtAttribute atAttribute) { output.writeln(""); if (atAttribute.identifier.type != tok!"") output.writeln("", atAttribute.identifier.text, ""); atAttribute.accept(this); output.writeln(""); } override void visit(const Attribute attribute) { if (attribute.attribute == tok!"") { output.writeln(""); attribute.accept(this); output.writeln(""); } else if (attribute.identifierChain is null) output.writeln(""); else { output.writeln(""); visit(attribute.identifierChain); output.writeln(""); } } override void visit(const AutoDeclaration autoDec) { output.writeln(""); output.writeln(""); foreach (sc; autoDec.storageClasses) visit(sc); output.writeln(""); foreach (part; autoDec.parts) visit(part); output.writeln(""); } override void visit(const AutoDeclarationPart part) { output.writeln(""); output.writeln(""); output.writeln("", part.identifier.text, ""); visit(part.initializer); output.writeln(""); output.writeln(""); } override void visit(const BreakStatement breakStatement) { if (breakStatement.label.type == tok!"") output.writeln(""); else output.writeln(""); } override void visit(const CaseRangeStatement caseRangeStatement) { output.writeln(""); if (caseRangeStatement.low !is null) { output.writeln(""); visit(caseRangeStatement.low); output.writeln(""); } if (caseRangeStatement.high !is null) { output.writeln(""); visit(caseRangeStatement.high); output.writeln(""); } if (caseRangeStatement.declarationsAndStatements !is null) visit(caseRangeStatement.declarationsAndStatements); output.writeln(""); } override void visit(const Catch catch_) { output.writeln(""); catch_.accept(this); output.writeln(""); } override void visit(const ClassDeclaration classDec) { output.writeln(""); writeName(classDec.name.text); writeDdoc(classDec.comment); classDec.accept(this); output.writeln(""); } override void visit(const ConditionalDeclaration conditionalDeclaration) { output.writeln(""); visit(conditionalDeclaration.compileCondition); output.writeln(""); foreach (dec; conditionalDeclaration.trueDeclarations) visit(dec); output.writeln(""); if (conditionalDeclaration.falseDeclarations.length > 0) { output.writeln(""); foreach (dec; conditionalDeclaration.falseDeclarations) visit(dec); output.writeln(""); } output.writeln(""); } override void visit(const ConditionalStatement conditionalStatement) { output.writeln(""); visit(conditionalStatement.compileCondition); output.writeln(""); visit(conditionalStatement.trueStatement); output.writeln(""); if (conditionalStatement.falseStatement !is null) { output.writeln(""); visit(conditionalStatement.falseStatement); output.writeln(""); } output.writeln(""); } override void visit(const ContinueStatement continueStatement) { if (continueStatement.label.type == tok!"") output.writeln(""); else output.writeln(""); } override void visit(const DebugCondition debugCondition) { if (debugCondition.identifierOrInteger.type == tok!"") output.writeln(""); else output.writeln(""); } override void visit(const DebugSpecification debugSpecification) { if (debugSpecification.identifierOrInteger.type == tok!"") output.writeln(""); else output.writeln(""); } override void visit(const Declarator declarator) { output.writeln(""); writeName(declarator.name.text); writeDdoc(declarator.comment); declarator.accept(this); output.writeln(""); } override void visit(const Deprecated deprecated_) { if (deprecated_.assignExpression !is null) { output.writeln(""); visit(deprecated_.assignExpression); output.writeln(""); } else output.writeln(""); } override void visit(const EnumDeclaration enumDec) { output.writeln(""); writeDdoc(enumDec.comment); if (enumDec.name.type == tok!"identifier") writeName(enumDec.name.text); enumDec.accept(this); output.writeln(""); } override void visit(const AnonymousEnumMember enumMember) { output.writeln(""); writeDdoc(enumMember.comment); if (enumMember.type !is null) visit(enumMember.type); output.write("", enumMember.name.text, ""); if (enumMember.assignExpression !is null) visit(enumMember.assignExpression); output.writeln(""); } override void visit(const EnumMember enumMem) { output.writeln(""); writeDdoc(enumMem.comment); enumMem.accept(this); output.writeln(""); } override void visit(const EqualExpression equalExpression) { output.writeln(""); output.writeln(""); visit(equalExpression.left); output.writeln(""); output.writeln(""); visit(equalExpression.right); output.writeln(""); output.writeln(""); } override void visit(const Finally finally_) { output.writeln(""); finally_.accept(this); output.writeln(""); } override void visit(const ForStatement forStatement) { output.writeln(""); if (forStatement.initialization !is null) { output.writeln(""); visit(forStatement.initialization); output.writeln(""); } if (forStatement.test !is null) { output.writeln(""); visit(forStatement.test); output.writeln(""); } if (forStatement.increment !is null) { output.writeln(""); visit(forStatement.increment); output.writeln(""); } if (forStatement.declarationOrStatement !is null) visit(forStatement.declarationOrStatement); output.writeln(""); } override void visit(const ForeachStatement foreachStatement) { output.writeln(""); if (foreachStatement.foreachType !is null) visit(foreachStatement.foreachType); if (foreachStatement.foreachTypeList !is null) visit(foreachStatement.foreachTypeList); output.writeln(""); visit(foreachStatement.low); output.writeln(""); if (foreachStatement.high !is null) { output.writeln(""); visit(foreachStatement.high); output.writeln(""); } visit(foreachStatement.declarationOrStatement); output.writeln(""); } override void visit(const ForeachType foreachType) { output.writeln(""); foreach (constructor; foreachType.typeConstructors) { output.writeln("", str(constructor), ""); } if (foreachType.type !is null) visit(foreachType.type); visit(foreachType.identifier); output.writeln(""); } override void visit(const FunctionDeclaration functionDec) { output.writeln(""); writeName(functionDec.name.text); writeDdoc(functionDec.comment); if (functionDec.hasAuto) output.writeln(""); if (functionDec.hasRef) output.writeln(""); functionDec.accept(this); output.writeln(""); } override void visit(const FunctionLiteralExpression functionLiteralExpression) { output.writeln(""); functionLiteralExpression.accept(this); output.writeln(""); } override void visit(const GotoStatement gotoStatement) { if (gotoStatement.label.type == tok!"default") output.writeln(""); else if (gotoStatement.label.type == tok!"identifier") output.writeln(""); else { output.writeln(""); output.writeln(""); if (gotoStatement.expression) visit(gotoStatement.expression); output.writeln(""); output.writeln(""); } } override void visit(const IdentityExpression identityExpression) { if (identityExpression.negated) output.writeln(""); else output.writeln(""); output.writeln(""); visit(identityExpression.left); output.writeln(""); output.writeln(""); visit(identityExpression.right); output.writeln(""); output.writeln(""); } override void visit(const IfStatement ifStatement) { output.writeln(""); output.writeln(""); if (ifStatement.identifier.type != tok!"") { if (ifStatement.type is null) output.writeln(""); else visit(ifStatement.type); visit(ifStatement.identifier); } ifStatement.expression.accept(this); output.writeln(""); output.writeln(""); ifStatement.thenStatement.accept(this); output.writeln(""); if (ifStatement.elseStatement !is null) { output.writeln(""); ifStatement.elseStatement.accept(this); output.writeln(""); } output.writeln(""); } override void visit(const ImportBind importBind) { if (importBind.right.type == tok!"") output.writeln(""); else output.writeln(""); } override void visit(const InExpression inExpression) { if (inExpression.negated) output.writeln(""); else output.writeln(""); output.writeln(""); visit(inExpression.left); output.writeln(""); output.writeln(""); visit(inExpression.right); output.writeln(""); output.writeln(""); } override void visit(const Initialize initialize) { if (initialize.statementNoCaseNoDefault is null) output.writeln(""); else { output.writeln(""); visit(initialize.statementNoCaseNoDefault); output.writeln(""); } } override void visit(const Initializer initializer) { if (initializer.nonVoidInitializer is null) output.writeln(""); else { output.writeln(""); visit(initializer.nonVoidInitializer); output.writeln(""); } } override void visit(const InterfaceDeclaration interfaceDec) { output.writeln(""); writeName(interfaceDec.name.text); writeDdoc(interfaceDec.comment); interfaceDec.accept(this); output.writeln(""); } override void visit(const Invariant invariant_) { output.writeln(""); writeDdoc(invariant_.comment); invariant_.accept(this); output.writeln(""); } override void visit(const IsExpression isExpression) { output.writeln(""); visit(isExpression.type); if (isExpression.identifier.type != tok!"") visit(isExpression.identifier); if (isExpression.typeSpecialization !is null) { if (isExpression.equalsOrColon == tok!":") output.writeln(""); else output.writeln(""); visit(isExpression.typeSpecialization); if (isExpression.templateParameterList !is null) visit(isExpression.templateParameterList); } output.writeln(""); } override void visit(const KeyValuePair keyValuePair) { output.writeln(""); output.writeln(""); visit(keyValuePair.key); output.writeln(""); output.writeln(""); visit(keyValuePair.value); output.writeln(""); output.writeln(""); } override void visit(const LabeledStatement labeledStatement) { output.writeln(""); if (labeledStatement.declarationOrStatement !is null) visit(labeledStatement.declarationOrStatement); output.writeln(""); } override void visit(const LinkageAttribute linkageAttribute) { if (linkageAttribute.hasPlusPlus) { output.write(""); } else if (linkageAttribute.classOrStruct == tok!"class") output.writeln(" mangleAs=\"class\"/>"); else if (linkageAttribute.classOrStruct == tok!"struct") output.writeln(" mangleAs=\"struct\"/>"); else output.writeln("/>"); } else if (linkageAttribute.identifier.text == "Objective") output.writeln(""); else output.writeln(""); } override void visit(const MemberFunctionAttribute memberFunctionAttribute) { output.writeln(""); if (memberFunctionAttribute.atAttribute is null) output.writeln(str(memberFunctionAttribute.tokenType)); else memberFunctionAttribute.accept(this); output.writeln(""); } override void visit(const Module module_) { output.writeln(""); output.writeln(""); module_.accept(this); output.writeln(""); } override void visit(const MulExpression mulExpression) { output.writeln(""); output.writeln(""); visit(mulExpression.left); output.writeln(""); if (mulExpression.right !is null) { output.writeln(""); visit(mulExpression.right); output.writeln(""); } output.writeln(""); } override void visit(const OrOrExpression orOrExpression) { output.writeln(""); output.writeln(""); visit(orOrExpression.left); output.writeln(""); if (orOrExpression.right !is null) { output.writeln(""); visit(orOrExpression.right); output.writeln(""); } output.writeln(""); } override void visit(const ParameterAttribute pa) { output.writeln(""); if (pa.atAttribute) visit(pa.atAttribute); else writeln(str(pa.idType)); output.writeln(""); } override void visit(const Parameter param) { output.writeln(""); if (param.name.type == tok!"identifier") writeName(param.name.text); param.accept(this); if (param.vararg) output.writeln(""); output.writeln(""); } override void visit(const PowExpression powExpression) { output.writeln(""); output.writeln(""); visit(powExpression.left); output.writeln(""); if (powExpression.right !is null) { output.writeln(""); visit(powExpression.right); output.writeln(""); } output.writeln(""); } override void visit(const RelExpression relExpression) { output.writeln(""); output.writeln(""); visit(relExpression.left); output.writeln(""); output.writeln(""); visit(relExpression.right); output.writeln(""); output.writeln(""); } override void visit(const ReturnStatement returnStatement) { if (returnStatement.expression is null) output.writeln(""); else { output.writeln(""); returnStatement.accept(this); output.writeln(""); } } override void visit(const ShiftExpression shiftExpression) { output.writeln(""); output.writeln(""); visit(shiftExpression.left); output.writeln(""); output.writeln(""); visit(shiftExpression.right); output.writeln(""); output.writeln(""); } override void visit(const SingleImport singleImport) { if (singleImport.rename.type == tok!"") output.writeln(""); else output.writeln(""); visit(singleImport.identifierChain); output.writeln(""); } override void visit(const StructDeclaration structDec) { output.writeln(""); writeName(structDec.name.text); writeDdoc(structDec.comment); structDec.accept(this); output.writeln(""); } override void visit(const TemplateAliasParameter templateAliasParameter) { output.writeln(""); if (templateAliasParameter.type !is null) visit(templateAliasParameter.type); visit(templateAliasParameter.identifier); if (templateAliasParameter.colonExpression !is null) { output.writeln(""); visit(templateAliasParameter.colonExpression); output.writeln(""); } else if (templateAliasParameter.colonType !is null) { output.writeln(""); visit(templateAliasParameter.colonType); output.writeln(""); } if (templateAliasParameter.assignExpression !is null) { output.writeln(""); visit(templateAliasParameter.assignExpression); output.writeln(""); } else if (templateAliasParameter.assignType !is null) { output.writeln(""); visit(templateAliasParameter.assignType); output.writeln(""); } output.writeln(""); } override void visit(const TemplateDeclaration templateDeclaration) { writeDdoc(templateDeclaration.comment); output.writeln(""); writeName(templateDeclaration.name.text); visit(templateDeclaration.templateParameters); if (templateDeclaration.constraint !is null) visit(templateDeclaration.constraint); foreach (dec; templateDeclaration.declarations) { if (dec !is null) visit(dec); } output.writeln(""); } override void visit(const Token token) { string tagName; switch (token.type) { case tok!"": return; case tok!"identifier": tagName = "identifier"; break; case tok!"doubleLiteral": tagName = "doubleLiteral"; break; case tok!"idoubleLiteral": tagName = "idoubleLiteral"; break; case tok!"floatLiteral": tagName = "floatLiteral"; break; case tok!"ifloatLiteral": tagName = "ifloatLiteral"; break; case tok!"intLiteral": tagName = "intLiteral"; break; case tok!"uintLiteral": tagName = "uintLiteral"; break; case tok!"longLiteral": tagName = "longLiteral"; break; case tok!"ulongLiteral": tagName = "ulongLiteral"; break; case tok!"realLiteral": tagName = "realLiteral"; break; case tok!"irealLiteral": tagName = "irealLiteral"; break; case tok!"characterLiteral": tagName = "characterLiteral"; break; case tok!"stringLiteral": tagName = "stringLiteral"; break; case tok!"dstringLiteral": tagName = "dstringLiteral"; break; case tok!"wstringLiteral": tagName = "wstringLiteral"; break; case tok!"scriptLine": tagName = "scriptLine"; break; case tok!"$": output.writeln(""); return; case tok!".": output.writeln(""); return; default: output.writeln("<", str(token.type), "/>"); return; } output.writeln("<", tagName, ">", xmlEscape(token.text), ""); } override void visit(const Type type) { auto app = appender!string(); auto formatter = new Formatter!(typeof(app))(app); formatter.format(type); output.writeln(""); type.accept(this); output.writeln(""); } override void visit(const Type2 type2) { if (type2.builtinType != tok!"") { output.writeln("", str(type2.builtinType), ""); if (type2.typeIdentifierPart !is null) visit(type2.typeIdentifierPart); } else { output.writeln(""); type2.accept(this); output.writeln(""); } } override void visit(const TypeSuffix typeSuffix) { if (typeSuffix.star != tok!"") output.writeln(""); else if (typeSuffix.array) { if (typeSuffix.low is null && typeSuffix.type is null) output.writeln(""); else { if (typeSuffix.low is null) { output.writeln(""); visit(typeSuffix.type); output.writeln(""); } else { output.writeln(""); if (typeSuffix.high !is null) { output.writeln(""); visit(typeSuffix.low); output.writeln(""); output.writeln(""); visit(typeSuffix.high); output.writeln(""); } else visit(typeSuffix.low); output.writeln(""); } } } else { visit(typeSuffix.delegateOrFunction); visit(typeSuffix.parameters); foreach (attr; typeSuffix.memberFunctionAttributes) { if (attr !is null) visit(attr); } } } override void visit(const UnaryExpression unaryExpression) { output.writeln(""); if (unaryExpression.prefix != tok!"") { output.writeln("", xmlEscape(str(unaryExpression.prefix.type)), ""); unaryExpression.unaryExpression.accept(this); } else { if (unaryExpression.suffix != tok!"") { assert(unaryExpression.suffix.text == ""); unaryExpression.unaryExpression.accept(this); output.writeln("", str(unaryExpression.suffix.type), ""); } else unaryExpression.accept(this); } output.writeln(""); } override void visit(const UnionDeclaration unionDeclaration) { output.writeln(""); if (unionDeclaration.name != tok!"") writeName(unionDeclaration.name.text); if (unionDeclaration.templateParameters !is null) visit(unionDeclaration.templateParameters); if (unionDeclaration.constraint !is null) visit(unionDeclaration.constraint); if (unionDeclaration.structBody !is null) visit(unionDeclaration.structBody); output.writeln(""); } override void visit(const Unittest unittest_) { output.writeln(""); unittest_.accept(this); output.writeln(""); } override void visit(const VariableDeclaration variableDeclaration) { output.writeln(""); writeDdoc(variableDeclaration.comment); variableDeclaration.accept(this); output.writeln(""); } override void visit(const XorExpression xorExpression) { output.writeln(""); output.writeln(""); visit(xorExpression.left); output.writeln(""); if (xorExpression.right !is null) { output.writeln(""); visit(xorExpression.right); output.writeln(""); } output.writeln(""); } override void visit(const Index index) { output.writeln(""); if (index.high) { output.writeln(""); visit(index.low); output.writeln(""); output.writeln(""); visit(index.high); output.writeln(""); } else visit(index.low); output.writeln(""); } // dfmt off override void visit(const AliasInitializer aliasInitializer) { mixin (tagAndAccept!"aliasInitializer"); } override void visit(const AliasThisDeclaration aliasThisDeclaration) { mixin (tagAndAccept!"aliasThisDeclaration"); } override void visit(const AnonymousEnumDeclaration anonymousEnumDeclaration) { mixin (tagAndAccept!"anonymousEnumDeclaration"); } override void visit(const ArgumentList argumentList) { mixin (tagAndAccept!"argumentList"); } override void visit(const Arguments arguments) { mixin (tagAndAccept!"arguments"); } override void visit(const ArrayInitializer arrayInitializer) { mixin (tagAndAccept!"arrayInitializer"); } override void visit(const ArrayLiteral arrayLiteral) { mixin (tagAndAccept!"arrayLiteral"); } override void visit(const ArrayMemberInitialization arrayMemberInitialization) { mixin (tagAndAccept!"arrayMemberInitialization"); } override void visit(const AsmAddExp asmAddExp) { mixin (tagAndAccept!"asmAddExp"); } override void visit(const AsmAndExp asmAndExp) { mixin (tagAndAccept!"asmAndExp"); } override void visit(const AsmBrExp asmBrExp) { mixin (tagAndAccept!"asmBrExp"); } override void visit(const AsmEqualExp asmEqualExp) { mixin (tagAndAccept!"asmEqualExp"); } override void visit(const AsmExp asmExp) { mixin (tagAndAccept!"asmExp"); } override void visit(const AsmLogAndExp asmLogAndExp) { mixin (tagAndAccept!"asmLogAndExp"); } override void visit(const AsmLogOrExp asmLogOrExp) { mixin (tagAndAccept!"asmLogOrExp"); } override void visit(const AsmMulExp asmMulExp) { mixin (tagAndAccept!"asmMulExp"); } override void visit(const AsmOrExp asmOrExp) { mixin (tagAndAccept!"asmOrExp"); } override void visit(const AsmPrimaryExp asmPrimaryExp) { mixin (tagAndAccept!"asmPrimaryExp"); } override void visit(const AsmRelExp asmRelExp) { mixin (tagAndAccept!"asmRelExp"); } override void visit(const AsmShiftExp asmShiftExp) { mixin (tagAndAccept!"asmShiftExp"); } override void visit(const AsmStatement asmStatement) { mixin (tagAndAccept!"asmStatement"); } override void visit(const AsmTypePrefix asmTypePrefix) { mixin (tagAndAccept!"asmTypePrefix"); } override void visit(const AsmUnaExp asmUnaExp) { mixin (tagAndAccept!"asmUnaExp"); } override void visit(const AsmXorExp asmXorExp) { mixin (tagAndAccept!"asmXorExp"); } override void visit(const AssocArrayLiteral assocArrayLiteral) { mixin (tagAndAccept!"assocArrayLiteral"); } override void visit(const AttributeDeclaration attributeDeclaration) { mixin (tagAndAccept!"attributeDeclaration"); } override void visit(const BaseClass baseClass) { mixin (tagAndAccept!"baseClass"); } override void visit(const BaseClassList baseClassList) { mixin (tagAndAccept!"baseClassList"); } override void visit(const BlockStatement blockStatement) { mixin (tagAndAccept!"blockStatement"); } override void visit(const BodyStatement bodyStatement) { mixin (tagAndAccept!"bodyStatement"); } override void visit(const CaseStatement caseStatement) { mixin (tagAndAccept!"caseStatement"); } override void visit(const CastExpression castExpression) { mixin (tagAndAccept!"castExpression"); } override void visit(const CastQualifier castQualifier) { mixin (tagAndAccept!"castQualifier"); } override void visit(const Catches catches) { mixin (tagAndAccept!"catches"); } override void visit(const CmpExpression cmpExpression) { mixin (tagAndAccept!"cmpExpression"); } override void visit(const CompileCondition compileCondition) { mixin (tagAndAccept!"compileCondition"); } override void visit(const Constraint constraint) { mixin (tagAndAccept!"constraint"); } override void visit(const Constructor constructor) { mixin (tagAndAccept!"constructor"); } override void visit(const Declaration declaration) { mixin (tagAndAccept!"declaration"); } override void visit(const DeclarationOrStatement declarationOrStatement) { mixin (tagAndAccept!"declarationOrStatement"); } override void visit(const DeclarationsAndStatements declarationsAndStatements) { mixin (tagAndAccept!"declarationsAndStatements"); } override void visit(const DeclaratorIdentifierList declaratorIdentifierList) { mixin (tagAndAccept!"declaratorIdentifierList"); } override void visit(const DefaultStatement defaultStatement) { mixin (tagAndAccept!"defaultStatement"); } override void visit(const DeleteExpression deleteExpression) { mixin (tagAndAccept!"deleteExpression"); } override void visit(const DeleteStatement deleteStatement) { mixin (tagAndAccept!"deleteStatement"); } override void visit(const Destructor destructor) { mixin (tagAndAccept!"destructor"); } override void visit(const DoStatement doStatement) { mixin (tagAndAccept!"doStatement"); } override void visit(const EnumBody enumBody) { mixin (tagAndAccept!"enumBody"); } override void visit(const EponymousTemplateDeclaration eponymousTemplateDeclaration) { mixin (tagAndAccept!"eponymousTemplateDeclaration"); } override void visit(const Expression expression) { mixin (tagAndAccept!"expression"); } override void visit(const ExpressionStatement expressionStatement) { mixin (tagAndAccept!"expressionStatement"); } override void visit(const FinalSwitchStatement finalSwitchStatement) { mixin (tagAndAccept!"finalSwitchStatement"); } override void visit(const ForeachTypeList foreachTypeList) { mixin (tagAndAccept!"foreachTypeList"); } override void visit(const FunctionAttribute functionAttribute) { mixin (tagAndAccept!"functionAttribute"); } override void visit(const FunctionBody functionBody) { mixin (tagAndAccept!"functionBody"); } override void visit(const FunctionCallExpression functionCallExpression) { mixin (tagAndAccept!"functionCallExpression"); } override void visit(const IdentifierChain identifierChain) { mixin (tagAndAccept!"identifierChain"); } override void visit(const IdentifierOrTemplateChain identifierOrTemplateChain) { mixin (tagAndAccept!"identifierOrTemplateChain"); } override void visit(const IdentifierOrTemplateInstance identifierOrTemplateInstance) { mixin (tagAndAccept!"identifierOrTemplateInstance"); } override void visit(const ImportBindings importBindings) { mixin (tagAndAccept!"importBindings"); } override void visit(const ImportDeclaration importDeclaration) { mixin (tagAndAccept!"importDeclaration"); } override void visit(const ImportExpression importExpression) { mixin (tagAndAccept!"importExpression"); } override void visit(const IndexExpression indexExpression) { mixin (tagAndAccept!"indexExpression"); } override void visit(const InStatement inStatement) { mixin (tagAndAccept!"inStatement"); } override void visit(const KeyValuePairs keyValuePairs) { mixin (tagAndAccept!"keyValuePairs"); } override void visit(const MixinExpression mixinExpression) { mixin (tagAndAccept!"mixinExpression"); } override void visit(const MixinTemplateDeclaration mixinTemplateDeclaration) { mixin (tagAndAccept!"mixinTemplateDeclaration"); } override void visit(const MixinTemplateName mixinTemplateName) { mixin (tagAndAccept!"mixinTemplateName"); } override void visit(const ModuleDeclaration moduleDeclaration) { mixin (tagAndAccept!"moduleDeclaration"); } override void visit(const LastCatch lastCatch) { mixin (tagAndAccept!"lastCatch"); } override void visit(const NewExpression newExpression) { mixin (tagAndAccept!"newExpression"); } override void visit(const NonVoidInitializer nonVoidInitializer) { mixin (tagAndAccept!"nonVoidInitializer"); } override void visit(const Operands operands) { mixin (tagAndAccept!"operands"); } override void visit(const OrExpression orExpression) { mixin (tagAndAccept!"orExpression"); } override void visit(const OutStatement outStatement) { mixin (tagAndAccept!"outStatement"); } override void visit(const MixinDeclaration mixinDeclaration) { mixin (tagAndAccept!"mixinDeclaration"); } override void visit(const Parameters parameters) { mixin (tagAndAccept!"parameters"); } override void visit(const Postblit postblit) { mixin (tagAndAccept!"postblit"); } override void visit(const NewAnonClassExpression newAnonClassExpression) { mixin (tagAndAccept!"newAnonClassExpression"); } override void visit(const PragmaDeclaration pragmaDeclaration) { mixin (tagAndAccept!"pragmaDeclaration"); } override void visit(const PragmaExpression pragmaExpression) { mixin (tagAndAccept!"pragmaExpression"); } override void visit(const PrimaryExpression primaryExpression) { mixin (tagAndAccept!"primaryExpression"); } override void visit(const Register register) { mixin (tagAndAccept!"register"); } override void visit(const ScopeGuardStatement scopeGuardStatement) { mixin (tagAndAccept!"scopeGuardStatement"); } override void visit(const SharedStaticConstructor sharedStaticConstructor) { mixin (tagAndAccept!"sharedStaticConstructor"); } override void visit(const SharedStaticDestructor sharedStaticDestructor) { mixin (tagAndAccept!"sharedStaticDestructor"); } override void visit(const StatementNoCaseNoDefault statementNoCaseNoDefault) { mixin (tagAndAccept!"statementNoCaseNoDefault"); } override void visit(const StaticAssertDeclaration staticAssertDeclaration) { mixin (tagAndAccept!"staticAssertDeclaration"); } override void visit(const StaticAssertStatement staticAssertStatement) { mixin (tagAndAccept!"staticAssertStatement"); } override void visit(const StaticConstructor staticConstructor) { mixin (tagAndAccept!"staticConstructor"); } override void visit(const StaticDestructor staticDestructor) { mixin (tagAndAccept!"staticDestructor"); } override void visit(const StaticIfCondition staticIfCondition) { mixin (tagAndAccept!"staticIfCondition"); } override void visit(const StorageClass storageClass) { mixin (tagAndAccept!"storageClass"); } override void visit(const StructBody structBody) { mixin (tagAndAccept!"structBody"); } override void visit(const StructInitializer structInitializer) { mixin (tagAndAccept!"structInitializer"); } override void visit(const StructMemberInitializers structMemberInitializers) { mixin (tagAndAccept!"structMemberInitializers"); } override void visit(const StructMemberInitializer structMemberInitializer) { mixin (tagAndAccept!"structMemberInitializer"); } override void visit(const SwitchStatement switchStatement) { mixin (tagAndAccept!"switchStatement"); } override void visit(const Symbol symbol) { mixin (tagAndAccept!"symbol"); } override void visit(const SynchronizedStatement synchronizedStatement) { mixin (tagAndAccept!"synchronizedStatement"); } override void visit(const Statement statement) { mixin (tagAndAccept!"statement"); } override void visit(const TemplateArgumentList templateArgumentList) { mixin (tagAndAccept!"templateArgumentList"); } override void visit(const TemplateArguments templateArguments) { mixin (tagAndAccept!"templateArguments"); } override void visit(const TemplateArgument templateArgument) { mixin (tagAndAccept!"templateArgument"); } override void visit(const TemplateMixinExpression templateMixinExpression) { mixin (tagAndAccept!"templateMixinExpression"); } override void visit(const TemplateParameterList templateParameterList) { mixin (tagAndAccept!"templateParameterList"); } override void visit(const TemplateParameters templateParameters) { mixin (tagAndAccept!"templateParameters"); } override void visit(const TemplateParameter templateParameter) { mixin (tagAndAccept!"templateParameter"); } override void visit(const TemplateSingleArgument templateSingleArgument) { mixin (tagAndAccept!"templateSingleArgument"); } override void visit(const TemplateThisParameter templateThisParameter) { mixin (tagAndAccept!"templateThisParameter"); } override void visit(const TemplateTupleParameter templateTupleParameter) { mixin (tagAndAccept!"templateTupleParameter"); } override void visit(const TemplateTypeParameter templateTypeParameter) { mixin (tagAndAccept!"templateTypeParameter"); } override void visit(const TemplateValueParameterDefault templateValueParameterDefault) { mixin (tagAndAccept!"templateValueParameterDefault"); } override void visit(const TemplateValueParameter templateValueParameter) { mixin (tagAndAccept!"templateValueParameter"); } override void visit(const TernaryExpression ternaryExpression) { mixin (tagAndAccept!"ternaryExpression"); } override void visit(const TypeIdentifierPart typeIdentifierPart) { mixin (tagAndAccept!"typeIdentifierPart"); } override void visit(const ThrowStatement throwStatement) { mixin (tagAndAccept!"throwStatement"); } override void visit(const TryStatement tryStatement) { mixin (tagAndAccept!"tryStatement"); } override void visit(const TemplateInstance templateInstance) { mixin (tagAndAccept!"templateInstance"); } override void visit(const TypeofExpression typeofExpression) { mixin (tagAndAccept!"typeofExpression"); } override void visit(const TypeSpecialization typeSpecialization) { mixin (tagAndAccept!"typeSpecialization"); } override void visit(const TraitsExpression traitsExpression) { mixin (tagAndAccept!"traitsExpression"); } override void visit(const Vector vector) { mixin (tagAndAccept!"vector"); } override void visit(const VersionCondition versionCondition) { mixin (tagAndAccept!"versionCondition"); } override void visit(const VersionSpecification versionSpecification) { mixin (tagAndAccept!"versionSpecification"); } override void visit(const WhileStatement whileStatement) { mixin (tagAndAccept!"whileStatement"); } override void visit(const WithStatement withStatement) { mixin (tagAndAccept!"withStatement"); } override void visit(const TypeidExpression typeidExpression) { mixin (tagAndAccept!"typeidExpression"); } // dfmt on alias visit = ASTVisitor.visit; private static string xmlEscape(string s) { return s.translate(['<' : "<", '>' : ">", '&' : "&"]); } private static string xmlAttributeEscape(string s) { return s.translate(['<' : "<", '>' : ">", '&' : "&", '\"' : """, '\'' : "'"]); } private void writeName(string name) { output.write("", name, ""); } private void writeDdoc(string comment) { if (comment.ptr is null) return; output.writeln("", xmlEscape(comment), ""); } /** * File that output is written to. */ File output; } private: template tagAndAccept(string tagName) { immutable tagAndAccept = `output.writeln("<` ~ tagName ~ `>");` ~ tagName ~ `.accept(this);` ~ `output.writeln("");`; }