diff options
Diffstat (limited to 'tools/droiddoc/src/Comment.java')
-rw-r--r-- | tools/droiddoc/src/Comment.java | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/tools/droiddoc/src/Comment.java b/tools/droiddoc/src/Comment.java new file mode 100644 index 0000000..3a24357 --- /dev/null +++ b/tools/droiddoc/src/Comment.java @@ -0,0 +1,394 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.regex.Pattern; +import java.util.regex.Matcher; +import java.util.ArrayList; + +public class Comment +{ + static final Pattern LEADING_WHITESPACE = Pattern.compile( + "^[ \t\n\r]*(.*)$", + Pattern.DOTALL); + + static final Pattern TAG_BEGIN = Pattern.compile( + "[\r\n][\r\n \t]*@", + Pattern.DOTALL); + + static final Pattern TAG = Pattern.compile( + "(@[^ \t\r\n]+)[ \t\r\n]+(.*)", + Pattern.DOTALL); + + static final Pattern INLINE_TAG = Pattern.compile( + "(.*?)\\{(@[^ \t\r\n\\}]+)[ \t\r\n]*(.*?)\\}", + Pattern.DOTALL); + + static final Pattern FIRST_SENTENCE = Pattern.compile( + "((.*?)\\.)[ \t\r\n\\<](.*)", + Pattern.DOTALL); + + private static final String[] KNOWN_TAGS = new String[] { + "@author", + "@since", + "@version", + "@deprecated", + "@undeprecate", + "@docRoot", + "@inheritDoc", + "@more", + "@code", + "@samplecode", + "@sample", + "@include", + "@serial", + "@com.intel.drl.spec_ref", + "@ar.org.fitc.spec_ref", + }; + + public Comment(String text, ContainerInfo base, SourcePositionInfo sp) + { + mText = text; + mBase = base; + // sp now points to the end of the text, not the beginning! + mPosition = SourcePositionInfo.findBeginning(sp, text); + } + + private void parseRegex(String text) + { + Matcher m; + + m = LEADING_WHITESPACE.matcher(text); + m.matches(); + text = m.group(1); + + m = TAG_BEGIN.matcher(text); + + int start = 0; + int end = 0; + while (m.find()) { + end = m.start(); + + tag(text, start, end); + + start = m.end()-1; // -1 is the @ + } + end = text.length(); + tag(text, start, end); + } + + private void tag(String text, int start, int end) + { + SourcePositionInfo pos = SourcePositionInfo.add(mPosition, mText, start); + + if (start >= 0 && end > 0 && (end-start) > 0) { + text = text.substring(start, end); + + Matcher m = TAG.matcher(text); + if (m.matches()) { + // out of line tag + tag(m.group(1), m.group(2), false, pos); + } else { + // look for inline tags + m = INLINE_TAG.matcher(text); + start = 0; + while (m.find()) { + String str = m.group(1); + String tagname = m.group(2); + String tagvalue = m.group(3); + tag(null, m.group(1), true, pos); + tag(tagname, tagvalue, true, pos); + start = m.end(); + } + int len = text.length(); + if (start != len) { + tag(null, text.substring(start), true, pos); + } + } + } + } + + private void tag(String name, String text, boolean isInline, SourcePositionInfo pos) + { + /* + String s = isInline ? "inline" : "outofline"; + System.out.println("---> " + s + + " name=[" + name + "] text=[" + text + "]"); + */ + if (name == null) { + mInlineTagsList.add(new TextTagInfo("Text", "Text", text, pos)); + } + else if (name.equals("@param")) { + mParamTagsList.add(new ParamTagInfo("@param", "@param", text, mBase, pos)); + } + else if (name.equals("@see")) { + mSeeTagsList.add(new SeeTagInfo("@see", "@see", text, mBase, pos)); + } + else if (name.equals("@link") || name.equals("@linkplain")) { + mInlineTagsList.add(new SeeTagInfo(name, "@see", text, mBase, pos)); + } + else if (name.equals("@throws") || name.equals("@exception")) { + mThrowsTagsList.add(new ThrowsTagInfo("@throws", "@throws", text, mBase, pos)); + } + else if (name.equals("@return")) { + mReturnTagsList.add(new ParsedTagInfo("@return", "@return", text, mBase, pos)); + } + else if (name.equals("@deprecated")) { + if (text.length() == 0) { + Errors.error(Errors.MISSING_COMMENT, pos, + "@deprecated tag with no explanatory comment"); + text = "No replacement."; + } + mDeprecatedTagsList.add(new ParsedTagInfo("@deprecated", "@deprecated", text, mBase, pos)); + } + else if (name.equals("@literal")) { + mInlineTagsList.add(new LiteralTagInfo(name, name, text, pos)); + } + else if (name.equals("@hide") || name.equals("@doconly")) { + // nothing + } + else if (name.equals("@attr")) { + AttrTagInfo tag = new AttrTagInfo("@attr", "@attr", text, mBase, pos); + mAttrTagsList.add(tag); + Comment c = tag.description(); + if (c != null) { + for (TagInfo t: c.tags()) { + mInlineTagsList.add(t); + } + } + } + else if (name.equals("@undeprecate")) { + mUndeprecateTagsList.add(new TextTagInfo("@undeprecate", "@undeprecate", text, pos)); + } + else if (name.equals("@include") || name.equals("@sample")) { + mInlineTagsList.add(new SampleTagInfo(name, "@include", text, mBase, pos)); + } + else { + boolean known = false; + for (String s: KNOWN_TAGS) { + if (s.equals(name)) { + known = true; + break; + } + } + if (!known) { + Errors.error(Errors.UNKNOWN_TAG, pos == null ? null : new SourcePositionInfo(pos), + "Unknown tag: " + name); + } + TagInfo t = new TextTagInfo(name, name, text, pos); + if (isInline) { + mInlineTagsList.add(t); + } else { + mTagsList.add(t); + } + } + } + + private void parseBriefTags() + { + int N = mInlineTagsList.size(); + + // look for "@more" tag, which means that we might go past the first sentence. + int more = -1; + for (int i=0; i<N; i++) { + if (mInlineTagsList.get(i).name().equals("@more")) { + more = i; + } + } + if (more >= 0) { + for (int i=0; i<more; i++) { + mBriefTagsList.add(mInlineTagsList.get(i)); + } + } else { + for (int i=0; i<N; i++) { + TagInfo t = mInlineTagsList.get(i); + if (t.name().equals("Text")) { + Matcher m = FIRST_SENTENCE.matcher(t.text()); + if (m.matches()) { + String text = m.group(1); + TagInfo firstSentenceTag = new TagInfo(t.name(), t.kind(), text, t.position()); + mBriefTagsList.add(firstSentenceTag); + break; + } + } + mBriefTagsList.add(t); + + } + } + } + + public TagInfo[] tags() + { + init(); + return mInlineTags; + } + + public TagInfo[] tags(String name) + { + init(); + ArrayList<TagInfo> results = new ArrayList<TagInfo>(); + int N = mInlineTagsList.size(); + for (int i=0; i<N; i++) { + TagInfo t = mInlineTagsList.get(i); + if (t.name().equals(name)) { + results.add(t); + } + } + return results.toArray(new TagInfo[results.size()]); + } + + public ParamTagInfo[] paramTags() + { + init(); + return mParamTags; + } + + public SeeTagInfo[] seeTags() + { + init(); + return mSeeTags; + } + + public ThrowsTagInfo[] throwsTags() + { + init(); + return mThrowsTags; + } + + public TagInfo[] returnTags() + { + init(); + return mReturnTags; + } + + public TagInfo[] deprecatedTags() + { + init(); + return mDeprecatedTags; + } + + public TagInfo[] undeprecateTags() + { + init(); + return mUndeprecateTags; + } + + public AttrTagInfo[] attrTags() + { + init(); + return mAttrTags; + } + + public TagInfo[] briefTags() + { + init(); + return mBriefTags; + } + + public boolean isHidden() + { + if (mHidden >= 0) { + return mHidden != 0; + } else { + if (DroidDoc.checkLevel(DroidDoc.SHOW_HIDDEN)) { + mHidden = 0; + return false; + } + boolean b = mText.indexOf("@hide") >= 0; + mHidden = b ? 1 : 0; + return b; + } + } + + public boolean isDocOnly() { + if (mDocOnly >= 0) { + return mDocOnly != 0; + } else { + boolean b = (mText != null) && (mText.indexOf("@doconly") >= 0); + mDocOnly = b ? 1 : 0; + return b; + } + } + + private void init() + { + if (!mInitialized) { + initImpl(); + } + } + + private void initImpl() + { + isHidden(); + isDocOnly(); + parseRegex(mText); + parseBriefTags(); + mText = null; + mInitialized = true; + + mInlineTags = mInlineTagsList.toArray(new TagInfo[mInlineTagsList.size()]); + mParamTags = mParamTagsList.toArray(new ParamTagInfo[mParamTagsList.size()]); + mSeeTags = mSeeTagsList.toArray(new SeeTagInfo[mSeeTagsList.size()]); + mThrowsTags = mThrowsTagsList.toArray(new ThrowsTagInfo[mThrowsTagsList.size()]); + mReturnTags = ParsedTagInfo.joinTags(mReturnTagsList.toArray( + new ParsedTagInfo[mReturnTagsList.size()])); + mDeprecatedTags = ParsedTagInfo.joinTags(mDeprecatedTagsList.toArray( + new ParsedTagInfo[mDeprecatedTagsList.size()])); + mUndeprecateTags = mUndeprecateTagsList.toArray(new TagInfo[mUndeprecateTagsList.size()]); + mAttrTags = mAttrTagsList.toArray(new AttrTagInfo[mAttrTagsList.size()]); + mBriefTags = mBriefTagsList.toArray(new TagInfo[mBriefTagsList.size()]); + + mParamTagsList = null; + mSeeTagsList = null; + mThrowsTagsList = null; + mReturnTagsList = null; + mDeprecatedTagsList = null; + mUndeprecateTagsList = null; + mAttrTagsList = null; + mBriefTagsList = null; + } + + boolean mInitialized; + int mHidden = -1; + int mDocOnly = -1; + String mText; + ContainerInfo mBase; + SourcePositionInfo mPosition; + int mLine = 1; + + TagInfo[] mInlineTags; + TagInfo[] mTags; + ParamTagInfo[] mParamTags; + SeeTagInfo[] mSeeTags; + ThrowsTagInfo[] mThrowsTags; + TagInfo[] mBriefTags; + TagInfo[] mReturnTags; + TagInfo[] mDeprecatedTags; + TagInfo[] mUndeprecateTags; + AttrTagInfo[] mAttrTags; + + ArrayList<TagInfo> mInlineTagsList = new ArrayList<TagInfo>(); + ArrayList<TagInfo> mTagsList = new ArrayList<TagInfo>(); + ArrayList<ParamTagInfo> mParamTagsList = new ArrayList<ParamTagInfo>(); + ArrayList<SeeTagInfo> mSeeTagsList = new ArrayList<SeeTagInfo>(); + ArrayList<ThrowsTagInfo> mThrowsTagsList = new ArrayList<ThrowsTagInfo>(); + ArrayList<TagInfo> mBriefTagsList = new ArrayList<TagInfo>(); + ArrayList<ParsedTagInfo> mReturnTagsList = new ArrayList<ParsedTagInfo>(); + ArrayList<ParsedTagInfo> mDeprecatedTagsList = new ArrayList<ParsedTagInfo>(); + ArrayList<TagInfo> mUndeprecateTagsList = new ArrayList<TagInfo>(); + ArrayList<AttrTagInfo> mAttrTagsList = new ArrayList<AttrTagInfo>(); + + +} |