Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 00f5ad27588cf1dcc1bc8a296bebc500259d1dee (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
/*******************************************************************************
 * Copyright (c) 2000, 2007 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.jdt.internal.formatter.comment;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jface.text.Position;

/**
 * Range in a comment region in comment region coordinates.
 *
 * @since 3.0
 */
public class CommentRange extends Position implements ICommentAttributes, IHtmlTagDelimiters {

	/** The attributes of this range */
	private int fAttributes= 0;

	/**
	 * Creates a new comment range.
	 *
	 * @param position offset of the range
	 * @param count length of the range
	 */
	public CommentRange(final int position, final int count) {
		super(position, count);
	}

	/**
	 * Is the attribute <code>attribute</code> true?
	 *
	 * @param attribute the attribute to get
	 * @return <code>true</code> iff this attribute is <code>true</code>,
	 *         <code>false</code> otherwise
	 */
	protected final boolean hasAttribute(final int attribute) {
		return (this.fAttributes & attribute) == attribute;
	}

	/**
	 * Does this comment range contain a closing HTML tag?
	 *
	 * @param token token belonging to the comment range
	 * @param tag the HTML tag to check
	 * @return <code>true</code> iff this comment range contains a closing
	 *         html tag, <code>false</code> otherwise
	 */
	protected final boolean isClosingTag(final char[] token, final char[] tag) {

		boolean result= (CharOperation.indexOf(HTML_CLOSE_PREFIX, token, false) == 0)
				&& token[token.length - 1] == HTML_TAG_POSTFIX;
		if (result) {

			setAttribute(COMMENT_CLOSE);
			result= CharOperation.equals(tag, token, HTML_CLOSE_PREFIX.length, token.length - 1, false);
		}
		return result;
	}

	/**
	 * Does this comment range contain an opening HTML tag?
	 *
	 * @param token token belonging to the comment range
	 * @param tag the HTML tag to check
	 * @return <code>true</code> iff this comment range contains an
	 *         opening html tag, <code>false</code> otherwise
	 */
	protected final boolean isOpeningTag(final char[] token, final char[] tag) {

		boolean result= token.length > 0
				&& token[0] == HTML_TAG_PREFIX
				&& (CharOperation.indexOf(HTML_CLOSE_PREFIX, token, false) != 0)
				&& token[token.length - 1] == HTML_TAG_POSTFIX;
		if (result) {

			setAttribute(COMMENT_OPEN);
			result= CharOperation.indexOf(tag, token, false) == 1;
		}
		return result;
	}

	/**
	 * Mark the comment range with the occurred HTML tags.
	 *
	 * @param tags the HTML tags to test for their occurrence
	 * @param token token belonging to the comment range
	 * @param attribute attribute to set if a HTML tag is present
	 * @param open <code>true</code> iff opening tags should be marked,
	 *                <code>false</code> otherwise
	 * @param close <code>true</code> iff closing tags should be marked,
	 *                <code>false</code> otherwise
	 */
	protected final void markHtmlTag(final char[][] tags, final char[] token, final int attribute, final boolean open, final boolean close) {
		if (token[0] == HTML_TAG_PREFIX && token[token.length - 1] == HTML_TAG_POSTFIX) {

			char[] tag= null;
			boolean isOpen= false;
			boolean isClose= false;

			for (int index= 0; index < tags.length; index++) {

				tag= tags[index];

				isOpen= isOpeningTag(token, tag);
				isClose= isClosingTag(token, tag);

				if ((open && isOpen) || (close && isClose)) {

					setAttribute(attribute);
					break;
				}
			}
		}
	}

	/**
	 * Mark the comment range with the occurred tags.
	 *
	 * @param tags the tags to test for their occurrence
	 * @param prefix the prefix which is common to all the tags to test
	 * @param token the token belonging to the comment range
	 * @param attribute attribute to set if a tag is present
	 */
	protected final void markPrefixTag(final char[][] tags, final char prefix, final char[] token, final int attribute) {

		if (token[0] == prefix) {

			char[] tag= null;
			for (int index= 0; index < tags.length; index++) {

				tag= tags[index];
				if (CharOperation.equals(token, tag)) {

					setAttribute(attribute);
					break;
				}
			}
		}
	}

	/**
	 * Marks the comment range with the HTML range tag.
	 *
	 * @param token the token belonging to the comment range
	 * @param tag the HTML tag which confines the HTML range
	 * @param level the nesting level of the current HTML range
	 * @param key the key of the attribute to set if the comment range is in
	 *                the HTML range
	 * @param html <code>true</code> iff the HTML tags in this HTML range
	 *                should be marked too, <code>false</code> otherwise
	 * @return the new nesting level of the HTML range
	 */
	protected final int markTagRange(final char[] token, final char[] tag, int level, final int key, final boolean html) {

		if (isOpeningTag(token, tag)) {
			if (level++ > 0)
				setAttribute(key);
		} else if (isClosingTag(token, tag)) {
			if (--level > 0)
				setAttribute(key);
		} else if (level > 0) {
			if (html || !hasAttribute(COMMENT_HTML))
				setAttribute(key);
		}
		return level;
	}

	/**
	 * Moves this comment range.
	 *
	 * @param delta the delta to move the range
	 */
	public final void move(final int delta) {
		this.offset += delta;
	}

	/**
	 * Set the attribute <code>attribute</code> to true.
	 *
	 * @param attribute the attribute to set.
	 */
	protected final void setAttribute(final int attribute) {
		this.fAttributes |= attribute;
	}

	/**
	 * Trims this comment range at the beginning.
	 *
	 * @param delta amount to trim the range
	 */
	public final void trimBegin(final int delta) {
		this.offset += delta;
		this.length -= delta;
	}

	/**
	 * Trims this comment range at the end.
	 *
	 * @param delta amount to trim the range
	 */
	public final void trimEnd(final int delta) {
		this.length += delta;
	}

	/*
	 * @see java.lang.Object#toString()
	 * @since 3.1
	 */
	public String toString() {
		List attributes= new ArrayList();
		if (hasAttribute(COMMENT_BLANKLINE))
			attributes.add("COMMENT_BLANKLINE"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_BREAK))
			attributes.add("COMMENT_BREAK"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_CLOSE))
			attributes.add("COMMENT_CLOSE"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_CODE))
			attributes.add("COMMENT_CODE"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_HTML))
			attributes.add("COMMENT_HTML"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_IMMUTABLE))
			attributes.add("COMMENT_IMMUTABLE"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_NEWLINE))
			attributes.add("COMMENT_NEWLINE"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_OPEN))
			attributes.add("COMMENT_OPEN"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_PARAGRAPH))
			attributes.add("COMMENT_PARAGRAPH"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_PARAMETER))
			attributes.add("COMMENT_PARAMETER"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_ROOT))
			attributes.add("COMMENT_ROOT"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_SEPARATOR))
			attributes.add("COMMENT_SEPARATOR"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_FIRST_TOKEN))
			attributes.add("COMMENT_FIRST_TOKEN"); //$NON-NLS-1$
		if (hasAttribute(COMMENT_STARTS_WITH_RANGE_DELIMITER))
			attributes.add("COMMENT_STARTS_WITH_RANGE_DELIMITER"); //$NON-NLS-1$

		StringBuffer buf= new StringBuffer("CommentRange [" + this.offset + "+" + this.length + "] {"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		for (Iterator it= attributes.iterator(); it.hasNext();) {
			String string= (String) it.next();
			buf.append(string);
			if (it.hasNext())
				buf.append(", "); //$NON-NLS-1$
		}

		return buf.toString() + "}"; //$NON-NLS-1$
	}
}

Back to the top