// 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("");`; } 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), ""); } 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; }