@Override public void visitObjectDeclaration(JetObjectDeclaration declaration) { if (declaration.getParent() instanceof JetObjectLiteralExpression || declaration.getParent() instanceof JetClassObject) { super.visitObjectDeclaration(declaration); } else { ClassDescriptor classDescriptor = bindingContext.get(CLASS, declaration); // working around a problem with shallow analysis if (classDescriptor == null) return; String name = getName(classDescriptor); recordClosure( bindingTrace, declaration, classDescriptor, peekFromStack(classStack), JvmClassName.byInternalName(name), false); classStack.push(classDescriptor); nameStack.push(name); super.visitObjectDeclaration(declaration); nameStack.pop(); classStack.pop(); } }
@Override public void visitObjectLiteralExpression(JetObjectLiteralExpression expression) { ClassDescriptor classDescriptor = bindingContext.get(CLASS, expression.getObjectDeclaration()); if (classDescriptor == null) { // working around a problem with shallow analysis super.visitObjectLiteralExpression(expression); return; } final String name = inventAnonymousClassName(expression.getObjectDeclaration()); recordClosure( bindingTrace, expression.getObjectDeclaration(), classDescriptor, peekFromStack(classStack), JvmClassName.byInternalName(name), false); classStack.push(classDescriptor); //noinspection ConstantConditions nameStack.push(bindingContext.get(FQN, classDescriptor).getInternalName()); super.visitObjectLiteralExpression(expression); nameStack.pop(); classStack.pop(); }
@Override public synchronized void popState() { LOG.assertTrue(!myTextStack.isEmpty()); String oldText = myTextStack.pop(); double oldFraction = myFractionStack.remove(myFractionStack.size() - 1); String oldText2 = myText2Stack.pop(); setText(oldText); setFraction(oldFraction); setText2(oldText2); }
private boolean runNextEvent() { final RunnableInfo lastInfo = getNextEvent(true); myLastInfo = lastInfo; if (lastInfo != null) { synchronized (RUN_LOCK) { // necessary only because of switching to our own event queue AWTEvent event = ourEventQueue.getTrueCurrentEvent(); ourEventStack.push(event); int stackSize = ourEventStack.size(); try { lastInfo.runnable.run(); lastInfo.callback.setDone(); } catch (ProcessCanceledException ignored) { } catch (Throwable t) { LOG.error(t); } finally { LOG.assertTrue(ourEventStack.size() == stackSize); ourEventStack.pop(); if (!DEBUG) myLastInfo = null; } } } return lastInfo != null; }
@Override public void visitClassObject(JetClassObject classObject) { ClassDescriptor classDescriptor = bindingContext.get(CLASS, classObject.getObjectDeclaration()); assert classDescriptor != null; JvmClassName name = JvmClassName.byInternalName(peekFromStack(nameStack) + JvmAbi.CLASS_OBJECT_SUFFIX); recordClosure( bindingTrace, classObject, classDescriptor, peekFromStack(classStack), name, false); classStack.push(classDescriptor); nameStack.push(name.getInternalName()); super.visitClassObject(classObject); nameStack.pop(); classStack.pop(); }
public void compileCorrectFiles( BindingContext bindingContext, List<JetFile> files, CompilationErrorHandler errorHandler, boolean annotate) { ClosureAnnotator closureAnnotator = !annotate ? null : new ClosureAnnotator(bindingContext, files); typeMapper = new JetTypeMapper(standardLibrary, bindingContext, closureAnnotator); bindingContexts.push(bindingContext); try { for (JetFile namespace : files) { try { generateNamespace(namespace); } catch (Throwable e) { errorHandler.reportException(e, namespace.getContainingFile().getVirtualFile().getUrl()); DiagnosticUtils.throwIfRunningOnServer(e); if (ApplicationManager.getApplication().isInternal()) { e.printStackTrace(); } } } } finally { bindingContexts.pop(); typeMapper = null; } }
public static String parseDiagnosedRanges(String text, List<DiagnosedRange> result) { Matcher matcher = RANGE_START_OR_END_PATTERN.matcher(text); Stack<DiagnosedRange> opened = new Stack<DiagnosedRange>(); int offsetCompensation = 0; while (matcher.find()) { int effectiveOffset = matcher.start() - offsetCompensation; String matchedText = matcher.group(); if ("<!>".equals(matchedText)) { opened.pop().setEnd(effectiveOffset); } else { Matcher diagnosticTypeMatcher = INDIVIDUAL_DIAGNOSTIC_PATTERN.matcher(matchedText); DiagnosedRange range = new DiagnosedRange(effectiveOffset); while (diagnosticTypeMatcher.find()) { range.addDiagnostic(diagnosticTypeMatcher.group()); } opened.push(range); result.add(range); } offsetCompensation += matchedText.length(); } assert opened.isEmpty() : "Stack is not empty"; matcher.reset(); return matcher.replaceAll(""); }
@Override public void emptyStack() { myCachedHash = null; while (!myStack.isEmpty() && !(myStack.peek() instanceof DfaControlTransferValue)) { myStack.pop(); } }
@Nullable private synchronized Loader getLoader(int i) { while (myLoaders.size() < i + 1) { boolean lastOne; URL url; synchronized (myUrls) { if (myUrls.empty()) { if (myCanUseCache) myCache.nameSymbolsLoaded(); return null; } url = myUrls.pop(); lastOne = myUrls.isEmpty(); } if (myLoadersMap.containsKey(url)) continue; Loader loader; try { loader = getLoader(url, myLoaders.size()); if (loader == null) continue; } catch (IOException ioexception) { continue; } myLoaders.add(loader); myLoadersMap.put(url, loader); if (lastOne && myCanUseCache) { myCache.nameSymbolsLoaded(); } } return myLoaders.get(i); }
@Override public void visitJetFile(JetFile file) { if (file.isScript()) { //noinspection ConstantConditions final ClassDescriptor classDescriptor = bindingContext.get(CLASS_FOR_FUNCTION, bindingContext.get(SCRIPT, file.getScript())); classStack.push(classDescriptor); //noinspection ConstantConditions nameStack.push(classNameForScriptPsi(bindingContext, file.getScript()).getInternalName()); } else { nameStack.push(JetPsiUtil.getFQName(file).getFqName().replace('.', '/')); } file.acceptChildren(this); nameStack.pop(); if (file.isScript()) { classStack.pop(); } }
private void eofCleanup() { if (markingBlock) { blockMarker.error(message("ss.parsing.unclosed.statement", blockTokenText)); markingBlock = false; } if (markingComment) { commentMarker.drop(); } while (!statementsStack.isEmpty()) { statementsStack.pop().drop(); } }
final void restoreValue(boolean pushed) { if (pushed) { --myLevel; if (myValueStack != null && !myValueStack.isEmpty()) { myValueStack.pop(); } } if (myValueStack != null) { myValue = myValueStack.isEmpty() ? null : myValueStack.peek(); } }
@Override public void visitClass(JetClass klass) { ClassDescriptor classDescriptor = bindingContext.get(CLASS, klass); // working around a problem with shallow analysis if (classDescriptor == null) return; String name = getName(classDescriptor); recordClosure( bindingTrace, klass, classDescriptor, peekFromStack(classStack), JvmClassName.byInternalName(name), false); classStack.push(classDescriptor); nameStack.push(name); super.visitClass(klass); nameStack.pop(); classStack.pop(); }
public void runWriteAction(@NotNull final Runnable action) { assertCanRunWriteAction(); ActivityTracker.getInstance().inc(); fireBeforeWriteActionStart(action); final AtomicBoolean stopped = new AtomicBoolean(false); if (ourDumpThreadsOnLongWriteActionWaiting > 0) { executeOnPooledThread( new Runnable() { @Override public void run() { while (!stopped.get()) { try { Thread.sleep(ourDumpThreadsOnLongWriteActionWaiting); if (!stopped.get()) { PerformanceWatcher.getInstance().dumpThreads(true); } } catch (InterruptedException ignored) { } } } }); } LOG.assertTrue( myActionsLock.isWriteLockAcquired(Thread.currentThread()) || !Thread.holdsLock(PsiLock.LOCK), "Thread must not hold PsiLock while performing writeAction"); try { myActionsLock.writeLock().acquire(); } catch (InterruptedException e) { throw new RuntimeInterruptedException(e); } stopped.set(true); try { myWriteActionsStack.push(action); fireWriteActionStarted(action); action.run(); } finally { try { fireWriteActionFinished(action); myWriteActionsStack.pop(); } finally { myActionsLock.writeLock().release(); } } }
@Override public void visitNamedFunction(JetNamedFunction function) { FunctionDescriptor functionDescriptor = (FunctionDescriptor) bindingContext.get(DECLARATION_TO_DESCRIPTOR, function); // working around a problem with shallow analysis if (functionDescriptor == null) return; DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration(); if (containingDeclaration instanceof ClassDescriptor) { nameStack.push(peekFromStack(nameStack) + '$' + function.getName()); super.visitNamedFunction(function); nameStack.pop(); } else if (containingDeclaration instanceof NamespaceDescriptor) { String peek = peekFromStack(nameStack); if (peek.isEmpty()) { peek = JvmAbi.PACKAGE_CLASS; } else { peek += "/" + JvmAbi.PACKAGE_CLASS; } nameStack.push(peek + '$' + function.getName()); super.visitNamedFunction(function); nameStack.pop(); } else { String name = inventAnonymousClassName(function); ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor); recordClosure( bindingTrace, function, classDescriptor, peekFromStack(classStack), JvmClassName.byInternalName(name), true); classStack.push(classDescriptor); nameStack.push(name); super.visitNamedFunction(function); nameStack.pop(); classStack.pop(); } }
@Override public final void action() throws Exception { if (LOG.isDebugEnabled()) { LOG.debug("trying " + this); } final SuspendContextImpl suspendContext = getSuspendContext(); if (suspendContext == null) { if (LOG.isDebugEnabled()) { LOG.debug("skip processing - context is null " + this); } notifyCancelled(); return; } if (suspendContext.myInProgress) { suspendContext.postponeCommand(this); } else { try { if (!suspendContext.isResumed()) { suspendContext.myInProgress = true; contextAction(suspendContext); } else { notifyCancelled(); } } finally { suspendContext.myInProgress = false; if (suspendContext.isResumed()) { for (SuspendContextCommandImpl postponed = suspendContext.pollPostponedCommand(); postponed != null; postponed = suspendContext.pollPostponedCommand()) { postponed.notifyCancelled(); } } else { SuspendContextCommandImpl postponed = suspendContext.pollPostponedCommand(); if (postponed != null) { final Stack<SuspendContextCommandImpl> stack = new Stack<>(); while (postponed != null) { stack.push(postponed); postponed = suspendContext.pollPostponedCommand(); } final DebuggerManagerThreadImpl managerThread = suspendContext.getDebugProcess().getManagerThread(); while (!stack.isEmpty()) { managerThread.pushBack(stack.pop()); } } } } } }
@Override public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) { FunctionDescriptor functionDescriptor = (FunctionDescriptor) bindingContext.get(DECLARATION_TO_DESCRIPTOR, expression); // working around a problem with shallow analysis if (functionDescriptor == null) return; String name = inventAnonymousClassName(expression); ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor); recordClosure( bindingTrace, expression, classDescriptor, peekFromStack(classStack), JvmClassName.byInternalName(name), true); classStack.push(classDescriptor); nameStack.push(name); super.visitFunctionLiteralExpression(expression); nameStack.pop(); classStack.pop(); }
private void setStructureViewSelection(@NotNull final String propertyName) { if (myStructureViewComponent.isDisposed()) { return; } JTree tree = myStructureViewComponent.getTree(); if (tree == null) { return; } Object root = tree.getModel().getRoot(); if (AbstractTreeUi.isLoadingChildrenFor(root)) { mySelectionChangeAlarm.cancelAllRequests(); mySelectionChangeAlarm.addRequest( new Runnable() { @Override public void run() { mySelectionChangeAlarm.cancelAllRequests(); setStructureViewSelection(propertyName); } }, 500); return; } Stack<TreeElement> toCheck = ContainerUtilRt.newStack(); toCheck.push(myStructureViewComponent.getTreeModel().getRoot()); while (!toCheck.isEmpty()) { TreeElement element = toCheck.pop(); PsiElement value = element instanceof ResourceBundlePropertyStructureViewElement ? ((ResourceBundlePropertyStructureViewElement) element).getValue() : null; if (value instanceof IProperty && propertyName.equals(((IProperty) value).getUnescapedKey())) { myStructureViewComponent.select(value, true); selectionChanged(); return; } else { for (TreeElement treeElement : element.getChildren()) { toCheck.push(treeElement); } } } }
private void doIteration(@NotNull State state) { List<Block> subBlocks = state.parentBlock.getSubBlocks(); final int subBlocksCount = subBlocks.size(); int childBlockIndex = state.getIndexOfChildBlockToProcess(); final Block block = subBlocks.get(childBlockIndex); if (state.previousBlock != null || (myCurrentWhiteSpace != null && myCurrentWhiteSpace.isIsFirstWhiteSpace())) { myCurrentSpaceProperty = (SpacingImpl) state.parentBlock.getSpacing(state.previousBlock, block); } boolean childBlockIsRightBlock = false; if (childBlockIndex == subBlocksCount - 1 && state.parentBlockIsRightBlock) { childBlockIsRightBlock = true; } final AbstractBlockWrapper wrapper = buildFrom( block, childBlockIndex, state.wrappedBlock, state.parentBlockWrap, state.parentBlock, childBlockIsRightBlock); registerExpandableIndents(block, wrapper); if (wrapper.getIndent() == null) { wrapper.setIndent((IndentImpl) block.getIndent()); } if (!state.readOnly) { try { subBlocks.set(childBlockIndex, null); // to prevent extra strong refs during model building } catch (Throwable ex) { // read-only blocks } } if (state.childBlockProcessed(block, wrapper)) { while (!myStates.isEmpty() && myStates.peek().isProcessed()) { myStates.pop(); } } }
private void processEntry( @Nullable JavaElementArrangementEntry entry, @Nullable PsiModifierListOwner modifier, @Nullable PsiElement nextPsiRoot) { if (entry == null) { return; } if (modifier != null) { parseModifiers(modifier.getModifierList(), entry); } if (nextPsiRoot == null) { return; } myStack.push(entry); try { nextPsiRoot.acceptChildren(this); } finally { myStack.pop(); } }
public static StringBuffer addDiagnosticMarkersToText( @NotNull final PsiFile psiFile, @NotNull Collection<Diagnostic> diagnostics, @NotNull Map<Diagnostic, TextDiagnostic> diagnosticToExpectedDiagnostic, @NotNull Function<PsiFile, String> getFileText) { String text = getFileText.fun(psiFile); StringBuffer result = new StringBuffer(); diagnostics = Collections2.filter( diagnostics, new Predicate<Diagnostic>() { @Override public boolean apply(Diagnostic diagnostic) { return psiFile.equals(diagnostic.getPsiFile()); } }); if (!diagnostics.isEmpty()) { List<DiagnosticDescriptor> diagnosticDescriptors = getSortedDiagnosticDescriptors(diagnostics); Stack<DiagnosticDescriptor> opened = new Stack<DiagnosticDescriptor>(); ListIterator<DiagnosticDescriptor> iterator = diagnosticDescriptors.listIterator(); DiagnosticDescriptor currentDescriptor = iterator.next(); for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); while (!opened.isEmpty() && i == opened.peek().end) { closeDiagnosticString(result); opened.pop(); } while (currentDescriptor != null && i == currentDescriptor.start) { openDiagnosticsString(result, currentDescriptor, diagnosticToExpectedDiagnostic); if (currentDescriptor.getEnd() == i) { closeDiagnosticString(result); } else { opened.push(currentDescriptor); } if (iterator.hasNext()) { currentDescriptor = iterator.next(); } else { currentDescriptor = null; } } result.append(c); } if (currentDescriptor != null) { assert currentDescriptor.start == text.length(); assert currentDescriptor.end == text.length(); openDiagnosticsString(result, currentDescriptor, diagnosticToExpectedDiagnostic); opened.push(currentDescriptor); } while (!opened.isEmpty() && text.length() == opened.peek().end) { closeDiagnosticString(result); opened.pop(); } assert opened.isEmpty() : "Stack is not empty: " + opened; } else { result.append(text); } return result; }
@Override public void visitProperty(JetProperty property) { nameStack.push(peekFromStack(nameStack) + '$' + property.getName()); super.visitProperty(property); nameStack.pop(); }
private void afterConsume(PsiBuilder builder, IElementType type) { if (type.equals(SS_VAR) && markingVar) { varMarker.done(NAMED_VAR); markingVar = false; identifierMarker = null; } if (markingTheme && type.equals(SS_THEME_VAR)) { themeMarker.done(SS_THEME_DIR); } if (type.equals(SS_STRING) && markingTheme) { PsiBuilder.Marker fullTheme = themeMarker.precede(); fullTheme.done(SS_THEME_FILE_PATH); markingTheme = false; themeMarker = null; } if (type.equals(SS_IDENTIFIER)) { if (identifierMarker == null) identifierMarker = varMarker.precede(); else identifierMarker = identifierMarker.precede(); identifierMarker.done(SS_FIELD_REFERENCE); } if (type.equals(SS_COMMENT_END)) { commentMarker.done(SS_COMMENT_STATEMENT); markingComment = false; } if (markingBlock && type.equals(SS_BLOCK_END)) { blockMarker.done(blockType); markingBlock = false; if (BLOCK_STATEMENTS.contains(blockType)) { blockStack.push(Pair.create(blockMarker, blockTokenText)); statementsStack.push(builder.mark()); } else if (blockType.equals(SS_ELSE_IF_STATEMENT) || blockType.equals(SS_ELSE_STATEMENT)) { if (!statementsStack.isEmpty()) { statementsStack.pop().doneBefore(SS_STATEMENTS, blockMarker); statementsStack.push(builder.mark()); } } else if (blockType.equals(SS_BLOCK_END_STATEMENT)) { PsiBuilder.Marker statementMarker = null; if (!statementsStack.isEmpty()) { statementMarker = statementsStack.pop(); statementMarker.doneBefore(SS_STATEMENTS, blockMarker); } if (!blockStack.isEmpty()) { Pair<PsiBuilder.Marker, String> blockLevel = blockStack.peek(); String endString = "end_" + blockLevel.getSecond(); if (endString.equals(blockTokenText)) { PsiBuilder.Marker blockMarker = blockLevel.getFirst().precede(); blockMarker.done(SS_BLOCK_STATEMENT); blockStack.pop(); } else { blockStack.pop(); if (statementMarker != null) statementMarker.drop(); } } } } if (markingBlock && !blockStartTokens.contains(type)) { blockMarker.drop(); markingBlock = false; } }
@RequiredReadAction private static boolean processInheritors( @NotNull final Processor<DotNetTypeDeclaration> consumer, @NotNull final String baseVmQName, @NotNull final SearchScope searchScope, @NotNull final SearchParameters parameters) { if (DotNetTypes.System.Object.equals(baseVmQName)) { return AllTypesSearch.search( searchScope, parameters.getProject(), parameters.getNameCondition()) .forEach( new Processor<DotNetTypeDeclaration>() { @Override public boolean process(final DotNetTypeDeclaration aClass) { ProgressIndicatorProvider.checkCanceled(); final String qname1 = ApplicationManager.getApplication() .runReadAction( new Computable<String>() { @Override @Nullable public String compute() { return aClass.getVmQName(); } }); return DotNetTypes.System.Object.equals(qname1) || consumer.process(parameters.myTransformer.fun(aClass)); } }); } final Ref<String> currentBase = Ref.create(null); final Stack<String> stack = new Stack<String>(); // there are two sets for memory optimization: it's cheaper to hold FQN than PsiClass final Set<String> processedFqns = new THashSet<String>(); // FQN of processed classes if the class has one final Processor<DotNetTypeDeclaration> processor = new Processor<DotNetTypeDeclaration>() { @Override public boolean process(final DotNetTypeDeclaration candidate) { ProgressIndicatorProvider.checkCanceled(); final Ref<Boolean> result = new Ref<Boolean>(); final Ref<String> vmQNameRef = new Ref<String>(); ApplicationManager.getApplication() .runReadAction( new Runnable() { @Override public void run() { vmQNameRef.set(candidate.getVmQName()); if (parameters.isCheckInheritance() || parameters.isCheckDeep()) { if (!candidate.isInheritor(currentBase.get(), false)) { result.set(true); return; } } if (PsiSearchScopeUtil.isInScope(searchScope, candidate)) { final String name = candidate.getName(); if (name != null && parameters.getNameCondition().value(name) && !consumer.process(parameters.myTransformer.fun(candidate))) { result.set(false); } } } }); if (!result.isNull()) { return result.get(); } if (parameters.isCheckDeep() && !isSealed(candidate)) { stack.push(vmQNameRef.get()); } return true; } }; stack.push(baseVmQName); final GlobalSearchScope projectScope = GlobalSearchScope.allScope(parameters.getProject()); while (!stack.isEmpty()) { ProgressIndicatorProvider.checkCanceled(); String vmQName = stack.pop(); if (!processedFqns.add(vmQName)) { continue; } currentBase.set(vmQName); if (!DirectTypeInheritorsSearch.search(parameters.getProject(), vmQName, projectScope, false) .forEach(processor)) { return false; } } return true; }
private static void divideInsideAndOutside( @NotNull PsiFile root, int startOffset, int endOffset, @NotNull TextRange range, @NotNull List<PsiElement> inside, @NotNull List<PsiElement> outside, boolean includeParents) { final int currentOffset = root.getTextRange().getStartOffset(); final Condition<PsiElement>[] filters = Extensions.getExtensions(CollectHighlightsUtil.EP_NAME); int offset = currentOffset; final TIntStack starts = new TIntStack(STARTING_TREE_HEIGHT); starts.push(startOffset); final Stack<PsiElement> elements = new Stack<PsiElement>(STARTING_TREE_HEIGHT); final Stack<PsiElement> children = new Stack<PsiElement>(STARTING_TREE_HEIGHT); PsiElement element = root; PsiElement child = PsiUtilBase.NULL_PSI_ELEMENT; while (true) { ProgressManager.checkCanceled(); for (Condition<PsiElement> filter : filters) { if (!filter.value(element)) { assert child == PsiUtilBase.NULL_PSI_ELEMENT; child = null; // do not want to process children break; } } boolean startChildrenVisiting; if (child == PsiUtilBase.NULL_PSI_ELEMENT) { startChildrenVisiting = true; child = element.getFirstChild(); } else { startChildrenVisiting = false; } if (child == null) { if (startChildrenVisiting) { // leaf element offset += element.getTextLength(); } int start = starts.pop(); if (startOffset <= start && offset <= endOffset) { if (range.containsRange(start, offset)) { inside.add(element); } else { outside.add(element); } } if (elements.isEmpty()) break; element = elements.pop(); child = children.pop(); } else { // composite element if (offset > endOffset) break; children.push(child.getNextSibling()); starts.push(offset); elements.push(element); element = child; child = PsiUtilBase.NULL_PSI_ELEMENT; } } if (includeParents) { PsiElement parent = !outside.isEmpty() ? outside.get(outside.size() - 1) : !inside.isEmpty() ? inside.get(inside.size() - 1) : CollectHighlightsUtil.findCommonParent(root, startOffset, endOffset); while (parent != null && parent != root) { parent = parent.getParent(); if (parent != null) outside.add(parent); } } }
@SuppressWarnings("unchecked") private static <E extends ArrangementEntry> void doArrange(Context<E> context) { // The general idea is to process entries bottom-up where every processed group belongs to the // same parent. We may not bother // with entries text ranges then. We use a list and a stack for achieving that than. // // Example: // Entry1 Entry2 // / \ / \ // Entry11 Entry12 Entry21 Entry22 // // -------------------------- // Stage 1: // list: Entry1 Entry2 <-- entries to process // stack: [0, 0, 2] <-- holds current iteration info at the following format: // (start entry index at the auxiliary list (inclusive); current // index; end index (exclusive)) // -------------------------- // Stage 2: // list: Entry1 Entry2 Entry11 Entry12 // stack: [0, 1, 2] // [2, 2, 4] // -------------------------- // Stage 3: // list: Entry1 Entry2 Entry11 Entry12 // stack: [0, 1, 2] // [2, 3, 4] // -------------------------- // Stage 4: // list: Entry1 Entry2 Entry11 Entry12 // stack: [0, 1, 2] // [2, 4, 4] // -------------------------- // arrange 'Entry11 Entry12' // -------------------------- // Stage 5: // list: Entry1 Entry2 // stack: [0, 1, 2] // -------------------------- // Stage 6: // list: Entry1 Entry2 Entry21 Entry22 // stack: [0, 2, 2] // [2, 2, 4] // -------------------------- // Stage 7: // list: Entry1 Entry2 Entry21 Entry22 // stack: [0, 2, 2] // [2, 3, 4] // -------------------------- // Stage 8: // list: Entry1 Entry2 Entry21 Entry22 // stack: [0, 2, 2] // [2, 4, 4] // -------------------------- // arrange 'Entry21 Entry22' // -------------------------- // Stage 9: // list: Entry1 Entry2 // stack: [0, 2, 2] // -------------------------- // arrange 'Entry1 Entry2' List<ArrangementEntryWrapper<E>> entries = new ArrayList<ArrangementEntryWrapper<E>>(); Stack<StackEntry> stack = new Stack<StackEntry>(); entries.addAll(context.wrappers); stack.push(new StackEntry(0, context.wrappers.size())); while (!stack.isEmpty()) { StackEntry stackEntry = stack.peek(); if (stackEntry.current >= stackEntry.end) { List<ArrangementEntryWrapper<E>> subEntries = entries.subList(stackEntry.start, stackEntry.end); if (subEntries.size() > 1) { doArrange(subEntries, context); } subEntries.clear(); stack.pop(); } else { ArrangementEntryWrapper<E> wrapper = entries.get(stackEntry.current++); List<ArrangementEntryWrapper<E>> children = wrapper.getChildren(); if (!children.isEmpty()) { entries.addAll(children); stack.push(new StackEntry(stackEntry.end, children.size())); } } } }
@Override public DfaValue pop() { myCachedHash = null; return myStack.pop(); }
private void pop() { visitors.pop(); }