/** * Skips the scope opened by <code>token</code>. * * @param scanner the scanner * @param start the start position * @param token the token * @return the position after the scope or <code>JavaHeuristicScanner.NOT_FOUND</code> */ private static int skipScope(JavaHeuristicScanner scanner, int start, int token) { int openToken = token; int closeToken; switch (token) { case Symbols.TokenLPAREN: closeToken = Symbols.TokenRPAREN; break; case Symbols.TokenLBRACKET: closeToken = Symbols.TokenRBRACKET; break; case Symbols.TokenLBRACE: closeToken = Symbols.TokenRBRACE; break; default: Assert.isTrue(false); return -1; // dummy } int depth = 1; int p = start; while (true) { int tok = scanner.nextToken(p, JavaHeuristicScanner.UNBOUND); p = scanner.getPosition(); if (tok == openToken) { depth++; } else if (tok == closeToken) { depth--; if (depth == 0) return p + 1; } else if (tok == Symbols.TokenEOF) { return JavaHeuristicScanner.NOT_FOUND; } } }
private int getPeerPosition(IDocument document, DocumentCommand command) { if (document.getLength() == 0) return 0; /* * Search for scope closers in the pasted text and find their opening peers * in the document. */ Document pasted = new Document(command.text); installJavaStuff(pasted); int firstPeer = command.offset; JavaHeuristicScanner pScanner = new JavaHeuristicScanner(pasted); JavaHeuristicScanner dScanner = new JavaHeuristicScanner(document); // add scope relevant after context to peer search int afterToken = dScanner.nextToken(command.offset + command.length, JavaHeuristicScanner.UNBOUND); try { switch (afterToken) { case Symbols.TokenRBRACE: pasted.replace(pasted.getLength(), 0, "}"); // $NON-NLS-1$ break; case Symbols.TokenRPAREN: pasted.replace(pasted.getLength(), 0, ")"); // $NON-NLS-1$ break; case Symbols.TokenRBRACKET: pasted.replace(pasted.getLength(), 0, "]"); // $NON-NLS-1$ break; } } catch (BadLocationException e) { // cannot happen Assert.isTrue(false); } int pPos = 0; // paste text position (increasing from 0) int dPos = Math.max(0, command.offset - 1); // document position (decreasing from paste offset) while (true) { int token = pScanner.nextToken(pPos, JavaHeuristicScanner.UNBOUND); pPos = pScanner.getPosition(); switch (token) { case Symbols.TokenLBRACE: case Symbols.TokenLBRACKET: case Symbols.TokenLPAREN: pPos = skipScope(pScanner, pPos, token); if (pPos == JavaHeuristicScanner.NOT_FOUND) return firstPeer; break; // closed scope -> keep searching case Symbols.TokenRBRACE: int peer = dScanner.findOpeningPeer(dPos, '{', '}'); dPos = peer - 1; if (peer == JavaHeuristicScanner.NOT_FOUND) return firstPeer; firstPeer = peer; break; // keep searching case Symbols.TokenRBRACKET: peer = dScanner.findOpeningPeer(dPos, '[', ']'); dPos = peer - 1; if (peer == JavaHeuristicScanner.NOT_FOUND) return firstPeer; firstPeer = peer; break; // keep searching case Symbols.TokenRPAREN: peer = dScanner.findOpeningPeer(dPos, '(', ')'); dPos = peer - 1; if (peer == JavaHeuristicScanner.NOT_FOUND) return firstPeer; firstPeer = peer; break; // keep searching case Symbols.TokenCASE: case Symbols.TokenDEFAULT: JavaIndenter indenter = new JavaIndenter(document, dScanner, fProject); peer = indenter.findReferencePosition(dPos, false, false, false, true); if (peer == JavaHeuristicScanner.NOT_FOUND) return firstPeer; firstPeer = peer; break; // keep searching case Symbols.TokenEOF: return firstPeer; default: // keep searching } } }
private void smartIndentUponE(IDocument d, DocumentCommand c) { if (c.offset < 4 || d.getLength() == 0) return; try { String content = d.get(c.offset - 3, 3); if (content.equals("els")) { // $NON-NLS-1$ JavaHeuristicScanner scanner = new JavaHeuristicScanner(d); int p = c.offset - 3; // current line int line = d.getLineOfOffset(p); int lineOffset = d.getLineOffset(line); // make sure we don't have any leading comments etc. if (d.get(lineOffset, p - lineOffset).trim().length() != 0) return; // line of last Java code int pos = scanner.findNonWhitespaceBackward(p - 1, JavaHeuristicScanner.UNBOUND); if (pos == -1) return; int lastLine = d.getLineOfOffset(pos); // only shift if the last java line is further up and is a braceless block candidate if (lastLine < line) { JavaIndenter indenter = new JavaIndenter(d, scanner, fProject); int ref = indenter.findReferencePosition(p, true, false, false, false); if (ref == JavaHeuristicScanner.NOT_FOUND) return; int refLine = d.getLineOfOffset(ref); String indent = getIndentOfLine(d, refLine); if (indent != null) { c.text = indent.toString() + "else"; // $NON-NLS-1$ c.length += c.offset - lineOffset; c.offset = lineOffset; } } return; } if (content.equals("cas")) { // $NON-NLS-1$ JavaHeuristicScanner scanner = new JavaHeuristicScanner(d); int p = c.offset - 3; // current line int line = d.getLineOfOffset(p); int lineOffset = d.getLineOffset(line); // make sure we don't have any leading comments etc. if (d.get(lineOffset, p - lineOffset).trim().length() != 0) return; // line of last Java code int pos = scanner.findNonWhitespaceBackward(p - 1, JavaHeuristicScanner.UNBOUND); if (pos == -1) return; int lastLine = d.getLineOfOffset(pos); // only shift if the last java line is further up and is a braceless block candidate if (lastLine < line) { JavaIndenter indenter = new JavaIndenter(d, scanner, fProject); int ref = indenter.findReferencePosition(p, false, false, false, true); if (ref == JavaHeuristicScanner.NOT_FOUND) return; int refLine = d.getLineOfOffset(ref); int nextToken = scanner.nextToken(ref, JavaHeuristicScanner.UNBOUND); String indent; if (nextToken == Symbols.TokenCASE || nextToken == Symbols.TokenDEFAULT) indent = getIndentOfLine(d, refLine); else // at the brace of the switch indent = indenter.computeIndentation(p).toString(); if (indent != null) { c.text = indent.toString() + "case"; // $NON-NLS-1$ c.length += c.offset - lineOffset; c.offset = lineOffset; } } return; } } catch (BadLocationException e) { JavaPlugin.log(e); } }