import std.d.lexer; import std.d.ast; import std.stdio; 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(""); visit(conditionalDeclaration.trueDeclaration); 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(""); 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(""); 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.token.type == TokenType.default_) output.writeln(""); else if (gotoStatement.token.type == TokenType.identifier) output.writeln(""); else { output.writeln(""); output.writeln(""); visit(gotoStatement.expression); output.writeln(""); output.writeln(""); } } override void visit(IdentifierChain chain) { output.writeln(""); chain.accept(this); output.writeln(""); } override void visit(IdentifierList list) { output.writeln(""); list.accept(this); output.writeln(""); } 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(OrExpression orOrExpression) { mixin(tagAndAccept!"orOrExpression"); } /*************************************************************************** * BOOKMARK **************************************************************************/ override void visit(Parameters parameters) { mixin (tagAndAccept!"parameters"); } 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(SingleImport singleImport) { if (singleImport.rename.type == TokenType.invalid) output.writeln(""); else output.writeln(""); visit(singleImport.identifierChain); output.writeln(""); } override void visit(StructDeclaration structDec) { output.writeln(""); output.writeln("", structDec.name.value, ""); structDec.accept(this); output.writeln(""); } override void visit(Token token) { string tagName; with (TokenType) switch (token.type) { 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; default: tagName = "token"; } output.writeln("<", tagName, ">"); } override void visit(Type type) { output.writeln(""); type.accept(this); output.writeln(""); } override void visit(Unittest unittest_) { output.writeln(""); unittest_.accept(this); output.writeln(""); } override void visit(VariableDeclaration variableDeclaration) { mixin (tagAndAccept!"variableDeclaration"); } alias ASTVisitor.visit visit; File output; }