1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- const util = require('util')
- /**
- * This class should be used to build .py source files
- */
- class SourceBuilder {
- constructor(stream, indentSize) {
- this.currentIndent = 0
- this.onNewLine = false
- this.indentSize = indentSize || 4
- this.stream = stream
- // Was a new line added automatically before? If so, avoid it
- this.autoAddedLine = false
- }
- /**
- * Indents the current source code line
- * by the current indentation level
- */
- indent() {
- this.write(' '.repeat(Math.abs(this.currentIndent * this.indentSize)))
- }
- /**
- * Writes a string into the source code,
- * applying indentation if required
- */
- write(string, ...args) {
- if (this.onNewLine) {
- this.onNewLine = false // We're not on a new line anymore
- // If the string was not empty, indent; Else probably a new line
- if (string.trim()) {
- this.indent()
- }
- }
- if (args.length) {
- this.stream.write(util.format(string, ...args))
- } else {
- this.stream.write(string)
- }
- }
- /**
- * Writes a string into the source code _and_ appends a new line,
- * applying indentation if required
- */
- writeln(string, ...args) {
- this.write(`${string || ''}\n`, ...args)
- this.onNewLine = true
- // If we're writing a block, increment indent for the next time
- if (string && string.endsWith('{')) {
- this.currentIndent++
- }
- // Clear state after the user adds a new line
- this.autoAddedLine = false
- }
- /**
- * Ends an indentation block, leaving an empty line afterwards
- */
- endBlock(semiColon = false) {
- this.currentIndent--
- // If we did not add a new line automatically yet, now it's the time!
- if (!this.autoAddedLine) {
- this.writeln('}%s', semiColon ? ';' : '')
- this.autoAddedLine = true
- }
- }
- }
- module.exports = SourceBuilder
|