1 /**********************************************************************
2  Copyright (c) 2000, 2002 IBM Corp. and others.
3  All rights reserved. This program and the accompanying materials
4  are made available under the terms of the Common Public License v1.0
5  which accompanies this distribution, and is available at
6  http://www.eclipse.org/legal/cpl-v10.html
7 
8  Contributors:
9  IBM Corporation - Initial implementation
10  **********************************************************************/
11 package net.sourceforge.phpdt.internal.ui.text.phpdoc;
12 
13 import java.util.ArrayList;
14 import java.util.List;
15 
16 import net.sourceforge.phpdt.internal.ui.text.AbstractJavaScanner;
17 import net.sourceforge.phpdt.ui.text.IColorManager;
18 import net.sourceforge.phpeclipse.IPreferenceConstants;
19 import net.sourceforge.phpeclipse.phpeditor.util.PHPWhitespaceDetector;
20 
21 import org.eclipse.jface.preference.IPreferenceStore;
22 import org.eclipse.jface.text.BadLocationException;
23 import org.eclipse.jface.text.IDocument;
24 import org.eclipse.jface.text.rules.ICharacterScanner;
25 import org.eclipse.jface.text.rules.IToken;
26 import org.eclipse.jface.text.rules.IWordDetector;
27 import org.eclipse.jface.text.rules.SingleLineRule;
28 import org.eclipse.jface.text.rules.Token;
29 import org.eclipse.jface.text.rules.WhitespaceRule;
30 import org.eclipse.jface.text.rules.WordRule;
31 
32 /**
33  * A rule based PHPDoc scanner.
34  */
35 public final class PHPDocCodeScanner extends AbstractJavaScanner {
36 
37 	/**
38 	 * A key word detector.
39 	 */
40 	static class JavaDocKeywordDetector implements IWordDetector {
41 
42 		/**
43 		 * @see IWordDetector#isWordStart
44 		 */
isWordStart(char c)45 		public boolean isWordStart(char c) {
46 			return (c == '@');
47 		}
48 
49 		/**
50 		 * @see IWordDetector#isWordPart
51 		 */
isWordPart(char c)52 		public boolean isWordPart(char c) {
53 			return Character.isLetter(c);
54 		}
55 	};
56 
57 	/**
58 	 * Detector for HTML comment delimiters.
59 	 */
60 	static class HTMLCommentDetector implements IWordDetector {
61 
62 		/**
63 		 * @see IWordDetector#isWordStart
64 		 */
isWordStart(char c)65 		public boolean isWordStart(char c) {
66 			return (c == '<' || c == '-');
67 		}
68 
69 		/**
70 		 * @see IWordDetector#isWordPart
71 		 */
isWordPart(char c)72 		public boolean isWordPart(char c) {
73 			return (c == '-' || c == '!' || c == '>');
74 		}
75 	};
76 
77 	class TagRule extends SingleLineRule {
78 
79 		/*
80 		 * @see SingleLineRule
81 		 */
TagRule(IToken token)82 		public TagRule(IToken token) {
83 			super("<", ">", token, (char) 0); //$NON-NLS-2$ //$NON-NLS-1$
84 		}
85 
86 		/*
87 		 * @see SingleLineRule
88 		 */
TagRule(IToken token, char escapeCharacter)89 		public TagRule(IToken token, char escapeCharacter) {
90 			super("<", ">", token, escapeCharacter); //$NON-NLS-2$ //$NON-NLS-1$
91 		}
92 
checkForWhitespace(ICharacterScanner scanner)93 		private IToken checkForWhitespace(ICharacterScanner scanner) {
94 
95 			try {
96 
97 				char c = getDocument().getChar(getTokenOffset() + 1);
98 				if (!Character.isWhitespace(c))
99 					return fToken;
100 
101 			} catch (BadLocationException x) {
102 			}
103 
104 			return Token.UNDEFINED;
105 		}
106 
107 		/*
108 		 * @see PatternRule#evaluate(ICharacterScanner)
109 		 */
evaluate(ICharacterScanner scanner)110 		public IToken evaluate(ICharacterScanner scanner) {
111 			IToken result = super.evaluate(scanner);
112 			if (result == fToken)
113 				return checkForWhitespace(scanner);
114 			return result;
115 		}
116 	};
117 
118 	private static String[] fgKeywords = {"@author", "@deprecated", "@exception", "@link", "@param", "@return", "@see", "@since", "@throws", "@value", "@version", "@license", "@abstract", "@access", "@category",
119 		"@copyright", "@example", "@final", "@filesource", "@global", "@ignore", "@internal", "@link", "@method", "@name", "@package", "@param", "@property", "@static",
120 		"@staticvar", "@subpackage", "@todo", "@tutorial", "@uses", "@var","@id", "inheritdoc", "@property-read", "@property-write", "@source" }; //$NON-NLS-12$ //$NON-NLS-11$ //$NON-NLS-10$ //$NON-NLS-7$ //$NON-NLS-9$ //$NON-NLS-8$ //$NON-NLS-6$ //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
121 
122 	private static String[] fgTokenProperties = {
123 			IPreferenceConstants.PHPDOC_KEYWORD,
124 			IPreferenceConstants.PHPDOC_TAG, IPreferenceConstants.PHPDOC_LINK,
125 			IPreferenceConstants.PHPDOC_DEFAULT };
126 
PHPDocCodeScanner(IColorManager manager, IPreferenceStore store)127 	public PHPDocCodeScanner(IColorManager manager, IPreferenceStore store) {
128 		super(manager, store);
129 		initialize();
130 	}
131 
getDocument()132 	public IDocument getDocument() {
133 		return fDocument;
134 	}
135 
136 	/*
137 	 * @see AbstractJavaScanner#getTokenProperties()
138 	 */
getTokenProperties()139 	protected String[] getTokenProperties() {
140 		return fgTokenProperties;
141 	}
142 
143 	/*
144 	 * @see AbstractJavaScanner#createRules()
145 	 */
createRules()146 	protected List createRules() {
147 
148 		List list = new ArrayList();
149 
150 		// Add rule for tags.
151 		Token token = getToken(IPreferenceConstants.PHPDOC_TAG);
152 		list.add(new TagRule(token));
153 
154 		// Add rule for HTML comments
155 		WordRule wordRule = new WordRule(new HTMLCommentDetector(), token);
156 		wordRule.addWord("<!--", token); //$NON-NLS-1$
157 		wordRule.addWord("--!>", token); //$NON-NLS-1$
158 		list.add(wordRule);
159 
160 		// Add rule for links.
161 		token = getToken(IPreferenceConstants.PHPDOC_LINK);
162 		list.add(new SingleLineRule("{@link", "}", token)); //$NON-NLS-2$ //$NON-NLS-1$
163 
164 		// Add generic whitespace rule.
165 		list.add(new WhitespaceRule(new PHPWhitespaceDetector()));
166 
167 		// Add word rule for keywords.
168 		token = getToken(IPreferenceConstants.PHPDOC_DEFAULT);
169 		wordRule = new WordRule(new JavaDocKeywordDetector(), token);
170 
171 		token = getToken(IPreferenceConstants.PHPDOC_KEYWORD);
172 		for (int i = 0; i < fgKeywords.length; i++)
173 			wordRule.addWord(fgKeywords[i], token);
174 		list.add(wordRule);
175 
176 		setDefaultReturnToken(getToken(IPreferenceConstants.PHPDOC_DEFAULT));
177 		return list;
178 	}
179 }
180