View | Details | Raw Unified | Return to bug 372128 | Differences between
and this patch

Collapse All | Expand All

(-)a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/JavaPairMatcher.java (-15 / +92 lines)
Lines 68-104 Link Here
68
	}
68
	}
69
69
70
	/**
70
	/**
71
	 * Returns true if the character at the specified offset is a
71
	 * Returns true if the character at the specified offset is a less-than sign, rather than an
72
	 * less-than sign, rather than an type parameter list open
72
	 * type parameter list open angle bracket.
73
	 * angle bracket.
73
	 * 
74
	 *
75
	 * @param document a document
74
	 * @param document a document
76
	 * @param offset an offset within the document
75
	 * @param offset an offset within the document
77
	 * @return true if the character at the specified offset is not
76
	 * @return true if the character at the specified offset is a less-than sign
78
	 *   a type parameter start bracket
79
	 * @throws BadLocationException if offset is invalid in the document
77
	 * @throws BadLocationException if offset is invalid in the document
80
	 */
78
	 */
81
	private boolean isLessThanOperator(IDocument document, int offset) throws BadLocationException {
79
	private boolean isLessThanOperator(IDocument document, int offset) throws BadLocationException {
82
		if (offset < 0) return false;
80
		if (offset < 0) return false;
83
		JavaHeuristicScanner scanner= new JavaHeuristicScanner(document, IJavaPartitions.JAVA_PARTITIONING, TextUtilities.getContentType(document, IJavaPartitions.JAVA_PARTITIONING, offset, false));
81
		String contentType= TextUtilities.getContentType(document, IJavaPartitions.JAVA_PARTITIONING, offset, false);
84
		return !isTypeParameterBracket(offset, document, scanner);
82
		if (!IDocument.DEFAULT_CONTENT_TYPE.equals(contentType)) {
83
			return false;
84
		}
85
		JavaHeuristicScanner scanner= new JavaHeuristicScanner(document, IJavaPartitions.JAVA_PARTITIONING, contentType);
86
		return !isTypeParameterOpeningBracket(offset, document, scanner);
85
	}
87
	}
86
88
87
	/**
89
	/**
88
	 * Checks if the angular bracket at <code>offset</code> is a type
90
	 * Checks if the angular bracket at <code>offset</code> is a type parameter opening bracket.
89
	 * parameter bracket.
91
	 * 
90
	 *
91
	 * @param offset the offset of the opening bracket
92
	 * @param offset the offset of the opening bracket
92
	 * @param document the document
93
	 * @param document the document
93
	 * @param scanner a java heuristic scanner on <code>document</code>
94
	 * @param scanner a java heuristic scanner on <code>document</code>
94
	 * @return <code>true</code> if the bracket is part of a type parameter,
95
	 * @return <code>true</code> if the bracket is part of a type parameter, <code>false</code>
95
	 *         <code>false</code> otherwise
96
	 *         otherwise
96
	 * @since 3.1
97
	 * @since 3.1
97
	 */
98
	 */
98
	private boolean isTypeParameterBracket(int offset, IDocument document, JavaHeuristicScanner scanner) {
99
	private boolean isTypeParameterOpeningBracket(int offset, IDocument document, JavaHeuristicScanner scanner) {
99
		/*
100
		/*
100
		 * type parameter come after braces (closing or opening), semicolons, or after
101
		 * type parameter come after braces (closing or opening), semicolons, or after
101
		 * a Type name (heuristic: starts with capital character, or after a modifier
102
		 * a Type name (heuristic: starts with capital character), or after a modifier
102
		 * keyword in a method declaration (visibility, static, synchronized, final)
103
		 * keyword in a method declaration (visibility, static, synchronized, final)
103
		 */
104
		 */
104
105
Lines 116-121 Link Here
116
					|| prevToken == Symbols.TokenSTATIC
117
					|| prevToken == Symbols.TokenSTATIC
117
					|| (prevToken == Symbols.TokenIDENT && isTypeParameterIntroducer(previous))
118
					|| (prevToken == Symbols.TokenIDENT && isTypeParameterIntroducer(previous))
118
					|| prevToken == Symbols.TokenEOF)
119
					|| prevToken == Symbols.TokenEOF)
120
				return true;
121
		} catch (BadLocationException e) {
122
			return false;
123
		}
124
125
		return false;
126
	}
127
128
	/**
129
	 * Returns true if the character at the specified offset is a greater-than sign, rather than an
130
	 * type parameter list close angle bracket.
131
	 * 
132
	 * @param document a document
133
	 * @param offset an offset within the document
134
	 * @return true if the character at the specified offset is a greater-than sign
135
	 * @throws BadLocationException if offset is invalid in the document
136
	 */
137
	private boolean isGreaterThanOperator(IDocument document, int offset) throws BadLocationException {
138
		if (offset < 0)
139
			return false;
140
		String contentType= TextUtilities.getContentType(document, IJavaPartitions.JAVA_PARTITIONING, offset, false);
141
		if (!IDocument.DEFAULT_CONTENT_TYPE.equals(contentType)) {
142
			return false;
143
		}
144
		JavaHeuristicScanner scanner= new JavaHeuristicScanner(document, IJavaPartitions.JAVA_PARTITIONING, contentType);
145
		return !isTypeParameterClosingBracket(offset, document, scanner);
146
	}
147
148
	/**
149
	 * Checks if the angular bracket at <code>offset</code> is a type parameter closing bracket.
150
	 * 
151
	 * @param offset the offset of the closing bracket
152
	 * @param document the document
153
	 * @param scanner a java heuristic scanner on <code>document</code>
154
	 * @return <code>true</code> if the bracket is part of a type parameter, <code>false</code>
155
	 *         otherwise
156
	 * @since 3.8
157
	 */
158
	private boolean isTypeParameterClosingBracket(int offset, IDocument document, JavaHeuristicScanner scanner) {
159
		/*
160
		 * type parameter closing brackets come after question marks, other type parameter
161
		 * closing brackets, or after a Type name (heuristic: starts with capital character)
162
		 */
163
164
		try {
165
			IRegion line= document.getLineInformationOfOffset(offset);
166
167
			int prevToken= scanner.previousToken(offset - 1, line.getOffset());
168
			int prevTokenOffset= scanner.getPosition() + 1;
169
			String previous= prevToken == Symbols.TokenEOF ? null : document.get(prevTokenOffset, offset - prevTokenOffset).trim();
170
171
			if ((prevToken == Symbols.TokenIDENT && (previous.length() > 0 && Character.isUpperCase(previous.charAt(0))))
172
					|| prevToken == Symbols.TokenEOF
173
					|| prevToken == Symbols.TokenGREATERTHAN
174
					|| prevToken == Symbols.TokenQUESTIONMARK)
119
				return true;
175
				return true;
120
		} catch (BadLocationException e) {
176
		} catch (BadLocationException e) {
121
			return false;
177
			return false;
Lines 156-159 Link Here
156
		else
212
		else
157
			fHighlightAngularBrackets= false;
213
			fHighlightAngularBrackets= false;
158
	}
214
	}
215
216
	/*
217
	 * @see org.eclipse.jface.text.source.DefaultCharacterPairMatcher#index(org.eclipse.jface.text.IDocument, char, int)
218
	 */
219
	@Override
220
	protected int getCharacterType(char ch, IDocument document, int offset) {
221
		try {
222
			if (ch == '<') {
223
				if (isLessThanOperator(document, offset)) {
224
					return -1;
225
				}
226
			} else if (ch == '>') {
227
				if (isGreaterThanOperator(document, offset)) {
228
					return -1;
229
				}
230
			}
231
		} catch (BadLocationException e) {
232
			return -1;
233
		}
234
		return super.getCharacterType(ch, document, offset);
235
	}
159
}
236
}

Return to bug 372128