diff options
-rw-r--r-- | res/assets/templates-sdk/macros_override.cs | 59 | ||||
-rw-r--r-- | res/assets/templates/macros.cs | 33 | ||||
-rw-r--r-- | src/com/google/doclava/AuxTagInfo.java (renamed from src/com/google/doclava/IntDefTagInfo.java) | 23 | ||||
-rw-r--r-- | src/com/google/doclava/AuxUtils.java | 72 | ||||
-rw-r--r-- | src/com/google/doclava/ContainerInfo.java | 5 | ||||
-rw-r--r-- | src/com/google/doclava/RangeTagInfo.java | 47 |
6 files changed, 139 insertions, 100 deletions
diff --git a/res/assets/templates-sdk/macros_override.cs b/res/assets/templates-sdk/macros_override.cs index 5b92fe3..10fb9c1 100644 --- a/res/assets/templates-sdk/macros_override.cs +++ b/res/assets/templates-sdk/macros_override.cs @@ -48,4 +48,61 @@ def:parameter_list(params, linebreaks) ?><?cs <?cs /if ?><?cs /if ?><?cs /each ?><?cs -/def ?>
\ No newline at end of file +/def ?><?cs + +# Print output for aux tags that are not "standard" javadoc tags ?><?cs +def:aux_tag_list(tags) ?><?cs + each:tag = tags ?><p><?cs + if:tag.kind == "@memberDoc" ?><?cs call:tag_list(tag.commentTags) ?><?cs + elif:tag.kind == "@paramDoc" ?><?cs call:tag_list(tag.commentTags) ?><?cs + elif:tag.kind == "@returnDoc" ?><?cs call:tag_list(tag.commentTags) ?><?cs + elif:tag.kind == "@range" ?><?cs call:dump_range(tag) ?><?cs + elif:tag.kind == "@intDef" ?><?cs call:dump_int_def(tag) ?><?cs + elif:tag.kind == "@permission" ?><?cs call:dump_permission(tag) ?><?cs + /if ?><?cs + /each ?></p><?cs +/def ?><?cs + +# Print output for @range tags ?><?cs +def:dump_range(tag) ?><?cs + if:tag.from && tag.to ?>Value is between <?cs var:tag.from ?> and <?cs var:tag.to ?> inclusive.<?cs + elif:tag.from ?>Value is <?cs var:tag.from ?> or greater.<?cs + elif:tag.to ?>Value is <?cs var:tag.to ?> or less.<?cs + /if ?><?cs +/def ?><?cs + +# Print output for @intDef tags ?><?cs +def:dump_int_def(tag) ?><?cs + if:tag.flag ?><?cs + if:subcount(tag.values) > 1 ?>Value is either <code>0</code> or combination of <?cs + else ?>Value is either <code>0</code> or <?cs + /if ?><?cs + else ?>Value is <?cs + /if ?><?cs + loop:i = #0, subcount(tag.values), #1 ?><?cs + with:val = tag.values[i] ?><?cs + call:tag_list(val.commentTags) ?><?cs + if i == subcount(tag.values) - 2 ?> or <?cs + elif:i < subcount(tag.values) - 2 ?>, <?cs + /if ?><?cs + /with ?><?cs + /loop ?>.<?cs +/def ?><?cs + +# Print output for @permission tags ?><?cs +def:dump_permission(tag) ?>Requires the <?cs + loop:i = #0, subcount(tag.values), #1 ?><?cs + with:val = tag.values[i] ?><?cs + call:tag_list(val.commentTags) ?><?cs + if i == subcount(tag.values) - 2 ?><?cs + if tag.any ?> or <?cs + else ?> and <?cs + /if ?><?cs + elif:i < subcount(tag.values) - 2 ?>, <?cs + /if ?><?cs + /with ?><?cs + /loop ?><?cs + if subcount(tag.values) > 1 ?> permissions.<?cs + else ?> permission.<?cs + /if ?><?cs +/def ?> diff --git a/res/assets/templates/macros.cs b/res/assets/templates/macros.cs index ade9d2e..3bf36e2 100644 --- a/res/assets/templates/macros.cs +++ b/res/assets/templates/macros.cs @@ -170,37 +170,6 @@ def:block_tag_list(tags) ?><?cs # Print output for aux tags that are not "standard" javadoc tags ?><?cs def:aux_tag_list(tags) ?><?cs - each:tag = tags ?><p><?cs - if:tag.kind == "@memberDoc" ?><?cs call:tag_list(tag.commentTags) ?><?cs - elif:tag.kind == "@paramDoc" ?><?cs call:tag_list(tag.commentTags) ?><?cs - elif:tag.kind == "@returnDoc" ?><?cs call:tag_list(tag.commentTags) ?><?cs - elif:tag.kind == "@range" ?><?cs call:dump_range(tag) ?><?cs - elif:tag.kind == "@intDef" ?><?cs call:dump_int_def(tag) ?><?cs - /if ?><?cs - /each ?></p><?cs -/def ?><?cs - -# Print output for @range tags ?><?cs -def:dump_range(tag) ?><?cs - if:tag.from && tag.to ?>Value is between <?cs var:tag.from ?> and <?cs var:tag.to ?> inclusive.<?cs - elif:tag.from ?>Value is <?cs var:tag.from ?> or greater.<?cs - elif:tag.to ?>Value is <?cs var:tag.to ?> or less.<?cs - /if ?><?cs -/def ?><?cs - -# Print output for @intDef tags ?><?cs -def:dump_int_def(tag) ?><?cs - if:tag.flag ?>Value is either <code>0</code> or combination of <?cs - else ?>Value is <?cs - /if ?><?cs - loop:i = #0, subcount(tag.values), #1 ?><?cs - with:val = tag.values[i] ?><?cs - call:tag_list(val.commentTags) ?><?cs - if i == subcount(tag.values) - 2 ?>, or <?cs - elif:i < subcount(tag.values) - 2 ?>, <?cs - /if ?><?cs - /with ?><?cs - /loop ?>.<?cs /def ?><?cs # Show the short-form description of something. These come from shortDescr and deprecated ?><?cs @@ -359,7 +328,7 @@ def:description(obj) ?><?cs <code><?cs var:param.kind ?></code><?cs if:string.find(param.comment.0.text, "<!--") != 0 ?>:<?cs # Do not print if param comment is an HTML comment ?><?cs - /if ?><?cs + /if ?> <?cs call:tag_list(param.comment) ?><?cs call:aux_tag_list(param.commentAux) ?></td> </tr><?cs diff --git a/src/com/google/doclava/IntDefTagInfo.java b/src/com/google/doclava/AuxTagInfo.java index 3044557..d2555d7 100644 --- a/src/com/google/doclava/IntDefTagInfo.java +++ b/src/com/google/doclava/AuxTagInfo.java @@ -18,19 +18,22 @@ package com.google.doclava; import com.google.clearsilver.jsilver.data.Data; -public class IntDefTagInfo extends TagInfo { - public static final IntDefTagInfo[] EMPTY_ARRAY = new IntDefTagInfo[0]; +import java.util.Map; - public static IntDefTagInfo[] getArray(int size) { - return size == 0 ? EMPTY_ARRAY : new IntDefTagInfo[size]; +public class AuxTagInfo extends TagInfo { + public static final AuxTagInfo[] EMPTY_ARRAY = new AuxTagInfo[0]; + + public static AuxTagInfo[] getArray(int size) { + return size == 0 ? EMPTY_ARRAY : new AuxTagInfo[size]; } - private boolean mFlag; + private Map<String, String> mArgs; private TagInfo[] mValues; - IntDefTagInfo(SourcePositionInfo position, boolean flag, TagInfo[] values) { - super("@intDef", "@intDef", "", position); - mFlag = flag; + AuxTagInfo(String name, String kind, SourcePositionInfo position, Map<String, String> args, + TagInfo[] values) { + super(name, kind, "", position); + mArgs = args; mValues = values; } @@ -41,8 +44,8 @@ public class IntDefTagInfo extends TagInfo { @Override public void makeHDF(Data data, String base) { super.makeHDF(data, base); - if (mFlag) { - data.setValue(base + ".flag", "true"); + for (Map.Entry<String, String> entry : mArgs.entrySet()) { + data.setValue(base + "." + entry.getKey(), entry.getValue()); } TagInfo.makeHDF(data, base + ".values", valuesTags()); } diff --git a/src/com/google/doclava/AuxUtils.java b/src/com/google/doclava/AuxUtils.java index cfa668c..262ae4d 100644 --- a/src/com/google/doclava/AuxUtils.java +++ b/src/com/google/doclava/AuxUtils.java @@ -19,6 +19,7 @@ package com.google.doclava; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Map; public class AuxUtils { private static final int TYPE_METHOD = 0; @@ -50,6 +51,7 @@ public class AuxUtils { private static TagInfo[] auxTags(int type, List<AnnotationInstanceInfo> annotations) { ArrayList<TagInfo> tags = new ArrayList<>(); for (AnnotationInstanceInfo annotation : annotations) { + // Blindly include docs requested by annotations ParsedTagInfo[] docTags = ParsedTagInfo.EMPTY_ARRAY; switch (type) { case TYPE_METHOD: @@ -67,11 +69,55 @@ public class AuxUtils { tags.add(docTag); } - // IntDef below belongs in return docs, not in method body + // Document required permissions + if ((type == TYPE_METHOD || type == TYPE_FIELD) + && annotation.type().qualifiedNameMatches("android", "annotation.RequiresPermission")) { + ArrayList<AnnotationValueInfo> values = null; + boolean any = false; + for (AnnotationValueInfo val : annotation.elementValues()) { + switch (val.element().name()) { + case "value": + values = new ArrayList<AnnotationValueInfo>(); + values.add(val); + break; + case "allOf": + values = (ArrayList<AnnotationValueInfo>) val.value(); + break; + case "anyOf": + any = true; + values = (ArrayList<AnnotationValueInfo>) val.value(); + break; + } + } + if (values == null || values.isEmpty()) continue; + + ClassInfo permClass = annotation.type().findClass("android.Manifest.permission"); + ArrayList<TagInfo> valueTags = new ArrayList<>(); + for (AnnotationValueInfo value : values) { + final String expected = String.valueOf(value.value()); + for (FieldInfo field : permClass.fields()) { + if (field.isHiddenOrRemoved()) continue; + if (String.valueOf(field.constantValue()).equals(expected)) { + valueTags.add(new ParsedTagInfo("", "", + "{@link " + permClass.qualifiedName() + "#" + field.name() + "}", null, + SourcePositionInfo.UNKNOWN)); + } + } + } + + Map<String, String> args = new HashMap<>(); + if (any) args.put("any", "true"); + tags.add(new AuxTagInfo("@permission", "@permission", SourcePositionInfo.UNKNOWN, args, + valueTags.toArray(TagInfo.getArray(valueTags.size())))); + } + + // The remaining annotations below always appear on return docs, and + // should not be included in the method body if (type == TYPE_METHOD) continue; - if (annotation.type().qualifiedName().equals("android.annotation.IntRange") - || annotation.type().qualifiedName().equals("android.annotation.FloatRange")) { + // Document value ranges + if (annotation.type().qualifiedNameMatches("android", "annotation.IntRange") + || annotation.type().qualifiedNameMatches("android", "annotation.FloatRange")) { String from = null; String to = null; for (AnnotationValueInfo val : annotation.elementValues()) { @@ -81,12 +127,17 @@ public class AuxUtils { } } if (from != null || to != null) { - tags.add(new RangeTagInfo(SourcePositionInfo.UNKNOWN, from, to)); + Map<String, String> args = new HashMap<>(); + if (from != null) args.put("from", from); + if (to != null) args.put("to", to); + tags.add(new AuxTagInfo("@range", "@range", SourcePositionInfo.UNKNOWN, args, + TagInfo.EMPTY_ARRAY)); } } + // Document integer values for (AnnotationInstanceInfo inner : annotation.type().annotations()) { - if (inner.type().qualifiedName().equals("android.annotation.IntDef")) { + if (inner.type().qualifiedNameMatches("android", "annotation.IntDef")) { ArrayList<AnnotationValueInfo> prefixes = null; ArrayList<AnnotationValueInfo> values = null; boolean flag = false; @@ -105,8 +156,7 @@ public class AuxUtils { final ClassInfo clazz = annotation.type().containingClass(); final HashMap<String, FieldInfo> candidates = new HashMap<>(); for (FieldInfo field : clazz.fields()) { - if (field.isHiddenOrRemoved()) - continue; + if (field.isHiddenOrRemoved()) continue; for (AnnotationValueInfo prefix : prefixes) { if (field.name().startsWith(String.valueOf(prefix.value()))) { candidates.put(String.valueOf(field.constantValue()), field); @@ -117,7 +167,7 @@ public class AuxUtils { ArrayList<TagInfo> valueTags = new ArrayList<>(); for (AnnotationValueInfo value : values) { final String expected = String.valueOf(value.value()); - final FieldInfo field = candidates.get(expected); + final FieldInfo field = candidates.remove(expected); if (field != null) { valueTags.add(new ParsedTagInfo("", "", "{@link " + clazz.qualifiedName() + "#" + field.name() + "}", null, @@ -126,7 +176,9 @@ public class AuxUtils { } if (!valueTags.isEmpty()) { - tags.add(new IntDefTagInfo(SourcePositionInfo.UNKNOWN, flag, + Map<String, String> args = new HashMap<>(); + if (flag) args.put("flag", "true"); + tags.add(new AuxTagInfo("@intDef", "@intDef", SourcePositionInfo.UNKNOWN, args, valueTags.toArray(TagInfo.getArray(valueTags.size())))); } } @@ -142,7 +194,7 @@ public class AuxUtils { private static boolean hasSuppress(List<AnnotationInstanceInfo> annotations) { for (AnnotationInstanceInfo annotation : annotations) { - if (annotation.type().qualifiedName().equals("android.annotation.SuppressAutoDoc")) { + if (annotation.type().qualifiedNameMatches("android", "annotation.SuppressAutoDoc")) { return true; } } diff --git a/src/com/google/doclava/ContainerInfo.java b/src/com/google/doclava/ContainerInfo.java index bde9506..0e7b000 100644 --- a/src/com/google/doclava/ContainerInfo.java +++ b/src/com/google/doclava/ContainerInfo.java @@ -19,5 +19,10 @@ package com.google.doclava; public interface ContainerInfo { public String qualifiedName(); + public default boolean qualifiedNameMatches(String prefix, String suffix) { + final String qualifiedName = qualifiedName(); + return (qualifiedName.startsWith(prefix) && qualifiedName.endsWith(suffix)); + } + public boolean checkLevel(); } diff --git a/src/com/google/doclava/RangeTagInfo.java b/src/com/google/doclava/RangeTagInfo.java deleted file mode 100644 index 8f3be30..0000000 --- a/src/com/google/doclava/RangeTagInfo.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2017 Google Inc. - * - * 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. - */ - -package com.google.doclava; - -import com.google.clearsilver.jsilver.data.Data; - -public class RangeTagInfo extends TagInfo { - public static final RangeTagInfo[] EMPTY_ARRAY = new RangeTagInfo[0]; - - public static RangeTagInfo[] getArray(int size) { - return size == 0 ? EMPTY_ARRAY : new RangeTagInfo[size]; - } - - private String mFrom; - private String mTo; - - RangeTagInfo(SourcePositionInfo position, String from, String to) { - super("@range", "@range", "", position); - mFrom = from; - mTo = to; - } - - @Override - public void makeHDF(Data data, String base) { - super.makeHDF(data, base); - if (mFrom != null) { - data.setValue(base + ".from", mFrom); - } - if (mTo != null) { - data.setValue(base + ".to", mTo); - } - } -} |