001 /* 002 * Copyright 2010-2015 JetBrains s.r.o. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package org.jetbrains.kotlin.utils; 018 019 import org.jetbrains.annotations.NotNull; 020 021 import java.io.IOException; 022 import java.util.Collection; 023 import java.util.Iterator; 024 025 public class Printer { 026 private static final String INDENTATION_UNIT = " "; 027 private static final String LINE_SEPARATOR = System.getProperty("line.separator"); 028 029 protected final Appendable out; 030 private final int maxBlankLines; 031 032 private String indent = ""; 033 private int blankLineCountIncludingCurrent = 0; 034 private boolean withholdIndentOnce = false; 035 036 public Printer(@NotNull Appendable out) { 037 this(out, Integer.MAX_VALUE); 038 } 039 040 public Printer(@NotNull Appendable out, int maxBlankLines) { 041 this.out = out; 042 this.maxBlankLines = maxBlankLines; 043 } 044 045 private void append(Object o) { 046 try { 047 out.append(o.toString()); 048 } 049 catch (IOException e) { 050 // Do nothing 051 } 052 } 053 054 @NotNull 055 public Printer println(Object... objects) { 056 print(objects); 057 printLineSeparator(); 058 059 return this; 060 } 061 062 private void printLineSeparator() { 063 if (blankLineCountIncludingCurrent <= maxBlankLines) { 064 blankLineCountIncludingCurrent++; 065 append(LINE_SEPARATOR); 066 } 067 } 068 069 @NotNull 070 public Printer print(Object... objects) { 071 if (withholdIndentOnce) { 072 withholdIndentOnce = false; 073 } 074 else if (objects.length > 0) { 075 printIndent(); 076 } 077 printWithNoIndent(objects); 078 079 return this; 080 } 081 082 public void printIndent() { 083 append(indent); 084 } 085 086 @NotNull 087 public Printer printWithNoIndent(Object... objects) { 088 for (Object object : objects) { 089 blankLineCountIncludingCurrent = 0; 090 append(object); 091 } 092 093 return this; 094 } 095 096 @NotNull 097 public Printer withholdIndentOnce() { 098 withholdIndentOnce = true; 099 return this; 100 } 101 102 @NotNull 103 public Printer printlnWithNoIndent(Object... objects) { 104 printWithNoIndent(objects); 105 printLineSeparator(); 106 107 return this; 108 } 109 110 @NotNull 111 public Printer pushIndent() { 112 indent += INDENTATION_UNIT; 113 114 return this; 115 } 116 117 @NotNull 118 public Printer popIndent() { 119 if (indent.length() < INDENTATION_UNIT.length()) { 120 throw new IllegalStateException("No indentation to pop"); 121 } 122 123 indent = indent.substring(INDENTATION_UNIT.length()); 124 125 return this; 126 } 127 128 @NotNull 129 public Printer separated(Object separator, Object... items) { 130 for (int i = 0; i < items.length; i++) { 131 if (i > 0) { 132 printlnWithNoIndent(separator); 133 } 134 printlnWithNoIndent(items[i]); 135 } 136 return this; 137 } 138 139 @NotNull 140 public Printer separated(Object separator, Collection<?> items) { 141 for (Iterator<?> iterator = items.iterator(); iterator.hasNext(); ) { 142 printlnWithNoIndent(iterator.next()); 143 if (iterator.hasNext()) { 144 printlnWithNoIndent(separator); 145 } 146 } 147 return this; 148 } 149 }