Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 330556 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jdt/text/tests/JavaHeuristicScannerTest.java (+15 lines)
Lines 916-921 Link Here
916
		Assert.assertEquals("\t\t\t", indent);
916
		Assert.assertEquals("\t\t\t", indent);
917
	}
917
	}
918
918
919
	public void testContinuationIndentationOfStrings() throws Exception {
920
		fDocument.set("\tString[] i = new String[] {\n\t\t\"X.java\",\n\t\t\"public class X extends B{\"\n\t\t+ \"test\"\n\t\t+ \"    public \"};");
921
922
		String indent= fScanner.computeIndentation(73).toString();
923
		Assert.assertEquals("\t\t\t", indent);
924
		indent= fScanner.computeIndentation(84).toString();
925
		Assert.assertEquals("\t\t\t", indent);
926
927
		fDocument.set("\tString[] i = new String[] {\n\t\t\"X.java\",\n\t\t\"public class X extends B{\" +\n\t\t\"test\" +\n\t\t\"    public\"\n};");
928
929
		indent= fScanner.computeIndentation(75).toString();
930
		Assert.assertEquals("\t\t\t", indent);
931
	}
932
933
919
	public void testContinuationIndentation1() throws Exception {
934
	public void testContinuationIndentation1() throws Exception {
920
		fDocument.set("\treturn (thisIsAVeryLongName == 1 && anotherVeryLongName == 1)\n" +
935
		fDocument.set("\treturn (thisIsAVeryLongName == 1 && anotherVeryLongName == 1)\n" +
921
				"\t\t|| thisIsAVeryLongName == 2;");
936
				"\t\t|| thisIsAVeryLongName == 2;");
(-)ui/org/eclipse/jdt/internal/ui/text/JavaHeuristicScanner.java (+24 lines)
Lines 61-66 Link Here
61
	private static final char LANGLE= '<';
61
	private static final char LANGLE= '<';
62
	private static final char RANGLE= '>';
62
	private static final char RANGLE= '>';
63
63
64
	private static final char PLUS= '+';
65
64
	/**
66
	/**
65
	 * Specifies the stop condition, upon which the <code>scanXXX</code> methods will decide whether
67
	 * Specifies the stop condition, upon which the <code>scanXXX</code> methods will decide whether
66
	 * to keep scanning or not. This interface may implemented by clients.
68
	 * to keep scanning or not. This interface may implemented by clients.
Lines 334-339 Link Here
334
				return TokenLESSTHAN;
336
				return TokenLESSTHAN;
335
			case RANGLE:
337
			case RANGLE:
336
				return TokenGREATERTHAN;
338
				return TokenGREATERTHAN;
339
			case PLUS:
340
				return TokenPLUS;
337
		}
341
		}
338
342
339
		// else
343
		// else
Lines 406-411 Link Here
406
				return TokenLESSTHAN;
410
				return TokenLESSTHAN;
407
			case RANGLE:
411
			case RANGLE:
408
				return TokenGREATERTHAN;
412
				return TokenGREATERTHAN;
413
			case PLUS:
414
				return TokenPLUS;
409
		}
415
		}
410
416
411
		// else
417
		// else
Lines 675-680 Link Here
675
	}
681
	}
676
682
677
	/**
683
	/**
684
	 * Finds the highest position in <code>fDocument</code> such that the position is &lt;=
685
	 * <code>position</code> and &gt; <code>bound</code> and
686
	 * <code>Character.isWhitespace(fDocument.getChar(pos))</code> evaluates to <code>false</code>
687
	 * and the position can be in any partition.
688
	 * 
689
	 * @param position the first character position in <code>fDocument</code> to be considered
690
	 * @param bound the first position in <code>fDocument</code> to not consider any more, with
691
	 *            <code>bound</code> &lt; <code>position</code>, or <code>UNBOUND</code>
692
	 * @return the highest position of a non-whitespace character in (<code>bound</code>,
693
	 *         <code>position</code>] that resides in a Java partition, or <code>NOT_FOUND</code> if
694
	 *         none can be found
695
	 * @since 3.7
696
	 */
697
	public int findNonWhitespaceBackwardInAnyPartition(int position, int bound) {
698
		return scanBackward(position, bound, fNonWS);
699
	}
700
701
	/**
678
	 * Finds the lowest position <code>p</code> in <code>fDocument</code> such that <code>start</code> &lt;= p &lt;
702
	 * Finds the lowest position <code>p</code> in <code>fDocument</code> such that <code>start</code> &lt;= p &lt;
679
	 * <code>bound</code> and <code>condition.stop(fDocument.getChar(p), p)</code> evaluates to <code>true</code>.
703
	 * <code>bound</code> and <code>condition.stop(fDocument.getChar(p), p)</code> evaluates to <code>true</code>.
680
	 *
704
	 *
(-)ui/org/eclipse/jdt/internal/ui/text/JavaIndenter.java (+47 lines)
Lines 22-27 Link Here
22
22
23
import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil;
23
import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil;
24
24
25
import org.eclipse.jdt.internal.ui.JavaPlugin;
25
26
26
/**
27
/**
27
 * Uses the {@link org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner} to
28
 * Uses the {@link org.eclipse.jdt.internal.ui.text.JavaHeuristicScanner} to
Lines 787-792 Link Here
787
					case Symbols.TokenTHROWS:
788
					case Symbols.TokenTHROWS:
788
						throwsClause= true;
789
						throwsClause= true;
789
						break;
790
						break;
791
					case Symbols.TokenPLUS:
792
						int position= handleStringContinuation(offset);
793
						if (position != JavaHeuristicScanner.NOT_FOUND) {
794
							fAlign= JavaHeuristicScanner.NOT_FOUND;
795
							fIndent= fPrefs.prefContinuationIndent;
796
							return position;
797
						}
798
						break;
790
				}
799
				}
791
			} catch (BadLocationException e) {
800
			} catch (BadLocationException e) {
792
			}
801
			}
Lines 804-809 Link Here
804
	}
813
	}
805
814
806
	/**
815
	/**
816
	 * Specifically handles the case of extra indentation for second line of string continuation.
817
	 * 
818
	 * @param offset the offset for which the reference is computed
819
	 * @return the reference statement relative to which <code>offset</code> should be indented, or
820
	 *         {@link JavaHeuristicScanner#NOT_FOUND}
821
	 * @since 3.7
822
	 */
823
	private int handleStringContinuation(int offset) {
824
		int prevNonWSCharPosition= fScanner.findNonWhitespaceBackwardInAnyPartition(offset - 1, JavaHeuristicScanner.UNBOUND);
825
		if (prevNonWSCharPosition != JavaHeuristicScanner.NOT_FOUND) {
826
			try {
827
				char c= fDocument.getChar(prevNonWSCharPosition);
828
				if (c == '"' || c == '+') {
829
					int initialLine= fDocument.getLineOfOffset(offset);
830
					nextToken(offset);
831
					while (fToken == Symbols.TokenPLUS) {
832
						if ((initialLine - fLine) > 1)
833
							return JavaHeuristicScanner.NOT_FOUND;
834
						nextToken();
835
					}
836
					int lineDiff= initialLine - fLine;
837
					if (lineDiff > 0) {
838
						int bound= fDocument.getLineOffset(fLine) + fDocument.getLineLength(fLine) - 1;
839
						int nextNonWSCharPosition= fScanner.findNonWhitespaceForwardInAnyPartition(fPosition + 1, bound);
840
						if (lineDiff < 3 && fPreviousPos != offset && nextNonWSCharPosition != JavaHeuristicScanner.NOT_FOUND && fDocument.getChar(nextNonWSCharPosition) != '"')
841
							return fPreviousPos;
842
						else
843
							return fPosition;
844
					}
845
				}
846
			} catch (BadLocationException e) {
847
				JavaPlugin.log(e);
848
			}
849
		}
850
		return JavaHeuristicScanner.NOT_FOUND;
851
	}
852
853
	/**
807
	 * Returns the reference position regarding to indentation for <code>position</code>, or
854
	 * Returns the reference position regarding to indentation for <code>position</code>, or
808
	 * <code>NOT_FOUND</code>.<code>fIndent</code> will contain the relative indentation (in
855
	 * <code>NOT_FOUND</code>.<code>fIndent</code> will contain the relative indentation (in
809
	 * indentation units, not characters) after the call. If there is a special alignment (e.g. for
856
	 * indentation units, not characters) after the call. If there is a special alignment (e.g. for
(-)ui/org/eclipse/jdt/internal/ui/text/Symbols.java (+1 lines)
Lines 32-37 Link Here
32
	int TokenEQUAL= 12;
32
	int TokenEQUAL= 12;
33
	int TokenLESSTHAN= 13;
33
	int TokenLESSTHAN= 13;
34
	int TokenGREATERTHAN= 14;
34
	int TokenGREATERTHAN= 14;
35
	int TokenPLUS= 15;
35
	int TokenIF= 109;
36
	int TokenIF= 109;
36
	int TokenDO= 1010;
37
	int TokenDO= 1010;
37
	int TokenFOR= 1011;
38
	int TokenFOR= 1011;
(-)ui/org/eclipse/jdt/internal/ui/text/java/JavaAutoIndentStrategy.java (-29 / +31 lines)
Lines 686-722 Link Here
686
			boolean changed= false;
686
			boolean changed= false;
687
			for (int l= first; l < lines; l++) { // we don't change the number of lines while adding indents
687
			for (int l= first; l < lines; l++) { // we don't change the number of lines while adding indents
688
688
689
				IRegion r= temp.getLineInformation(l);
689
				if (!isIndentDetected) {
690
				int lineOffset= r.getOffset();
690
					IRegion r= temp.getLineInformation(l);
691
				int lineLength= r.getLength();
691
					int lineOffset= r.getOffset();
692
692
					int lineLength= r.getLength();
693
				if (lineLength == 0) // don't modify empty lines
693
694
					continue;
694
					if (lineLength == 0) // don't modify empty lines
695
695
						continue;
696
696
697
				// indent the first pasted line
697
698
				String current= getCurrentIndent(temp, l);
698
					// indent the first pasted line
699
				StringBuffer correct= indenter.computeIndentation(lineOffset);
699
					String current= getCurrentIndent(temp, l);
700
				if (correct == null)
700
					StringBuffer correct= indenter.computeIndentation(lineOffset);
701
					return; // bail out
701
					if (correct == null)
702
702
						return; // bail out
703
				insertLength= subtractIndent(correct, current, addition, tabLength);
703
704
				if (!isIndentDetected && l != first && temp.get(lineOffset, lineLength).trim().length() != 0) {
704
					insertLength= subtractIndent(correct, current, addition, tabLength);
705
					isIndentDetected= true;
705
					if (l != first && temp.get(lineOffset, lineLength).trim().length() != 0) {
706
					if (insertLength == 0) {
706
						isIndentDetected= true;
707
						// no adjustment needed, bail out
707
						if (insertLength == 0) {
708
						if (firstLine == 0) {
708
							// no adjustment needed, bail out
709
							// but we still need to adjust the first line
709
							if (firstLine == 0) {
710
							command.offset= newOffset;
710
								// but we still need to adjust the first line
711
							command.length= newLength;
711
								command.offset= newOffset;
712
							if (changed)
712
								command.length= newLength;
713
								break; // still need to get the leading indent of the first line
713
								if (changed)
714
									break; // still need to get the leading indent of the first line
715
							}
716
							return;
714
						}
717
						}
715
						return;
718
					} else {
719
						changed= insertLength != 0;
716
					}
720
					}
717
					removeJavaStuff(temp);
718
				} else {
719
					changed= insertLength != 0;
720
				}
721
				}
721
722
722
				// relatively indent all pasted lines
723
				// relatively indent all pasted lines
Lines 727-732 Link Here
727
728
728
			}
729
			}
729
730
731
			removeJavaStuff(temp);
730
			temp.stopRewriteSession(session);
732
			temp.stopRewriteSession(session);
731
			newText= temp.get(prefix.length(), temp.getLength() - prefix.length());
733
			newText= temp.get(prefix.length(), temp.getLength() - prefix.length());
732
734

Return to bug 330556