// Copyright Brian Schott (Sir Alaran) 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)
import stdx.d.lexer;
import stdx.d.ast;
import std.stdio;
import std.string;
import std.array;
import formatter;
template tagAndAccept(string tagName)
{
immutable tagAndAccept = `output.writeln("<` ~ tagName ~ `>");`
~ tagName ~ `.accept(this);`
~ `output.writeln("` ~ tagName ~ `>");`;
}
class XMLPrinter : ASTVisitor
{
override void visit(AddExpression addExpression)
{
output.writeln("");
output.writeln("");
addExpression.left.accept(this);
output.writeln("");
if (addExpression.right !is null)
{
output.writeln("");
addExpression.right.accept(this);
output.writeln("");
}
output.writeln("");
}
override void visit(AliasDeclaration aliasDeclaration)
{
mixin (tagAndAccept!"aliasDeclaration");
}
override void visit(AliasInitializer aliasInitializer)
{
mixin (tagAndAccept!"aliasInitializer");
}
override void visit(AliasThisDeclaration aliasThisDeclaration)
{
mixin (tagAndAccept!"aliasThisDeclaration");
}
override void visit(AlignAttribute alignAttribute)
{
output.writeln("");
}
override void visit(AndAndExpression andAndExpression)
{
output.writeln("");
output.writeln("");
andAndExpression.left.accept(this);
output.writeln("");
if (andAndExpression.right !is null)
{
output.writeln("");
andAndExpression.right.accept(this);
output.writeln("");
}
output.writeln("");
}
override void visit(AndExpression andExpression)
{
output.writeln("");
output.writeln("");
andExpression.left.accept(this);
output.writeln("");
if (andExpression.right !is null)
{
output.writeln("");
andExpression.right.accept(this);
output.writeln("");
}
output.writeln("");
}
override void visit(ArgumentList argumentList)
{
mixin (tagAndAccept!"argumentList");
}
override void visit(Arguments arguments)
{
mixin (tagAndAccept!"arguments");
}
override void visit(ArrayInitializer arrayInitializer)
{
mixin (tagAndAccept!"arrayInitializer");
}
override void visit(ArrayLiteral arrayLiteral)
{
mixin (tagAndAccept!"arrayLiteral");
}
override void visit(ArrayMemberInitialization arrayMemberInitialization)
{
mixin (tagAndAccept!"arrayMemberInitialization");
}
override void visit(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(AssignExpression assignExpression)
{
if (assignExpression.assignExpression is null)
output.writeln("");
else
output.writeln("");
assignExpression.accept(this);
output.writeln("");
}
override void visit(AssocArrayLiteral assocArrayLiteral)
{
mixin (tagAndAccept!"assocArrayLiteral");
}
override void visit(AtAttribute atAttribute)
{
output.writeln("");
if (atAttribute.identifier.type == TokenType.invalid)
atAttribute.accept(this);
else
output.writeln("", atAttribute.identifier.value, "");
output.writeln("");
}
override void visit(Attribute attribute)
{
output.writeln("");
if (attribute.attribute == TokenType.invalid)
attribute.accept(this);
else
output.writeln(getTokenValue(attribute.attribute));
output.writeln("");
}
override void visit(AttributeDeclaration attributeDeclaration)
{
assert (attributeDeclaration !is null);
mixin (tagAndAccept!"attributeDeclaration");
}
override void visit(AutoDeclaration autoDec)
{
output.writeln("");
for (size_t i = 0; i < autoDec.identifiers.length; i++)
{
output.writeln("- ");
output.writeln("",
autoDec.identifiers[i].value, "");
visit(autoDec.initializers[i]);
output.writeln("
");
}
output.writeln("");
}
override void visit(BlockStatement blockStatement)
{
output.writeln("");
blockStatement.accept(this);
output.writeln("");
}
override void visit(BodyStatement bodyStatement)
{
output.writeln("");
bodyStatement.accept(this);
output.writeln("");
}
override void visit(BreakStatement breakStatement)
{
if (breakStatement.label.type == TokenType.invalid)
output.writeln("");
else
output.writeln("");
}
override void visit(BaseClass baseClass)
{
mixin (tagAndAccept!"baseClass");
}
override void visit(BaseClassList baseClassList)
{
mixin (tagAndAccept!"baseClassList");
}
override void visit(CaseRangeStatement caseRangeStatement)
{
output.writeln("");
output.writeln("");
visit(caseRangeStatement.low);
output.writeln("");
output.writeln("");
visit(caseRangeStatement.high);
output.writeln("");
if (caseRangeStatement.declarationsAndStatements !is null)
visit(caseRangeStatement.declarationsAndStatements);
output.writeln("");
}
override void visit(CaseStatement caseStatement)
{
mixin (tagAndAccept!"caseStatement");
}
override void visit(CastExpression castExpression)
{
mixin (tagAndAccept!"castExpression");
}
override void visit(CastQualifier castQualifier)
{
mixin (tagAndAccept!"castQualifier");
}
override void visit(Catches catches)
{
mixin (tagAndAccept!"catches");
}
override void visit(Catch catch_)
{
output.writeln("");
catch_.accept(this);
output.writeln("");
}
override void visit(ClassDeclaration classDec)
{
output.writeln("");
output.writeln("", classDec.name.value, "");
classDec.accept(this);
output.writeln("");
}
override void visit(CmpExpression cmpExpression)
{
mixin (tagAndAccept!"cmpExpression");
}
override void visit(CompileCondition compileCondition)
{
mixin (tagAndAccept!"compileCondition");
}
override void visit(ConditionalDeclaration conditionalDeclaration)
{
output.writeln("");
visit(conditionalDeclaration.compileCondition);
output.writeln("");
foreach (dec; conditionalDeclaration.trueDeclarations)
visit(dec);
output.writeln("");
if (conditionalDeclaration.falseDeclaration !is null)
{
output.writeln("");
visit(conditionalDeclaration.falseDeclaration);
output.writeln("");
}
output.writeln("");
}
override void visit(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(Constraint constraint)
{
output.writeln("");
constraint.accept(this);
output.writeln("");
}
override void visit(Constructor constructor)
{
mixin (tagAndAccept!"constructor");
}
override void visit(ContinueStatement continueStatement)
{
if (continueStatement.label.type == TokenType.invalid)
output.writeln("");
else
output.writeln("");
}
override void visit(DebugCondition debugCondition)
{
if (debugCondition.identifierOrInteger.type == TokenType.invalid)
output.writeln("");
else
output.writeln("");
}
override void visit(DebugSpecification debugSpecification)
{
if (debugSpecification.identifierOrInteger.type == TokenType.invalid)
output.writeln("");
else
output.writeln("");
}
override void visit(Declaration declaration)
{
mixin (tagAndAccept!"declaration");
}
override void visit(DeclarationsAndStatements declarationsAndStatements)
{
mixin (tagAndAccept!"declarationsAndStatements");
}
override void visit(DeclarationOrStatement declarationOrStatement)
{
mixin (tagAndAccept!"declarationOrStatement");
}
override void visit(Declarator declarator)
{
output.writeln("");
output.writeln("", declarator.name.value, "");
declarator.accept(this);
output.writeln("");
}
override void visit(DefaultStatement defaultStatement)
{
mixin (tagAndAccept!"defaultStatement");
}
override void visit(DeleteExpression deleteExpression)
{
mixin (tagAndAccept!"deleteExpression");
}
override void visit(DeleteStatement deleteStatement)
{
mixin (tagAndAccept!"deleteStatement");
}
override void visit(Deprecated deprecated_)
{
if (deprecated_.assignExpression !is null)
{
output.writeln("");
deprecated_.accept(this);
output.writeln("");
}
else
output.writeln("");
}
override void visit(Destructor destructor)
{
mixin (tagAndAccept!"destructor");
}
override void visit(DoStatement doStatement)
{
mixin (tagAndAccept!"doStatement");
}
override void visit(EnumBody enumBody)
{
mixin (tagAndAccept!"enumBody");
}
override void visit(EnumDeclaration enumDec)
{
output.writeln("");
if (enumDec.name.type == TokenType.identifier)
output.writeln("", enumDec.name.value, "");
enumDec.accept(this);
output.writeln("");
}
override void visit(EnumMember enumMem)
{
output.writeln("");
enumMem.accept(this);
output.writeln("");
}
override void visit(EqualExpression equalExpression)
{
output.writeln("");
output.writeln("");
visit(equalExpression.left);
output.writeln("");
output.writeln("");
visit(equalExpression.right);
output.writeln("");
output.writeln("");
}
override void visit(Expression expression)
{
output.writeln("");
expression.accept(this);
output.writeln("");
}
override void visit(ExpressionStatement expressionStatement)
{
output.writeln("");
expressionStatement.accept(this);
output.writeln("");
}
override void visit(FinalSwitchStatement finalSwitchStatement)
{
output.writeln("");
finalSwitchStatement.accept(this);
output.writeln("");
}
override void visit(Finally finally_)
{
output.writeln("");
finally_.accept(this);
output.writeln("");
}
override void visit(ForStatement forStatement)
{
output.writeln("");
if (forStatement.declarationOrStatement !is null)
{
output.writeln("");
visit(forStatement.declarationOrStatement);
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("");
}
visit(forStatement.statementNoCaseNoDefault);
output.writeln("");
}
override void visit(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(ForeachType foreachType)
{
output.writeln("");
foreach (constructor; foreachType.typeConstructors)
{
output.writeln("", getTokenValue(constructor), "");
}
if (foreachType.type !is null)
visit(foreachType.type);
visit(foreachType.identifier);
output.writeln("");
}
override void visit(ForeachTypeList foreachTypeList)
{
mixin (tagAndAccept!"foreachTypeList");
}
override void visit(FunctionAttribute functionAttribute)
{
mixin (tagAndAccept!"functionAttribute");
}
override void visit(FunctionBody functionBody)
{
mixin (tagAndAccept!"functionBody");
}
override void visit(FunctionCallExpression functionCallExpression)
{
mixin (tagAndAccept!"functionCallExpression");
}
override void visit(FunctionCallStatement functionCallStatement)
{
mixin (tagAndAccept!"functionCallStatement");
}
override void visit(FunctionDeclaration functionDec)
{
output.writeln("");
output.writeln("", functionDec.name.value, "");
if (functionDec.hasAuto)
output.writeln("");
if (functionDec.hasRef)
output.writeln("");
functionDec.accept(this);
output.writeln("");
}
override void visit(FunctionLiteralExpression functionLiteralExpression)
{
output.writeln("");
functionLiteralExpression.accept(this);
output.writeln("");
}
override void visit(GotoStatement gotoStatement)
{
if (gotoStatement.label.type == TokenType.default_)
output.writeln("");
else if (gotoStatement.label.type == TokenType.identifier)
output.writeln("");
else
{
output.writeln("");
output.writeln("");
visit(gotoStatement.expression);
output.writeln("");
output.writeln("");
}
}
override void visit(IdentifierChain identifierChain)
{
mixin (tagAndAccept!"identifierChain");
}
override void visit(IdentifierList identifierList)
{
mixin (tagAndAccept!"identifierList");
}
override void visit(IdentifierOrTemplateChain identifierOrTemplateChain)
{
mixin (tagAndAccept!"identifierOrTemplateChain");
}
override void visit(IdentifierOrTemplateInstance identifierOrTemplateInstance)
{
mixin (tagAndAccept!"identifierOrTemplateInstance");
}
override void visit(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(IfStatement ifStatement)
{
output.writeln("");
output.writeln("");
if (ifStatement.identifier.type != TokenType.invalid)
{
if (ifStatement.type is null)
output.writeln("");
else
visit(ifStatement.type);
visit(ifStatement.identifier);
}
visit(ifStatement.expression);
output.writeln("");
output.writeln("");
visit(ifStatement.thenStatement);
output.writeln("");
if (ifStatement.elseStatement !is null)
{
output.writeln("");
visit(ifStatement.elseStatement);
output.writeln("");
}
output.writeln("");
}
override void visit(ImportBind importBind)
{
if (importBind.right.type == TokenType.invalid)
output.writeln("");
else
output.writeln("");
}
override void visit(ImportBindings importBindings)
{
mixin (tagAndAccept!"importBindings");
}
override void visit(ImportDeclaration importDeclaration)
{
mixin (tagAndAccept!"importDeclaration");
}
override void visit(ImportExpression importExpression)
{
mixin (tagAndAccept!"importExpression");
}
override void visit(IndexExpression indexExpression)
{
mixin (tagAndAccept!"indexExpression");
}
override void visit(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(InStatement inStatement)
{
mixin (tagAndAccept!"inStatement");
}
override void visit(Initialize initialize)
{
if (initialize.statementNoCaseNoDefault is null)
output.writeln("");
else
{
output.writeln("");
visit(initialize.statementNoCaseNoDefault);
output.writeln("");
}
}
override void visit(Initializer initializer)
{
if (initializer.nonVoidInitializer is null)
output.writeln("");
else
{
output.writeln("");
visit(initializer.nonVoidInitializer);
output.writeln("");
}
}
override void visit(InterfaceDeclaration interfaceDec)
{
output.writeln("");
output.writeln("", interfaceDec.name.value, "");
interfaceDec.accept(this);
output.writeln("");
}
override void visit(Invariant invariant_)
{
output.writeln("");
invariant_.accept(this);
output.writeln("");
}
override void visit(IsExpression isExpression)
{
output.writeln("");
visit(isExpression.type);
if (isExpression.identifier.type != TokenType.invalid)
visit(isExpression.identifier);
if (isExpression.typeSpecialization !is null)
{
if (isExpression.equalsOrColon == TokenType.colon)
output.writeln("");
else
output.writeln("");
visit(isExpression.typeSpecialization);
if (isExpression.templateParameterList !is null)
visit(isExpression.templateParameterList);
}
output.writeln("");
}
override void visit(KeyValuePair keyValuePair)
{
output.writeln("");
output.writeln("");
visit(keyValuePair.key);
output.writeln("");
output.writeln("");
visit(keyValuePair.value);
output.writeln("");
output.writeln("");
}
override void visit(KeyValuePairs keyValuePairs)
{
mixin (tagAndAccept!"keyValuePairs");
}
override void visit (LabeledStatement labeledStatement)
{
output.writeln("");
visit(labeledStatement.declarationOrStatement);
output.writeln("");
}
override void visit(LambdaExpression lambdaExpression)
{
output.writeln("");
if (lambdaExpression.functionType == TokenType.function_)
output.writeln("");
if (lambdaExpression.functionType == TokenType.delegate_)
output.writeln("");
lambdaExpression.accept(this);
output.writeln("");
}
override void visit(LastCatch lastCatch)
{
mixin (tagAndAccept!"lastCatch");
}
override void visit(LinkageAttribute linkageAttribute)
{
if (linkageAttribute.hasPlusPlus)
output.writeln("");
else
output.writeln("");
}
override void visit(MemberFunctionAttribute memberFunctionAttribute)
{
output.writeln("");
if (memberFunctionAttribute.atAttribute is null)
output.writeln(getTokenValue(memberFunctionAttribute.tokenType));
else
memberFunctionAttribute.accept(this);
output.writeln("");
}
override void visit(MixinDeclaration mixinDeclaration)
{
mixin (tagAndAccept!"mixinDeclaration");
}
override void visit(MixinExpression mixinExpression)
{
mixin (tagAndAccept!"mixinExpression");
}
override void visit(MixinTemplateDeclaration mixinTemplateDeclaration)
{
mixin (tagAndAccept!"mixinTemplateDeclaration");
}
override void visit(MixinTemplateName mixinTemplateName)
{
mixin (tagAndAccept!"mixinTemplateName");
}
override void visit(Module module_)
{
output.writeln("");
module_.accept(this);
output.writeln("");
}
override void visit(ModuleDeclaration moduleDeclaration)
{
mixin (tagAndAccept!"moduleDeclaration");
}
override void visit(MulExpression mulExpression)
{
output.writeln("");
output.writeln("");
mulExpression.left.accept(this);
output.writeln("");
if (mulExpression.right !is null)
{
output.writeln("");
mulExpression.right.accept(this);
output.writeln("");
}
output.writeln("");
}
override void visit(NewAnonClassExpression newAnonClassExpression)
{
mixin (tagAndAccept!"newAnonClassExpression");
}
override void visit(NewExpression newExpression)
{
mixin (tagAndAccept!"newExpression");
}
override void visit(StatementNoCaseNoDefault statementNoCaseNoDefault)
{
mixin (tagAndAccept!"statementNoCaseNoDefault");
}
override void visit(NonVoidInitializer nonVoidInitializer)
{
mixin (tagAndAccept!"nonVoidInitializer");
}
override void visit(OrExpression orExpression)
{
mixin (tagAndAccept!"orExpression");
}
override void visit(OrOrExpression orOrExpression)
{
mixin (tagAndAccept!"orOrExpression");
}
override void visit(OutStatement outStatement)
{
mixin (tagAndAccept!"outStatement");
}
override void visit(Parameter param)
{
output.writeln("");
if (param.name.type == TokenType.identifier)
output.writeln("", param.name.value, "");
foreach (attribute; param.parameterAttributes)
{
output.writeln("", getTokenValue(attribute), "");
}
param.accept(this);
if (param.vararg)
output.writeln("");
output.writeln("");
}
override void visit(Parameters parameters)
{
mixin (tagAndAccept!"parameters");
}
override void visit(Postblit postblit)
{
mixin (tagAndAccept!"postblit");
}
override void visit(PostIncDecExpression postIncDecExpression)
{
output.writeln("");
postIncDecExpression.accept(this);
output.writeln("");
}
override void visit(PowExpression powExpression)
{
output.writeln("");
output.writeln("");
powExpression.left.accept(this);
output.writeln("");
if (powExpression.right !is null)
{
output.writeln("");
powExpression.right.accept(this);
output.writeln("");
}
output.writeln("");
}
override void visit(PragmaDeclaration pragmaDeclaration)
{
mixin (tagAndAccept!"pragmaDeclaration");
}
override void visit(PragmaExpression pragmaExpression)
{
mixin (tagAndAccept!"pragmaExpression");
}
override void visit(PreIncDecExpression preIncDecExpression)
{
output.writeln("");
preIncDecExpression.accept(this);
output.writeln("");
}
override void visit(PrimaryExpression primaryExpression)
{
mixin (tagAndAccept!"primaryExpression");
}
// TODO: Register
override void visit(RelExpression relExpression)
{
output.writeln("");
output.writeln("");
visit(relExpression.left);
output.writeln("");
output.writeln("");
visit(relExpression.right);
output.writeln("");
output.writeln("");
}
override void visit(ReturnStatement returnStatement)
{
if (returnStatement.expression is null)
output.writeln("");
else
{
output.writeln("");
returnStatement.accept(this);
output.writeln("");
}
}
override void visit(ScopeGuardStatement scopeGuardStatement)
{
mixin (tagAndAccept!"scopeGuardStatement");
}
override void visit(SharedStaticConstructor sharedStaticConstructor)
{
mixin (tagAndAccept!"sharedStaticConstructor");
}
override void visit(SharedStaticDestructor sharedStaticDestructor)
{
mixin (tagAndAccept!"sharedStaticDestructor");
}
override void visit(ShiftExpression shiftExpression)
{
output.writeln("");
output.writeln("");
visit(shiftExpression.left);
output.writeln("");
output.writeln("");
visit(shiftExpression.right);
output.writeln("");
output.writeln("");
}
override void visit(SingleImport singleImport)
{
if (singleImport.rename.type == TokenType.invalid)
output.writeln("");
else
output.writeln("");
visit(singleImport.identifierChain);
output.writeln("");
}
override void visit(SliceExpression sliceExpression)
{
output.writeln("");
if (sliceExpression.unaryExpression is null)
{
output.writeln("");
}
override void visit(Statement statement)
{
mixin (tagAndAccept!"statement");
}
override void visit(StaticAssertDeclaration staticAssertDeclaration)
{
mixin (tagAndAccept!"staticAssertDeclaration");
}
override void visit(StaticAssertStatement staticAssertStatement)
{
mixin (tagAndAccept!"staticAssertStatement");
}
override void visit(StaticConstructor staticConstructor)
{
mixin (tagAndAccept!"staticConstructor");
}
override void visit(StaticDestructor staticDestructor)
{
mixin (tagAndAccept!"staticDestructor");
}
override void visit(StaticIfCondition staticIfCondition)
{
mixin (tagAndAccept!"staticIfCondition");
}
override void visit(StorageClass storageClass)
{
mixin (tagAndAccept!"storageClass");
}
override void visit(StructBody structBody)
{
mixin (tagAndAccept!"structBody");
}
override void visit(StructDeclaration structDec)
{
output.writeln("");
output.writeln("", structDec.name.value, "");
structDec.accept(this);
output.writeln("");
}
override void visit(StructInitializer structInitializer)
{
mixin (tagAndAccept!"structInitializer");
}
override void visit(StructMemberInitializer structMemberInitializer)
{
mixin (tagAndAccept!"structMemberInitializer");
}
override void visit(StructMemberInitializers structMemberInitializers)
{
mixin (tagAndAccept!"structMemberInitializers");
}
override void visit(SwitchStatement switchStatement)
{
mixin (tagAndAccept!"switchStatement");
}
override void visit(Symbol symbol)
{
mixin (tagAndAccept!"symbol");
}
override void visit(SynchronizedStatement synchronizedStatement)
{
mixin (tagAndAccept!"synchronizedStatement");
}
override void visit(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(TemplateArgument templateArgument)
{
mixin (tagAndAccept!"templateArgument");
}
override void visit(TemplateArgumentList templateArgumentList)
{
mixin (tagAndAccept!"templateArgumentList");
}
override void visit(TemplateArguments templateArguments)
{
mixin (tagAndAccept!"templateArguments");
}
override void visit (EponymousTemplateDeclaration eponymousTemplateDeclaration)
{
mixin (tagAndAccept!"eponymousTemplateDeclaration");
}
override void visit(TemplateDeclaration templateDeclaration)
{
if (templateDeclaration.eponymousTemplateDeclaration !is null)
{
output.writeln("");
visit(templateDeclaration.eponymousTemplateDeclaration);
output.writeln("");
return;
}
output.writeln("");
output.writeln("", templateDeclaration.name.value, "");
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(TemplateInstance templateInstance)
{
mixin (tagAndAccept!"templateInstance");
}
override void visit(TemplateMixinExpression templateMixinExpression)
{
mixin (tagAndAccept!"templateMixinExpression");
}
override void visit(TemplateParameter templateParameter)
{
mixin (tagAndAccept!"templateParameter");
}
override void visit(TemplateParameterList templateParameterList)
{
mixin (tagAndAccept!"templateParameterList");
}
override void visit(TemplateParameters templateParameters)
{
mixin (tagAndAccept!"templateParameters");
}
override void visit(TemplateSingleArgument templateSingleArgument)
{
mixin (tagAndAccept!"templateSingleArgument");
}
override void visit(TemplateThisParameter templateThisParameter)
{
mixin (tagAndAccept!"templateThisParameter");
}
override void visit(TemplateTupleParameter templateTupleParameter)
{
mixin (tagAndAccept!"templateTupleParameter");
}
override void visit(TemplateTypeParameter templateTypeParameter)
{
mixin (tagAndAccept!"templateTypeParameter");
}
override void visit(TemplateValueParameter templateValueParameter)
{
mixin (tagAndAccept!"templateValueParameter");
}
override void visit(TemplateValueParameterDefault templateValueParameterDefault)
{
mixin (tagAndAccept!"templateValueParameterDefault");
}
override void visit(TernaryExpression ternaryExpression)
{
mixin (tagAndAccept!"ternaryExpression");
}
override void visit(ThrowStatement throwStatement)
{
mixin (tagAndAccept!"throwStatement");
}
override void visit(Token token)
{
string tagName;
with (TokenType) switch (token.type)
{
case invalid: return;
case identifier: tagName = "identifier"; break;
case doubleLiteral: tagName = "doubleLiteral"; break;
case idoubleLiteral: tagName = "idoubleLiteral"; break;
case floatLiteral: tagName = "floatLiteral"; break;
case ifloatLiteral: tagName = "ifloatLiteral"; break;
case intLiteral: tagName = "intLiteral"; break;
case uintLiteral: tagName = "uintLiteral"; break;
case longLiteral: tagName = "longLiteral"; break;
case ulongLiteral: tagName = "ulongLiteral"; break;
case realLiteral: tagName = "realLiteral"; break;
case irealLiteral: tagName = "irealLiteral"; break;
case characterLiteral: tagName = "characterLiteral"; break;
case stringLiteral: tagName = "stringLiteral"; break;
case dstringLiteral: tagName = "dstringLiteral"; break;
case wstringLiteral: tagName = "wstringLiteral"; break;
case dollar: output.writeln(""); return;
default: output.writeln("<", getTokenValue(token.type), "/>"); return;
}
output.writeln("<", tagName, ">", xmlEscape(token.value), "", tagName, ">");
}
override void visit(TraitsExpression traitsExpression)
{
mixin (tagAndAccept!"traitsExpression");
}
override void visit(TryStatement tryStatement)
{
mixin (tagAndAccept!"tryStatement");
}
override void visit(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(Type2 type2)
{
output.writeln("");
if (type2.builtinType != TokenType.invalid)
output.writeln(getTokenValue(type2.builtinType));
else
type2.accept(this);
output.writeln("");
}
override void visit(TypeSpecialization typeSpecialization)
{
mixin (tagAndAccept!"typeSpecialization");
}
override void visit(TypeSuffix typeSuffix)
{
if (typeSuffix.star)
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(TypeidExpression typeidExpression)
{
mixin (tagAndAccept!"typeidExpression");
}
override void visit(TypeofExpression typeofExpression)
{
mixin (tagAndAccept!"typeofExpression");
}
override void visit(UnaryExpression unaryExpression)
{
output.writeln("");
if (unaryExpression.prefix != TokenType.invalid)
{
output.writeln("", xmlEscape(unaryExpression.prefix.value),
"");
visit(unaryExpression.unaryExpression);
}
if (unaryExpression.suffix != TokenType.invalid)
{
visit(unaryExpression.unaryExpression);
output.writeln("", unaryExpression.suffix.value,
"");
}
else
unaryExpression.accept(this);
output.writeln("");
}
override void visit(UnionDeclaration unionDeclaration)
{
output.writeln("");
if (unionDeclaration.name != TokenType.invalid)
output.writeln("", unionDeclaration.name.value, "");
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(Unittest unittest_)
{
output.writeln("");
unittest_.accept(this);
output.writeln("");
}
override void visit(VariableDeclaration variableDeclaration)
{
mixin (tagAndAccept!"variableDeclaration");
}
override void visit(Vector vector)
{
mixin (tagAndAccept!"vector");
}
override void visit(VersionCondition versionCondition)
{
mixin (tagAndAccept!"versionCondition");
}
override void visit(VersionSpecification versionSpecification)
{
mixin (tagAndAccept!"versionSpecification");
}
override void visit(WhileStatement whileStatement)
{
mixin (tagAndAccept!"whileStatement");
}
override void visit(WithStatement withStatement)
{
mixin (tagAndAccept!"withStatement");
}
override void visit(XorExpression xorExpression)
{
output.writeln("");
output.writeln("");
xorExpression.left.accept(this);
output.writeln("");
if (xorExpression.right !is null)
{
output.writeln("");
xorExpression.right.accept(this);
output.writeln("");
}
output.writeln("");
}
alias ASTVisitor.visit visit;
private string xmlEscape(string s)
{
return s.translate(['<' : "<", '>' : ">", '&' : "&"]);
}
File output;
}