module formatter; import stdx.d.ast; import stdx.d.lexer; /** * The only brace styles worth using. */ enum IndentStyle { /** * --- * if (something) * { * foo(); * bar(); * } * else * { * bar(); * baz(); * } * --- */ allman, /** * --- * if (something) { * foo(); * bar(); * } else { * bar(); * baz(); * } * --- */ otbs, } /** * */ void format(Sink)(Sink sink, Module mod, bool useTabs = false, IndentStyle style = IndentStyle.allman, uint indentWith = 4) { Formatter!Sink formatter = new Formatter!(Sink)(sink, useTabs, style, indentWith); formatter.format(mod); } class Formatter(Sink) { /** * Parameters: * sink = the output range that the formatted source code is placed in * useTabs = if true, tabs are used for indent levels instead of spaces * style = the brace style * indenteWidth = the number of spaces used for indentation if useTabs is false */ this(Sink sink, bool useTabs = false, IndentStyle style = IndentStyle.allman, uint indentWidth = 4) { this.sink = sink; this.useTabs = useTabs; this.indentWidth = indentWidth; this.style = style; } void format(const AddExpression addExpression) { format(addExpression.left); if (addExpression.right is null) return; sink.put(" "); sink.put(getTokenValue(addExpression.operator)); sink.put(" "); format(addExpression.right); } void format(const AliasDeclaration aliasDeclaration) {} void format(const AliasInitializer aliasInitializer) {} void format(const AliasThisDeclaration aliasThisDeclaration) {} void format(const AlignAttribute alignAttribute) {} void format(const AndAndExpression andAndExpression) {} void format(const AndExpression andExpression) {} void format(const ArgumentList argumentList) {} void format(const Arguments arguments) {} void format(const ArrayInitializer arrayInitializer) {} void format(const ArrayLiteral arrayLiteral) {} void format(const ArrayMemberInitialization arrayMemberInitialization) {} void format(const AsmAddExp asmAddExp) {} void format(const AsmAndExp asmAndExp) {} void format(const AsmBrExp asmBrExp) {} void format(const AsmEqualExp asmEqualExp) {} void format(const AsmExp asmExp) {} void format(const AsmInstruction asmInstruction) {} void format(const AsmLogAndExp asmLogAndExp) {} void format(const AsmLogOrExp asmLogOrExp) {} void format(const AsmMulExp asmMulExp) {} void format(const AsmOrExp asmOrExp) {} void format(const AsmPrimaryExp asmPrimaryExp) {} void format(const AsmRelExp asmRelExp) {} void format(const AsmShiftExp asmShiftExp) {} void format(const AsmStatement asmStatement) {} void format(const AsmTypePrefix asmTypePrefix) {} void format(const AsmUnaExp asmUnaExp) {} void format(const AsmXorExp asmXorExp) {} void format(const AssertExpression assertExpression) {} void format(const AssignExpression assignExpression) {} void format(const AssocArrayLiteral assocArrayLiteral) {} void format(const AtAttribute atAttribute) {} void format(const Attribute attribute) {} void format(const AttributeDeclaration attributeDeclaration) {} void format(const AutoDeclaration autoDeclaration) {} void format(const BlockStatement blockStatement) {} void format(const BodyStatement bodyStatement) {} void format(const BreakStatement breakStatement) {} void format(const BaseClass baseClass) {} void format(const BaseClassList baseClassList) {} void format(const CaseRangeStatement caseRangeStatement) {} void format(const CaseStatement caseStatement) {} void format(const CastExpression castExpression) {} void format(const CastQualifier castQualifier) {} void format(const Catch catch_) {} void format(const Catches catches) {} void format(const ClassDeclaration classDeclaration) {} void format(const CmpExpression cmpExpression) {} void format(const CompileCondition compileCondition) {} void format(const ConditionalDeclaration conditionalDeclaration) {} void format(const ConditionalStatement conditionalStatement) {} void format(const Constraint constraint) {} void format(const Constructor constructor) {} void format(const ContinueStatement continueStatement) {} void format(const DebugCondition debugCondition) {} void format(const DebugSpecification debugSpecification) {} void format(const Declaration declaration) {} void format(const DeclarationOrStatement declarationsOrStatement) {} void format(const DeclarationsAndStatements declarationsAndStatements) {} void format(const Declarator declarator) {} void format(const DefaultStatement defaultStatement) {} void format(const DeleteExpression deleteExpression) {} void format(const DeleteStatement deleteStatement) {} void format(const Deprecated deprecated_) {} void format(const Destructor destructor) {} void format(const DoStatement doStatement) {} void format(const EnumBody enumBody) {} void format(const EnumDeclaration enumDeclaration) {} void format(const EnumMember enumMember) {} void format(const EqualExpression equalExpression) {} void format(const Expression expression) {} void format(const ExpressionNode expressionNode) {} void format(const ExpressionStatement expressionStatement) {} void format(const FinalSwitchStatement finalSwitchStatement) {} void format(const Finally finally_) {} void format(const ForStatement forStatement) {} void format(const ForeachStatement foreachStatement) {} void format(const ForeachType foreachType) {} void format(const ForeachTypeList foreachTypeList) {} void format(const FunctionAttribute functionAttribute) {} void format(const FunctionBody functionBody) {} void format(const FunctionCallExpression functionCallExpression) {} void format(const FunctionCallStatement functionCallStatement) {} void format(const FunctionDeclaration functionDeclaration) {} void format(const FunctionLiteralExpression functionLiteralExpression) {} void format(const GotoStatement gotoStatement) { sink.put("goto "); if (gotoStatement.label != TokenType.invalid) sink.put(gotoStatement.label.value); else format(gotoStatement.expression); sink.put(";"); } void format(const IdentifierChain identifierChain) { bool first = true; foreach(ident; identifierChain.identifiers) { if (!first) sink.put("."); first = false; sink.put(ident.value); } } void format(const IdentifierList identifierList) {} void format(const IdentifierOrTemplateChain identifierOrTemplateChain) { bool first = true; foreach(ident; identifierOrTemplateChain.identifiersOrTemplateInstances) { if (!first) sink.put("."); first = false; format(ident); } } void format(const IdentifierOrTemplateInstance identifierOrTemplateInstance) { if (identifierOrTemplateInstance.templateInstance !is null) format(identifierOrTemplateInstance.templateInstance); else sink.put(identifierOrTemplateInstance.identifier.value); } void format(const IdentityExpression identityExpression) {} void format(const IfStatement ifStatement) {} void format(const ImportBind importBind) {} void format(const ImportBindings importBindings) {} void format(const ImportDeclaration importDeclaration) {} void format(const ImportExpression importExpression) {} void format(const IndexExpression indexExpression) {} void format(const InExpression inExpression) {} void format(const InStatement inStatement) {} void format(const Initialize initialize) {} void format(const Initializer initializer) {} void format(const InterfaceDeclaration interfaceDeclaration) {} void format(const Invariant invariant_) {} void format(const IsExpression isExpression) {} void format(const KeyValuePair keyValuePair) {} void format(const KeyValuePairs keyValuePairs) {} void format(const LabeledStatement labeledStatement) {} void format(const LambdaExpression lambdaExpression) {} void format(const LastCatch lastCatch) {} void format(const LinkageAttribute linkageAttribute) {} void format(const MemberFunctionAttribute memberFunctionAttribute) {} void format(const MixinDeclaration mixinDeclaration) {} void format(const MixinExpression mixinExpression) {} void format(const MixinTemplateDeclaration mixinTemplateDeclaration) {} void format(const MixinTemplateName mixinTemplateName) {} void format(const Module module_) {} void format(const ModuleDeclaration moduleDeclaration) {} void format(const MulExpression mulExpression) {} void format(const NewAnonClassExpression newAnonClassExpression) {} void format(const NewExpression newExpression) {} void format(const NonVoidInitializer nonVoidInitializer) {} void format(const Operand operand) {} void format(const Operands operands) {} void format(const OrExpression orExpression) {} void format(const OrOrExpression orOrExpression) {} void format(const OutStatement outStatement) {} void format(const Parameter parameter) { foreach (attribute; parameter.parameterAttributes) { sink.put(getTokenValue(attribute)); } if (parameter.type !is null) format(parameter.type); if (parameter.name.type != TokenType.invalid) { sink.put(" "); sink.put(parameter.name.value); } if (parameter.vararg) sink.put(" ..."); } void format(const Parameters parameters) { sink.put("("); bool first = true; foreach (param; parameters.parameters) { if (!first) sink.put(", "); first = false; format(param); } sink.put(")"); } void format(const Postblit postblit) {} void format(const PostIncDecExpression postIncDecExpression) {} void format(const PowExpression powExpression) {} void format(const PragmaDeclaration pragmaDeclaration) {} void format(const PragmaExpression pragmaExpression) {} void format(const PreIncDecExpression preIncDecExpression) {} void format(const PrimaryExpression primaryExpression) {} void format(const Register register) {} void format(const RelExpression relExpression) {} void format(const ReturnStatement returnStatement) {} void format(const ScopeGuardStatement scopeGuardStatement) {} void format(const SharedStaticConstructor sharedStaticConstructor) {} void format(const SharedStaticDestructor sharedStaticDestructor) {} void format(const ShiftExpression shiftExpression) {} void format(const SingleImport singleImport) {} void format(const SliceExpression sliceExpression) {} void format(const Statement statement) {} void format(const StatementNoCaseNoDefault statementNoCaseNoDefault) {} void format(const StaticAssertDeclaration staticAssertDeclaration) {} void format(const StaticAssertStatement staticAssertStatement) {} void format(const StaticConstructor staticConstructor) {} void format(const StaticDestructor staticDestructor) {} void format(const StaticIfCondition staticIfCondition) {} void format(const StorageClass storageClass) {} void format(const StructBody structBody) {} void format(const StructDeclaration structDeclaration) {} void format(const StructInitializer structInitializer) {} void format(const StructMemberInitializer structMemberInitializer) {} void format(const StructMemberInitializers structMemberInitializers) {} void format(const SwitchStatement switchStatement) {} void format(const Symbol symbol) { if (symbol.dot != TokenType.invalid) sink.put("."); format(symbol.identifierOrTemplateChain); } void format(const SynchronizedStatement synchronizedStatement) {} void format(const TemplateAliasParameter templateAliasParameter) {} void format(const TemplateArgument templateArgument) {} void format(const TemplateArgumentList templateArgumentList) {} void format(const TemplateArguments templateArguments) {} void format(const TemplateDeclaration templateDeclaration) {} void format(const TemplateInstance templateInstance) {} void format(const TemplateMixinExpression templateMixinExpression) {} void format(const TemplateParameter templateParameter) {} void format(const TemplateParameterList templateParameterList) {} void format(const TemplateParameters templateParameters) {} void format(const TemplateSingleArgument templateSingleArgument) {} void format(const TemplateThisParameter templateThisParameter) {} void format(const TemplateTupleParameter templateTupleParameter) {} void format(const TemplateTypeParameter templateTypeParameter) {} void format(const TemplateValueParameter templateValueParameter) {} void format(const TemplateValueParameterDefault templateValueParameterDefault) {} void format(const TernaryExpression ternaryExpression) {} void format(const ThrowStatement throwStatement) {} void format(const Token token) { sink.put(token.value); } void format(const TraitsExpression traitsExpression) {} void format(const TryStatement tryStatement) {} void format(const Type type) { bool first = true; foreach (constructor; type.typeConstructors) { if (first) sink.put(" "); first = false; sink.put(getTokenValue(constructor)); } if (type.typeConstructors.length > 0) sink.put(" "); format(type.type2); foreach (suffix; type.typeSuffixes) { format(suffix); } } void format(const Type2 type2) { if (type2.symbol !is null) { format(type2.symbol); return; } else if (type2.typeofExpression !is null) { format(type2.typeofExpression); return; } else if (type2.typeConstructor != TokenType.invalid) { sink.put(getTokenValue(type2.typeConstructor)); sink.put("("); format(type2.type); sink.put(")"); return; } else sink.put(getTokenValue(type2.builtinType)); } void format(const TypeSpecialization typeSpecialization) {} void format(const TypeSuffix typeSuffix) { if (typeSuffix.star) { sink.put("*"); return; } else if (typeSuffix.array) { if (typeSuffix.type is null) { if (typeSuffix.low is null) { sink.put("[]"); return; } else { if (typeSuffix.high is null) { sink.put("["); format(typeSuffix.low); sink.put("]"); return; } else { sink.put("["); format(typeSuffix.low); sink.put(".."); format(typeSuffix.high); sink.put("]"); return; } } } else { sink.put("["); format(typeSuffix.type); sink.put("]"); return; } } else { // TODO sink.put(" "); format(typeSuffix.delegateOrFunction); sink.put("()"); return; } } void format(const TypeidExpression typeidExpression) {} void format(const TypeofExpression typeofExpression) {} void format(const UnaryExpression unaryExpression) {} void format(const UnionDeclaration unionDeclaration) {} void format(const Unittest unittest_) {} void format(const VariableDeclaration variableDeclaration) {} void format(const Vector vector) {} void format(const VersionCondition versionCondition) {} void format(const VersionSpecification versionSpecification) {} void format(const WhileStatement whileStatement) {} void format(const WithStatement withStatement) {} void format(const XorExpression xorExpression) {} private: void indent() { indentLevel++; } void outdent() { if (indentLevel == 0) return; indentLevel--; } bool useTabs; uint indentWidth; uint indentLevel; IndentStyle style; Sink sink; }