summaryrefslogtreecommitdiffstats
path: root/tools/droiddoc/src/LinkReference.java
diff options
context:
space:
mode:
Diffstat (limited to 'tools/droiddoc/src/LinkReference.java')
-rw-r--r--tools/droiddoc/src/LinkReference.java440
1 files changed, 0 insertions, 440 deletions
diff --git a/tools/droiddoc/src/LinkReference.java b/tools/droiddoc/src/LinkReference.java
deleted file mode 100644
index bbcd4db..0000000
--- a/tools/droiddoc/src/LinkReference.java
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * 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;
-
-/**
- * Class that represents what you see in an link or see tag. This is
- * factored out of SeeTagInfo so it can be used elsewhere (like AttrTagInfo).
- */
-public class LinkReference {
-
- /** The original text. */
- public String text;
-
- /** The kind of this tag, if we have a new suggestion after parsing. */
- public String kind;
-
- /** The user visible text. */
- public String label;
-
- /** The link. */
- public String href;
-
- /** The {@link PackageInfo} if any. */
- public PackageInfo packageInfo;
-
- /** The {@link ClassInfo} if any. */
- public ClassInfo classInfo;
-
- /** The {@link MemberInfo} if any. */
- public MemberInfo memberInfo;
-
- /** The name of the referenced member PackageInfo} if any. */
- public String referencedMemberName;
-
- /** Set to true if everything is a-ok */
- public boolean good;
-
- /**
- * regex pattern to use when matching explicit "<a href" reference text
- */
- private static final Pattern HREF_PATTERN
- = Pattern.compile("^<a href=\"([^\"]*)\">([^<]*)</a>[ \n\r\t]*$",
- Pattern.CASE_INSENSITIVE);
-
- /**
- * Parse and resolve a link string.
- *
- * @param text the original text
- * @param base the class or whatever that this link is on
- * @param pos the original position in the source document
- * @return a new link reference. It always returns something. If there was an
- * error, it logs it and fills in href and label with error text.
- */
- public static LinkReference parse(String text, ContainerInfo base, SourcePositionInfo pos,
- boolean printOnErrors) {
- LinkReference result = new LinkReference();
- result.text = text;
-
- int index;
- int len = text.length();
- int pairs = 0;
- int pound = -1;
- // split the string
- done: {
- for (index=0; index<len; index++) {
- char c = text.charAt(index);
- switch (c)
- {
- case '(':
- pairs++;
- break;
- case '[':
- pairs++;
- break;
- case ')':
- pairs--;
- break;
- case ']':
- pairs--;
- break;
- case ' ':
- case '\t':
- case '\r':
- case '\n':
- if (pairs == 0) {
- break done;
- }
- break;
- case '#':
- if (pound < 0) {
- pound = index;
- }
- break;
- }
- }
- }
- if (index == len && pairs != 0) {
- Errors.error(Errors.UNRESOLVED_LINK, pos,
- "unable to parse link/see tag: " + text.trim());
- return result;
- }
-
- int linkend = index;
-
- for (; index<len; index++) {
- char c = text.charAt(index);
- if (!(c == ' ' || c == '\t' || c == '\r' || c == '\n')) {
- break;
- }
- }
-
- result.label = text.substring(index);
-
- String ref;
- String mem;
- if (pound == 0) {
- ref = null;
- mem = text.substring(1, linkend);
- }
- else if (pound > 0) {
- ref = text.substring(0, pound);
- mem = text.substring(pound+1, linkend);
- }
- else {
- ref = text.substring(0, linkend);
- mem = null;
- }
-
- // parse parameters, if any
- String[] params = null;
- String[] paramDimensions = null;
- if (mem != null) {
- index = mem.indexOf('(');
- if (index > 0) {
- ArrayList<String> paramList = new ArrayList<String>();
- ArrayList<String> paramDimensionList = new ArrayList<String>();
- len = mem.length();
- int start = index+1;
- final int START = 0;
- final int TYPE = 1;
- final int NAME = 2;
- int dimension = 0;
- int arraypair = 0;
- int state = START;
- int typestart = 0;
- int typeend = -1;
- for (int i=start; i<len; i++) {
- char c = mem.charAt(i);
- switch (state)
- {
- case START:
- if (c!=' ' && c!='\t' && c!='\r' && c!='\n') {
- state = TYPE;
- typestart = i;
- }
- break;
- case TYPE:
- if (c == '[') {
- if (typeend < 0) {
- typeend = i;
- }
- dimension++;
- arraypair++;
- }
- else if (c == ']') {
- arraypair--;
- }
- else if (c==' ' || c=='\t' || c=='\r' || c=='\n') {
- if (typeend < 0) {
- typeend = i;
- }
- }
- else {
- if (typeend >= 0 || c == ')' || c == ',') {
- if (typeend < 0) {
- typeend = i;
- }
- String s = mem.substring(typestart, typeend);
- paramList.add(s);
- s = "";
- for (int j=0; j<dimension; j++) {
- s += "[]";
- }
- paramDimensionList.add(s);
- state = START;
- typeend = -1;
- dimension = 0;
- if (c == ',' || c == ')') {
- state = START;
- } else {
- state = NAME;
- }
- }
- }
- break;
- case NAME:
- if (c == ',' || c == ')') {
- state = START;
- }
- break;
- }
-
- }
- params = paramList.toArray(new String[paramList.size()]);
- paramDimensions = paramDimensionList.toArray(new String[paramList.size()]);
- mem = mem.substring(0, index);
- }
- }
-
- ClassInfo cl = null;
- if (base instanceof ClassInfo) {
- cl = (ClassInfo)base;
- }
-
- if (ref == null) {
- // no class or package was provided, assume it's this class
- if (cl != null) {
- result.classInfo = cl;
- }
- } else {
- // they provided something, maybe it's a class or a package
- if (cl != null) {
- result.classInfo = cl.extendedFindClass(ref);
- if (result.classInfo == null) {
- result.classInfo = cl.findClass(ref);
- }
- if (result.classInfo == null) {
- result.classInfo = cl.findInnerClass(ref);
- }
- }
- if (result.classInfo == null) {
- result.classInfo = Converter.obtainClass(ref);
- }
- if (result.classInfo == null) {
- result.packageInfo = Converter.obtainPackage(ref);
- }
- }
-
- if (result.classInfo != null && mem != null) {
- // it's either a field or a method, prefer a field
- if (params == null) {
- FieldInfo field = result.classInfo.findField(mem);
- // findField looks in containing classes, so it might actually
- // be somewhere else; link to where it really is, not what they
- // typed.
- if (field != null) {
- result.classInfo = field.containingClass();
- result.memberInfo = field;
- }
- }
- if (result.memberInfo == null) {
- MethodInfo method = result.classInfo.findMethod(mem, params, paramDimensions);
- if (method != null) {
- result.classInfo = method.containingClass();
- result.memberInfo = method;
- }
- }
- }
-
- result.referencedMemberName = mem;
- if (params != null) {
- result.referencedMemberName = result.referencedMemberName + '(';
- len = params.length;
- if (len > 0) {
- len--;
- for (int i=0; i<len; i++) {
- result.referencedMemberName = result.referencedMemberName + params[i]
- + paramDimensions[i] + ", ";
- }
- result.referencedMemberName = result.referencedMemberName + params[len]
- + paramDimensions[len];
- }
- result.referencedMemberName = result.referencedMemberName + ")";
- }
-
- // debugging spew
- if (false) {
- result.label = result.label + "/" + ref + "/" + mem + '/';
- if (params != null) {
- for (int i=0; i<params.length; i++) {
- result.label += params[i] + "|";
- }
- }
-
- FieldInfo f = (result.memberInfo instanceof FieldInfo)
- ? (FieldInfo)result.memberInfo
- : null;
- MethodInfo m = (result.memberInfo instanceof MethodInfo)
- ? (MethodInfo)result.memberInfo
- : null;
- result.label = result.label
- + "/package=" + (result.packageInfo!=null?result.packageInfo.name():"")
- + "/class=" + (result.classInfo!=null?result.classInfo.qualifiedName():"")
- + "/field=" + (f!=null?f.name():"")
- + "/method=" + (m!=null?m.name():"");
-
- }
-
- MethodInfo method = null;
- boolean skipHref = false;
-
- if (result.memberInfo != null && result.memberInfo.isExecutable()) {
- method = (MethodInfo)result.memberInfo;
- }
-
- if (text.startsWith("\"")) {
- // literal quoted reference (e.g., a book title)
- result.label = text.substring(1);
- skipHref = true;
- if (!result.label.endsWith("\"")) {
- Errors.error(Errors.UNRESOLVED_LINK, pos,
- "unbalanced quoted link/see tag: " + text.trim());
- result.makeError();
- return result;
- }
- result.label = result.label.substring(0, result.label.length() - 1);
- result.kind = "@seeJustLabel";
- }
- else if (text.startsWith("<")) {
- // explicit "<a href" form
- Matcher matcher = HREF_PATTERN.matcher(text);
- if (! matcher.matches()) {
- Errors.error(Errors.UNRESOLVED_LINK, pos,
- "invalid <a> link/see tag: " + text.trim());
- result.makeError();
- return result;
- }
- result.href = matcher.group(1);
- result.label = matcher.group(2);
- result.kind = "@seeHref";
- }
- else if (result.packageInfo != null) {
- result.href = result.packageInfo.htmlPage();
- if (result.label.length() == 0) {
- result.href = result.packageInfo.htmlPage();
- result.label = result.packageInfo.name();
- }
- }
- else if (result.classInfo != null && result.referencedMemberName == null) {
- // class reference
- if (result.label.length() == 0) {
- result.label = result.classInfo.name();
- }
- result.href = result.classInfo.htmlPage();
- }
- else if (result.memberInfo != null) {
- // member reference
- ClassInfo containing = result.memberInfo.containingClass();
- if (result.memberInfo.isExecutable()) {
- if (result.referencedMemberName.indexOf('(') < 0) {
- result.referencedMemberName += method.flatSignature();
- }
- }
- if (result.label.length() == 0) {
- result.label = result.referencedMemberName;
- }
- result.href = containing.htmlPage() + '#' + result.memberInfo.anchor();
- }
-
- if (result.href == null && !skipHref) {
- if (printOnErrors && (base == null || base.checkLevel())) {
- Errors.error(Errors.UNRESOLVED_LINK, pos,
- "Unresolved link/see tag \"" + text.trim()
- + "\" in " + ((base != null) ? base.qualifiedName() : "[null]"));
- }
- result.makeError();
- }
- else if (result.memberInfo != null && !result.memberInfo.checkLevel()) {
- if (printOnErrors && (base == null || base.checkLevel())) {
- Errors.error(Errors.HIDDEN_LINK, pos,
- "Link to hidden member: " + text.trim());
- result.href = null;
- }
- result.kind = "@seeJustLabel";
- }
- else if (result.classInfo != null && !result.classInfo.checkLevel()) {
- if (printOnErrors && (base == null || base.checkLevel())) {
- Errors.error(Errors.HIDDEN_LINK, pos,
- "Link to hidden class: " + text.trim() + " label=" + result.label);
- result.href = null;
- }
- result.kind = "@seeJustLabel";
- }
- else if (result.packageInfo != null && !result.packageInfo.checkLevel()) {
- if (printOnErrors && (base == null || base.checkLevel())) {
- Errors.error(Errors.HIDDEN_LINK, pos,
- "Link to hidden package: " + text.trim());
- result.href = null;
- }
- result.kind = "@seeJustLabel";
- }
-
- result.good = true;
-
- return result;
- }
-
- public boolean checkLevel() {
- if (memberInfo != null) {
- return memberInfo.checkLevel();
- }
- if (classInfo != null) {
- return classInfo.checkLevel();
- }
- if (packageInfo != null) {
- return packageInfo.checkLevel();
- }
- return false;
- }
-
- /** turn this LinkReference into one with an error message */
- private void makeError() {
- //this.href = "ERROR(" + this.text.trim() + ")";
- this.href = null;
- if (this.label == null) {
- this.label = "";
- }
- this.label = "ERROR(" + this.label + "/" + text.trim() + ")";
- }
-
- /** private. **/
- private LinkReference() {
- }
-}