diff --git a/.idea/artifacts/KotlinPlugin.xml b/.idea/artifacts/KotlinPlugin.xml index 5550cf923a2..c6443f79573 100644 --- a/.idea/artifacts/KotlinPlugin.xml +++ b/.idea/artifacts/KotlinPlugin.xml @@ -40,6 +40,7 @@ + diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedMemberScope.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedMemberScope.java index a9b34e398fc..87614c65bc9 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedMemberScope.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedMemberScope.java @@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.storage.MemoizedFunctionToNotNull; import org.jetbrains.jet.storage.NotNullLazyValue; import org.jetbrains.jet.storage.StorageManager; +import org.jetbrains.jet.utils.Printer; import java.util.*; @@ -255,4 +256,14 @@ public abstract class DeserializedMemberScope implements JetScope { boolean accept(T value); } + @Override + public void printScopeStructure(@NotNull Printer p) { + p.println(getClass().getSimpleName(), " {"); + p.pushIndent(); + + p.println("containingDeclaration = " + containingDeclaration); + + p.popIndent(); + p.println("}"); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java index b4a4c0100f0..6bbb89ccf23 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java @@ -43,6 +43,7 @@ import org.jetbrains.jet.lang.types.expressions.DataFlowUtils; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lexer.JetTokens; +import org.jetbrains.jet.utils.Printer; import javax.inject.Inject; import java.util.ArrayList; @@ -113,7 +114,12 @@ public class CallExpressionResolver { public String toString() { return "Scope for the type parameter on the left hand side of dot"; } - }; + + @Override + public void printScopeStructure(@NotNull Printer p) { + p.println(toString(), " for ", classifier); + } + }; return new NamespaceType(referencedName, scopeForStaticMembersResolution, NO_RECEIVER); } temporaryTrace.commit(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyImportScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyImportScope.java index 5b30c261761..e4f9c8cf1d2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyImportScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyImportScope.java @@ -22,6 +22,7 @@ import jet.Function0; import jet.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetImportDirective; @@ -32,6 +33,7 @@ import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.*; import org.jetbrains.jet.storage.MemoizedFunctionToNotNull; +import org.jetbrains.jet.utils.Printer; import java.util.Collection; import java.util.Collections; @@ -312,4 +314,19 @@ public class LazyImportScope implements JetScope { public String toString() { return "LazyImportScope: " + debugName; } + + @TestOnly + @Override + public void printScopeStructure(@NotNull Printer p) { + p.println(getClass().getSimpleName(), ": ", debugName, " {"); + p.pushIndent(); + + p.println("packageDescriptor = ", packageDescriptor); + + p.print("rootScope = "); + rootScope.printScopeStructure(p.withholdIndentOnce()); + + p.popIndent(); + p.println("}"); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/AbstractLazyMemberScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/AbstractLazyMemberScope.java index 30a89c31b2c..9563341b86e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/AbstractLazyMemberScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/AbstractLazyMemberScope.java @@ -35,6 +35,7 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.storage.MemoizedFunctionToNotNull; import org.jetbrains.jet.storage.NotNullLazyValue; import org.jetbrains.jet.storage.StorageManager; +import org.jetbrains.jet.utils.Printer; import java.util.Collection; import java.util.Collections; @@ -329,4 +330,15 @@ public abstract class AbstractLazyMemberScope getOwnDeclaredDescriptors() { return getAllDescriptors(); } + + @Override + public void printScopeStructure(@NotNull Printer p) { + p.println(getClass().getSimpleName(), " {"); + p.pushIndent(); + + p.println("thisDescriptor = ", thisDescriptor); + + p.popIndent(); + p.println("}"); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeUtils.java index 840a792a36f..6a5f9136b10 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeUtils.java @@ -22,11 +22,12 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.BindingTrace; -import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.TraceBasedRedeclarationHandler; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; +import org.jetbrains.jet.utils.Printer; import java.util.Collection; import java.util.List; @@ -130,4 +131,18 @@ public final class JetScopeUtils { result.changeLockLevel(WritableScope.LockLevel.READING); return result; } + + @TestOnly + @NotNull + public static String printStructure(@Nullable JetScope scope) { + StringBuilder out = new StringBuilder(); + Printer p = new Printer(out); + if (scope == null) { + p.println("null"); + } + else { + scope.printScopeStructure(p); + } + return out.toString(); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java index 6a16e9064bf..f61e7915f87 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WriteThroughScope.java @@ -21,9 +21,11 @@ import com.google.common.collect.Multimap; import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.utils.Printer; import java.util.Collection; import java.util.Set; @@ -284,4 +286,11 @@ public class WriteThroughScope extends WritableScopeWithImports { return getWorkerScope(); } + + @TestOnly + @Override + protected void printAdditionalScopeStructure(@NotNull Printer p) { + p.print("writableWorker = "); + writableWorker.printScopeStructure(p.withholdIndentOnce()); + } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaBaseScope.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaBaseScope.java index 10e0e77ba70..c4d51814d11 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaBaseScope.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaBaseScope.java @@ -18,11 +18,13 @@ package org.jetbrains.jet.lang.resolve.java.scope; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.java.resolver.JavaMemberResolver; import org.jetbrains.jet.lang.resolve.java.resolver.ProgressChecker; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScopeImpl; +import org.jetbrains.jet.utils.Printer; import java.util.*; @@ -170,4 +172,16 @@ public abstract class JavaBaseScope extends JetScopeImpl { } return result; } + + @TestOnly + @Override + public void printScopeStructure(@NotNull Printer p) { + p.println(getClass().getSimpleName(), " {"); + p.pushIndent(); + + p.println("descriptor = ", descriptor); + + p.popIndent(); + p.println("}"); + } } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/AbstractScopeAdapter.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/AbstractScopeAdapter.java index a2c242b2e6c..73a1f3b9608 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/AbstractScopeAdapter.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/AbstractScopeAdapter.java @@ -17,9 +17,11 @@ package org.jetbrains.jet.lang.resolve.scopes; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.TestOnly; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.utils.Printer; import java.util.Collection; import java.util.List; @@ -98,4 +100,17 @@ public abstract class AbstractScopeAdapter implements JetScope { public Collection getOwnDeclaredDescriptors() { return getWorkerScope().getOwnDeclaredDescriptors(); } + + @TestOnly + @Override + public void printScopeStructure(@NotNull Printer p) { + p.println(getClass().getSimpleName(), " {"); + p.pushIndent(); + + p.print("worker ="); + getWorkerScope().printScopeStructure(p.withholdIndentOnce()); + + p.popIndent(); + p.println("}"); + } } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java index 688a7012aaa..dc614db7f0b 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/ChainedScope.java @@ -19,9 +19,11 @@ package org.jetbrains.jet.lang.resolve.scopes; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.TestOnly; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.utils.Printer; import java.util.Collection; import java.util.Collections; @@ -170,4 +172,18 @@ public class ChainedScope implements JetScope { public String toString() { return debugName; } + + @TestOnly + @Override + public void printScopeStructure(@NotNull Printer p) { + p.println(getClass().getSimpleName(), ": ", debugName, " {"); + p.pushIndent(); + + for (JetScope scope : scopeChain) { + scope.printScopeStructure(p); + } + + p.popIndent(); + p.println("}"); + } } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/FilteringScope.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/FilteringScope.java index 0abfb11fcf5..a786f4ca47a 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/FilteringScope.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/FilteringScope.java @@ -20,9 +20,11 @@ import com.google.common.base.Predicate; import com.google.common.collect.Collections2; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.utils.Printer; import java.util.Collection; import java.util.List; @@ -108,4 +110,17 @@ public class FilteringScope implements JetScope { public Collection getOwnDeclaredDescriptors() { return Collections2.filter(workerScope.getOwnDeclaredDescriptors(), predicate); } + + @TestOnly + @Override + public void printScopeStructure(@NotNull Printer p) { + p.println(getClass().getSimpleName(), " {"); + p.pushIndent(); + + p.print("workerScope = "); + workerScope.printScopeStructure(p.withholdIndentOnce()); + + p.popIndent(); + p.println("}"); + } } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java index bbc6064cf3f..3b33d1b659b 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/JetScope.java @@ -19,9 +19,11 @@ package org.jetbrains.jet.lang.resolve.scopes; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.ReadOnly; +import org.jetbrains.annotations.TestOnly; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.utils.Printer; import java.util.Collection; import java.util.List; @@ -38,6 +40,11 @@ public interface JetScope { public String toString() { return "EMPTY"; } + + @Override + public void printScopeStructure(@NotNull Printer p) { + p.println("EMPTY"); + } }; /** @@ -93,4 +100,7 @@ public interface JetScope { @NotNull @ReadOnly Collection getOwnDeclaredDescriptors(); + + @TestOnly + void printScopeStructure(@NotNull Printer p); } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java index 7d8605af9b5..ddf02ebea76 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeImpl.java @@ -17,9 +17,11 @@ package org.jetbrains.jet.lang.resolve.scopes; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.TestOnly; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.utils.Printer; import java.util.Collection; import java.util.Collections; @@ -88,4 +90,9 @@ public abstract class JetScopeImpl implements JetScope { public Collection getOwnDeclaredDescriptors() { return Collections.emptyList(); } -} + + // This method should not be implemented here by default: every scope class has its unique structure pattern + @TestOnly + @Override + public abstract void printScopeStructure(@NotNull Printer p); +} \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java index 9dee539339f..6781cd46ed0 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java @@ -20,10 +20,12 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.TypeSubstitutor; +import org.jetbrains.jet.utils.Printer; import java.util.Collection; import java.util.List; @@ -150,4 +152,22 @@ public class SubstitutingScope implements JetScope { public Collection getOwnDeclaredDescriptors() { return substitute(workerScope.getOwnDeclaredDescriptors()); } + + @TestOnly + @Override + public void printScopeStructure(@NotNull Printer p) { + p.println(getClass().getSimpleName(), " {"); + p.pushIndent(); + + p.println("substitutor = "); + p.pushIndent(); + p.println(substitutor); + p.popIndent(); + + p.print("workerScope = "); + workerScope.printScopeStructure(p.withholdIndentOnce()); + + p.popIndent(); + p.println("}"); + } } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java index 3b4bec0b9aa..be9ffc271e9 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java @@ -19,11 +19,13 @@ package org.jetbrains.jet.lang.resolve.scopes; import com.google.common.collect.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.name.LabelName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.utils.CommonSuppliers; +import org.jetbrains.jet.utils.Printer; import java.util.*; @@ -507,4 +509,10 @@ public class WritableScopeImpl extends WritableScopeWithImports { throw new IllegalStateException("unknown classifier: " + classifier); } } + + @TestOnly + @Override + protected void printAdditionalScopeStructure(@NotNull Printer p) { + p.println("allDescriptorsDone = ", allDescriptorsDone); + } } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java index 6ce0598d304..a4893459e03 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeWithImports.java @@ -20,8 +20,10 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.TestOnly; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.utils.Printer; import java.util.*; @@ -249,4 +251,36 @@ public abstract class WritableScopeWithImports extends JetScopeAdapter implement return getClass().getSimpleName() + "@" + Integer.toHexString(System.identityHashCode(this)) + " " + debugName + " for " + getContainingDeclaration(); } + @TestOnly + @Override + public void printScopeStructure(@NotNull Printer p) { + p.println(getClass().getSimpleName(), ": ", debugName, " for ", getContainingDeclaration(), " {"); + p.pushIndent(); + + p.println("lockLevel = ", lockLevel); + + printAdditionalScopeStructure(p); + + p.print("worker = "); + getWorkerScope().printScopeStructure(p.withholdIndentOnce()); + + if (getImports().isEmpty()) { + p.println("imports = {}"); + } + else { + p.println("imports = {"); + p.pushIndent(); + for (JetScope anImport : getImports()) { + anImport.printScopeStructure(p); + } + p.popIndent(); + p.println("}"); + } + + p.popIndent(); + p.println("}"); + } + + @TestOnly + protected abstract void printAdditionalScopeStructure(@NotNull Printer p); } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/ErrorUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/types/ErrorUtils.java index 4b9e8a74148..a68cf7d88c8 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/ErrorUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/ErrorUtils.java @@ -32,6 +32,7 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.error.ErrorClassDescriptor; import org.jetbrains.jet.lang.types.error.ErrorSimpleFunctionDescriptorImpl; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; +import org.jetbrains.jet.utils.Printer; import java.util.Collection; import java.util.Collections; @@ -155,6 +156,11 @@ public class ErrorUtils { public String toString() { return "ErrorScope{" + debugMessage + '}'; } + + @Override + public void printScopeStructure(@NotNull Printer p) { + p.println(getClass().getSimpleName(), ": ", debugMessage); + } } private static class ThrowingScope implements JetScope { @@ -240,6 +246,11 @@ public class ErrorUtils { public String toString() { return "ThrowingScope{" + debugMessage + '}'; } + + @Override + public void printScopeStructure(@NotNull Printer p) { + p.println(getClass().getSimpleName(), ": ", debugMessage); + } } private static final ErrorClassDescriptor ERROR_CLASS = new ErrorClassDescriptor(""); diff --git a/compiler/util/src/org/jetbrains/jet/utils/Printer.java b/core/util.runtime/src/org/jetbrains/jet/utils/Printer.java similarity index 91% rename from compiler/util/src/org/jetbrains/jet/utils/Printer.java rename to core/util.runtime/src/org/jetbrains/jet/utils/Printer.java index 73e1c40f3b8..6c9855a1bc1 100644 --- a/compiler/util/src/org/jetbrains/jet/utils/Printer.java +++ b/core/util.runtime/src/org/jetbrains/jet/utils/Printer.java @@ -31,6 +31,7 @@ public class Printer { private String indent = ""; private int blankLineCountIncludingCurrent = 0; + private boolean withholdIndentOnce = false; public Printer(@NotNull Appendable out) { this(out, Integer.MAX_VALUE); @@ -67,7 +68,12 @@ public class Printer { @NotNull public Printer print(Object... objects) { - append(indent); + if (withholdIndentOnce) { + withholdIndentOnce = false; + } + else { + append(indent); + } printWithNoIndent(objects); return this; @@ -83,6 +89,12 @@ public class Printer { return this; } + @NotNull + public Printer withholdIndentOnce() { + withholdIndentOnce = true; + return this; + } + @NotNull public Printer printlnWithNoIndent(Object... objects) { printWithNoIndent(objects);