com.redhat.ceylon.ceylondoc.ClassDoc Maven / Gradle / Ivy
/*
* Copyright Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the authors tag. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License version 2.
*
* This particular file is subject to the "Classpath" exception as provided in the
* LICENSE file that accompanied this code.
*
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License,
* along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package com.redhat.ceylon.ceylondoc;
import static com.redhat.ceylon.ceylondoc.Util.getAncestors;
import static com.redhat.ceylon.ceylondoc.Util.getDoc;
import static com.redhat.ceylon.ceylondoc.Util.getSuperInterfaces;
import static com.redhat.ceylon.ceylondoc.Util.isAbbreviatedType;
import static com.redhat.ceylon.ceylondoc.Util.isEmpty;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import com.redhat.ceylon.ceylondoc.Util.ReferenceableComparatorByName;
import com.redhat.ceylon.model.typechecker.model.Class;
import com.redhat.ceylon.model.typechecker.model.ClassOrInterface;
import com.redhat.ceylon.model.typechecker.model.Declaration;
import com.redhat.ceylon.model.typechecker.model.Function;
import com.redhat.ceylon.model.typechecker.model.Interface;
import com.redhat.ceylon.model.typechecker.model.ModelUtil;
import com.redhat.ceylon.model.typechecker.model.Package;
import com.redhat.ceylon.model.typechecker.model.Parameter;
import com.redhat.ceylon.model.typechecker.model.ParameterList;
import com.redhat.ceylon.model.typechecker.model.Type;
import com.redhat.ceylon.model.typechecker.model.TypeAlias;
import com.redhat.ceylon.model.typechecker.model.TypeDeclaration;
import com.redhat.ceylon.model.typechecker.model.TypedDeclaration;
import com.redhat.ceylon.model.typechecker.model.Value;
public class ClassDoc extends ClassOrPackageDoc {
private TypeDeclaration klass;
private SortedMap constructors;
private SortedMap> methods;
private SortedMap attributes;
private SortedMap innerInterfaces;
private SortedMap innerClasses;
private SortedMap innerExceptions;
private SortedMap innerAliases;
private List superInterfaces;
private List superClasses;
private Map>> superclassInheritedMembers = new HashMap>>(2);
private Map>> interfaceInheritedMembers = new HashMap>>(2);
private interface MemberSpecification {
boolean isSatisfiedBy(Declaration decl);
}
private MemberSpecification attributeSpecification = new MemberSpecification() {
@Override
public boolean isSatisfiedBy(Declaration decl) {
return decl instanceof Value;
}
};
private MemberSpecification methodSpecification = new MemberSpecification() {
@Override
public boolean isSatisfiedBy(Declaration decl) {
return decl instanceof Function;
}
};
private Comparator overloadedFunctionComperator = new Comparator() {
@Override
public int compare(Function f1, Function f2) {
int result;
List parameterLists1 = f1.getParameterLists();
List parameterLists2 = f2.getParameterLists();
result = Integer.compare(parameterLists1.size(), parameterLists2.size());
if( result != 0 ) {
return result;
}
for( int i = 0; i < parameterLists1.size(); i++) {
List parameterList1 = parameterLists1.get(i).getParameters();
List parameterList2 = parameterLists2.get(i).getParameters();
result = Integer.compare(parameterList1.size(), parameterList2.size());
if( result != 0 ) {
return result;
}
}
String signature1 = f1.toString();
String signature2 = f2.toString();
result = signature1.compareTo(signature2);
return result;
}
};
public ClassDoc(CeylonDocTool tool, Writer writer, TypeDeclaration klass) throws IOException {
super(tool.getModule(klass), tool, writer);
this.klass = klass;
loadMembers();
}
private void loadMembers() {
constructors = new TreeMap();
methods = new TreeMap>();
attributes = new TreeMap();
innerInterfaces = new TreeMap();
innerClasses = new TreeMap();
innerExceptions = new TreeMap();
innerAliases = new TreeMap();
superClasses = getAncestors(klass);
superInterfaces = getSuperInterfaces(klass);
for (Declaration m : klass.getMembers()) {
if (tool.shouldInclude(m)) {
if (ModelUtil.isConstructor(m)) {
addTo(constructors, m);
} else if (m instanceof Value) {
addTo(attributes, (Value)m);
} else if (m instanceof Function) {
if( m.isAbstraction() && m.getOverloads().size() > 0 ) {
// we want document each overloads, see https://github.com/ceylon/ceylon/issues/5748
continue;
}
addTo(methods, (Function)m);
} else if (m instanceof Interface) {
addTo(innerInterfaces, (Interface)m);
} else if (m instanceof Class) {
Class c = (Class) m;
if (Util.isThrowable(c)) {
addTo(innerExceptions, c);
} else {
addTo(innerClasses, c);
}
} else if (m instanceof TypeAlias) {
addTo(innerAliases, (TypeAlias)m);
}
}
}
Collections.sort(superInterfaces, ReferenceableComparatorByName.INSTANCE);
loadInheritedMembers(attributeSpecification, superClasses, superclassInheritedMembers);
loadInheritedMembers(methodSpecification, superClasses, superclassInheritedMembers);
loadInheritedMembers(attributeSpecification, superInterfaces, interfaceInheritedMembers);
loadInheritedMembers(methodSpecification, superInterfaces, interfaceInheritedMembers);
}
private void addTo(SortedMap map, T decl) {
map.put(Util.getDeclarationName(decl), decl);
for(String alias : decl.getAliases()){
map.put(alias, decl);
}
}
private void addTo(SortedMap> map, Function decl) {
String declName = Util.getDeclarationName(decl);
SortedSet overloadedDeclSet = map.get(declName);
if( overloadedDeclSet == null ) {
overloadedDeclSet = new TreeSet(overloadedFunctionComperator);
map.put(declName, overloadedDeclSet);
}
overloadedDeclSet.add(decl);
for(String alias : decl.getAliases()){
overloadedDeclSet = map.get(alias);
if( overloadedDeclSet == null ) {
overloadedDeclSet = new TreeSet(overloadedFunctionComperator);
map.put(alias, overloadedDeclSet);
}
overloadedDeclSet.add(decl);
}
}
private void loadInheritedMembers(MemberSpecification specification,
List superClassOrInterfaceList,
Map>> superClassOrInterfaceInheritedMemebers) {
LinkedHashMap> inheritedMembersMap =
new LinkedHashMap>();
for (TypeDeclaration superClassOrInterface : superClassOrInterfaceList) {
SortedMap inheritedMembers = new TreeMap();
for (Declaration member : superClassOrInterface.getMembers()) {
if (specification.isSatisfiedBy(member) && tool.shouldInclude(member) ) {
inheritedMembers.put(Util.getDeclarationName(member), member);
for(String alias : member.getAliases()){
inheritedMembers.put(alias, member);
}
}
}
if( !inheritedMembers.isEmpty() ) {
inheritedMembersMap.put(superClassOrInterface, inheritedMembers);
}
}
superClassOrInterfaceInheritedMemebers.put(specification, inheritedMembersMap);
}
private boolean isObject() {
return klass instanceof Class && klass.isAnonymous();
}
private boolean hasInitializer() {
return klass instanceof Class && !isObject() && constructors.isEmpty();
}
/**
* Determines whether the type has any attributes (include any inherited from superclasses or superinterfaces).
* @return true if the type has any attributes.
*/
private boolean hasAnyAttributes() {
return !(attributes.isEmpty()
&& interfaceInheritedMembers.get(attributeSpecification).isEmpty()
&& superclassInheritedMembers.get(attributeSpecification).isEmpty());
}
/**
* Determines whether the type has any methods (include any inherited from superclasses or superinterfaces).
* @return true if the type has any methods.
*/
private boolean hasAnyMethods() {
return !(methods.isEmpty()
&& interfaceInheritedMembers.get(methodSpecification).isEmpty()
&& superclassInheritedMembers.get(methodSpecification).isEmpty());
}
private String getClassLabel() {
if (klass.isDynamic()) {
return "dynamic";
} else if (klass instanceof Interface) {
return "interface";
} else if (klass.isAnnotation()) {
return "annotation";
} else if (isObject()) {
return "object";
} else {
return "class";
}
}
public void generate() throws IOException {
writeHeader(Util.capitalize(getClassLabel()) + " " + klass.getName());
writeNavBar();
writeSubNavBar();
open("div class='container-fluid'");
writeDescription();
if (hasInitializer()) {
writeInitializer((Class) klass);
}
if( !constructors.isEmpty() ) {
writeConstructors();
}
if (hasAnyAttributes()) {
open("div id='section-attributes'");
writeAttributes();
writeInheritedMembers(attributeSpecification, "Inherited Attributes", "Attributes inherited from: ");
close("div");
}
if (hasAnyMethods()) {
open("div id='section-methods'");
writeMethods();
writeInheritedMembers(methodSpecification, "Inherited Methods", "Methods inherited from: ");
close("div");
}
// Nested types at the end
writeInnerTypes(innerAliases, "section-nested-aliases", "Nested Aliases");
writeInnerTypes(innerInterfaces, "section-nested-interfaces", "Nested Interfaces");
writeInnerTypes(innerClasses, "section-nested-classes", "Nested Classes");
writeInnerTypes(innerExceptions, "section-nested-exceptions", "Nested Exceptions");
close("div");
writeFooter();
}
private void writeSubNavBar() throws IOException {
Package pkg = tool.getPackage(klass);
open("div class='sub-navbar'");
writeLinkSourceCode(klass);
open("div class='sub-navbar-inner'");
open("span class='sub-navbar-package'");
writeIcon(pkg);
writePackageNavigation(pkg);
close("span");
write("
");
writeClassSignature();
close("div"); // sub-navbar-inner
open("div class='sub-navbar-menu'");
writeSubNavBarLink(linkRenderer().to(module).getUrl(), "Overview", 'O', "Jump to module documentation");
writeSubNavBarLink(linkRenderer().to(pkg).getUrl(), "Package", 'P', "Jump to package documentation");
if (hasInitializer()) {
writeSubNavBarLink("#section-initializer", "Initializer", 'z', "Jump to initializer");
}
if (!constructors.isEmpty()) {
writeSubNavBarLink("#section-constructors", "Constructors", 't', "Jump to constructors");
}
if (hasAnyAttributes()) {
writeSubNavBarLink("#section-attributes", "Attributes", 'A', "Jump to attributes");
}
if (hasAnyMethods()) {
writeSubNavBarLink("#section-methods", "Methods", 'M', "Jump to methods");
}
if (!innerAliases.isEmpty()) {
writeSubNavBarLink("#section-nested-aliases", "Nested Aliases", 'l', "Jump to nested aliases");
}
if (!innerInterfaces.isEmpty()) {
writeSubNavBarLink("#section-nested-interfaces", "Nested Interfaces", 'I', "Jump to nested interfaces");
}
if (!innerClasses.isEmpty()) {
writeSubNavBarLink("#section-nested-classes", "Nested Classes", 'C', "Jump to nested classes");
}
if (!innerExceptions.isEmpty()) {
writeSubNavBarLink("#section-nested-exceptions", "Nested Exceptions", 'E', "Jump to nested exceptions");
}
if( isObject() ) {
writeSubNavBarLink(linkRenderer().to(klass.getContainer()).useAnchor(klass.getName()).getUrl(), "Singleton object declaration", '\0', "Jump to singleton object declaration");
}
close("div"); // sub-navbar-menu
close("div"); // sub-navbar
}
private void writeClassSignature() throws IOException {
open("span class='sub-navbar-label'");
write(getClassLabel());
close("span");
writeIcon(klass);
open("span class='sub-navbar-name'");
writeQualifyingType(klass);
open("span class='type-identifier'");
write(klass.getName());
close("span");
writeTypeParameters(klass.getTypeParameters(), klass);
close("span");
writeInheritance(klass);
writeTypeParametersConstraints(klass.getTypeParameters(), klass);
}
private void writeQualifyingType(TypeDeclaration klass) throws IOException {
if (klass.isClassOrInterfaceMember()) {
TypeDeclaration container = (TypeDeclaration) klass.getContainer();
writeQualifyingType(container);
linkRenderer().to(container).useScope(klass).write();
write(".");
}
}
private void writeDescription() throws IOException {
open("div class='class-description'");
writeTagged(klass);
writeTabs();
close("div"); // class-description
}
private void writeTabs() throws IOException {
boolean hasTypeHierarchy = klass instanceof Class;
boolean hasSupertypeHierarchy = klass instanceof Class || !isEmpty(klass.getSatisfiedTypes());
boolean hasSubtypeHierarchy = !isEmpty(tool.getSubclasses(klass)) || !isEmpty(tool.getSatisfyingClassesOrInterfaces(klass));
open("div class='type-tabs section'");
open("div class='tabbable'");
open("ul class='nav nav-tabs'");
writeTabNav("tabDocumentation", "Documentation", "icon-documentation", true, true, false);
writeTabNav("tabTypeHierarchy", "Type Hierarchy", "icon-type-hierarchy", false, hasTypeHierarchy, false);
writeTabNav("tabSupertypeHierarchy", "Supertype Hierarchy", "icon-supertype-hierarchy", false, hasSupertypeHierarchy, false);
writeTabNav("tabSubtypeHierarchy", "Subtype Hierarchy", "icon-subtype-hierarchy", false, hasSubtypeHierarchy, Util.isEnumerated(klass));
close("ul"); // nav-tabs
open("div class='tab-content'");
open("div class='tab-pane active' id='tabDocumentation'");
/*if (!klass.getUnit().getAnythingDeclaration().equals(klass) &&
klass.getExtendedTypeDeclaration()!=null) {
writeListOnSummary("extended", "Extended class: ",
singletonList(klass.getExtendedTypeDeclaration()));
}
writeListOnSummary("satisfied", "Satisfied Interfaces: ", superInterfaces);
writeEnclosingType();*/
writeAnnotationConstructors();
around("div class='doc'", getDoc(klass, linkRenderer()));
writeBy(klass);
writeSee(klass);
writeSince(klass);
close("div");
open("div class='tab-pane' id='tabTypeHierarchy'");
if( hasTypeHierarchy ) {
writeTypeHierarchy();
} else {
write("no type hierarchy
");
}
close("div");
open("div class='tab-pane' id='tabSupertypeHierarchy'");
if( hasSupertypeHierarchy ) {
writeSuperTypeHierarchy(Collections.singletonList(klass), 0);
} else {
write("no supertypes hierarchy
");
}
close("div");
open("div class='tab-pane' id='tabSubtypeHierarchy'");
if( hasSubtypeHierarchy ) {
writeSubtypesHierarchy(Collections.singletonList(klass), 0);
} else {
write("no subtypes hierarchy
");
}
close("div");
close("div"); // tab-content
close("div"); // tabbable
close("div"); // typeHierarchy
}
private void writeTabNav(String id, String name, String icon, boolean isActive, boolean isEnabled, boolean isEnumerated) throws IOException {
write("");
write("");
write("");
if(isEnumerated){
around("span class='label label-info' title='Enumerated type with an "of" clause'", "Enumerated");
write(" ");
}
write("" + name + "");
write("");
write(" ");
}
private void writeTypeHierarchy() throws IOException {
LinkedList superTypes = new LinkedList();
superTypes.add(klass.getType());
Type type = klass.getExtendedType();
while (type != null) {
superTypes.add(0, type);
type = type.getExtendedType();
}
int level = 0;
for (Type superType : superTypes) {
writeTypeHierarchyLevel(superType.getDeclaration(), level < superTypes.size() - 1);
if (!isEmpty(superType.getSatisfiedTypes())) {
write(" ...and other supertypes");
}
open("div class='subhierarchy'");
level++;
}
while (level-- > 0) {
close("div"); // subhierarchy
close("li", "ul");
}
}
private void writeSuperTypeHierarchy(List types, int level) throws IOException {
if (types.size() > 1) {
Collections.sort(types, ReferenceableComparatorByName.INSTANCE);
}
for (TypeDeclaration type : types) {
List supertypes = collectSupertypes(type);
writeTypeHierarchyLevel(type, !supertypes.isEmpty());
open("div class='subhierarchy'");
writeSuperTypeHierarchy(supertypes, level + 1);
close("div"); // subhierarchy
close("li", "ul");
}
}
private void writeSubtypesHierarchy(List types, int level) throws IOException {
if (types.size() > 1) {
Collections.sort(types, ReferenceableComparatorByName.INSTANCE);
}
for (TypeDeclaration type : types) {
List subtypes = collectSubtypes(type);
writeTypeHierarchyLevel(type, !subtypes.isEmpty());
if(level == 0 && Util.isEnumerated(type)){
around("span class='keyword'", " of");
}
open("div class='subhierarchy'");
writeSubtypesHierarchy(subtypes, level + 1);
close("div"); // subhierarchy
close("li", "ul");
}
}
private void writeTypeHierarchyLevel(TypeDeclaration type, boolean hasSublevels) throws IOException {
open("ul class='hierarchy-level'", "li");
if( hasSublevels ) {
write("");
} else {
write("");
}
writeIcon(type);
linkRenderer().to(type).useScope(klass).withinText(true).printTypeParameters(false).printAbbreviated(false).write();
}
private List collectSupertypes(TypeDeclaration type) {
List supertypes = new ArrayList();
if (type instanceof Class && type.getExtendedType() != null) {
supertypes.add(type.getExtendedType().getDeclaration());
}
List satisfiedTypes = type.getSatisfiedTypes();
if (satisfiedTypes != null) {
for (Type satisfiedType: satisfiedTypes) {
supertypes.add(satisfiedType.getDeclaration());
}
}
return supertypes;
}
private List collectSubtypes(TypeDeclaration type) {
List subtypes = new ArrayList();
List subclasses = tool.getSubclasses(type);
if (subclasses != null) {
subtypes.addAll(subclasses);
}
List satisfyingClassesOrInterfaces = tool.getSatisfyingClassesOrInterfaces(type);
if (satisfyingClassesOrInterfaces != null) {
subtypes.addAll(satisfyingClassesOrInterfaces);
}
return subtypes;
}
private void writeListOnSummary(String cssClass, String title, List> types) throws IOException {
if (!isEmpty(types)) {
open("div class='" + cssClass + " section'");
around("span class='title'", title);
boolean first = true;
for (Object type : types) {
if (!first) {
write(", ");
} else {
first = false;
}
if( type instanceof TypedDeclaration ) {
TypedDeclaration decl = (TypedDeclaration) type;
linkRenderer().to(decl).useScope(klass).write();
} else if( type instanceof ClassOrInterface ) {
ClassOrInterface coi = (ClassOrInterface) type;
linkRenderer().to(coi).useScope(klass).printAbbreviated(!isAbbreviatedType(coi)).write();
} else {
Type pt = (Type) type;
linkRenderer().to(pt).useScope(klass).printAbbreviated(!isAbbreviatedType(pt.getDeclaration())).write();
}
}
close("div");
}
}
/*private void writeEnclosingType() throws IOException {
if (klass.isMember()) {
ClassOrInterface enclosingType = (ClassOrInterface) klass.getContainer();
open("div class='enclosingType section'");
around("span class='title'", "Enclosing " + (enclosingType instanceof Class ? "class: " : "interface: "));
writeIcon(enclosingType);
linkToDeclaration(enclosingType);
close("div");
}
}*/
private void writeAnnotationConstructors() throws IOException {
if( klass.isAnnotation() ) {
List annotationConstructors = tool.getAnnotationConstructors(klass);
if( annotationConstructors != null ) {
Collections.sort(annotationConstructors, ReferenceableComparatorByName.INSTANCE);
writeListOnSummary("annotationConstructors", "Annotation Constructors: ", annotationConstructors);
}
}
}
private void writeInheritedMembers(MemberSpecification specification, String tableTitle, String rowTitle) throws IOException {
boolean first = true;
Map> superClassInheritedMembersMap = superclassInheritedMembers.get(specification);
List superClasses = new ArrayList(superclassInheritedMembers.get(specification).keySet());
Collections.sort(superClasses, ReferenceableComparatorByName.INSTANCE);
for (TypeDeclaration superClass : superClasses) {
SortedMap inheritedMembers = superClassInheritedMembersMap.get(superClass);
if (first) {
first = false;
openTable(null, tableTitle, 1, false);
}
writeInheritedMembersRow(rowTitle, superClass, inheritedMembers);
}
Map> superInterfaceInheritedMembersMap = interfaceInheritedMembers.get(specification);
List superInterfaces = new ArrayList(superInterfaceInheritedMembersMap.keySet());
Collections.sort(superInterfaces, ReferenceableComparatorByName.INSTANCE);
for (TypeDeclaration superInterface : superInterfaces) {
SortedMap members = superInterfaceInheritedMembersMap.get(superInterface);
if (members == null || members.isEmpty()) {
continue;
}
if (first) {
first = false;
openTable(null, tableTitle, 1, false);
}
writeInheritedMembersRow(rowTitle, superInterface, members);
}
if (!first) {
closeTable();
}
}
private void writeInheritedMembersRow(String title, TypeDeclaration superType, SortedMap members) throws IOException {
open("tr", "td");
write(title);
writeIcon(superType);
linkRenderer().to(superType).useScope(klass).withinText(true).write();
open("div class='inherited-members'");
boolean first = true;
for (Entry entry : members.entrySet()) {
if (!first) {
write(", ");
} else {
first = false;
}
String name = entry.getKey();
Declaration member = entry.getValue();
boolean alias = Util.nullSafeCompare(name, Util.getDeclarationName(member)) != 0;
LinkRenderer linkRenderer = linkRenderer().withinText(true).to(member).useScope(klass).printMemberContainerName(false);
if(alias){
StringBuilder sb = new StringBuilder();
sb.append("");
sb.append(name);
sb.append("
");
linkRenderer.useCustomText(sb.toString());
}
linkRenderer.write();
}
close("div");
close("td", "tr");
}
private void writeInnerTypes(Map innerTypeDeclarations, String id, String title) throws IOException {
if (!innerTypeDeclarations.isEmpty()) {
openTable(id, title, 2, true);
for (Entry entry : innerTypeDeclarations.entrySet()) {
TypeDeclaration innerTypeDeclaration = entry.getValue();
String name = entry.getKey();
if (innerTypeDeclaration instanceof ClassOrInterface) {
ClassOrInterface innerClassOrInterface = (ClassOrInterface) innerTypeDeclaration;
tool.doc(innerClassOrInterface);
doc(name, innerClassOrInterface);
}
if (innerTypeDeclaration instanceof TypeAlias) {
TypeAlias innerAlias = (TypeAlias) innerTypeDeclaration;
doc(name, innerAlias);
}
}
closeTable();
}
}
private void writeInitializer(Class klass) throws IOException {
openTable("section-initializer", "Initializer", 1, true);
open("tr", "td");
writeParameterLinksIfRequired(klass);
writeIcon(klass);
open("code class='decl-label'");
write(klass.getName());
writeParameterList(klass, klass);
close("code");
open("div class='description'");
writeParameters(klass);
writeThrows(klass);
close("div");
close("td", "tr");
closeTable();
}
private void writeConstructors() throws IOException {
if (constructors.isEmpty()){
return;
}
openTable("section-constructors", "Constructors", 2, true);
for (Entry entry : constructors.entrySet()) {
doc(entry.getKey(), entry.getValue());
}
closeTable();
}
private void writeAttributes() throws IOException {
if (attributes.isEmpty()){
return;
}
openTable(null, "Attributes", 2, true);
for (Entry entry : attributes.entrySet()) {
doc(entry.getKey(), entry.getValue());
}
closeTable();
}
private void writeMethods() throws IOException {
if (methods.isEmpty()){
return;
}
openTable(null, "Methods", 2, true);
for (Entry> entry : methods.entrySet()) {
int index = 1;
for(Function f : entry.getValue()) {
String id = null;
if( index > 1 ) {
id = entry.getKey()+"_"+index;
}
doc(id, entry.getKey(), f);
index++;
}
}
closeTable();
}
@Override
protected void registerAdditionalKeyboardShortcuts() throws IOException {
registerKeyboardShortcut('p', "index.html");
if (hasAnyAttributes()) {
registerKeyboardShortcut('a', "#section-attributes");
}
if (hasInitializer()) {
registerKeyboardShortcut('z', "#section-initializer");
}
if (!constructors.isEmpty()) {
registerKeyboardShortcut('t', "#section-constructors");
}
if (hasAnyMethods()) {
registerKeyboardShortcut('m', "#section-methods");
}
if (!innerAliases.isEmpty()) {
registerKeyboardShortcut('l', "#section-nested-aliases");
}
if (!innerInterfaces.isEmpty()) {
registerKeyboardShortcut('i', "#section-nested-interfaces");
}
if (!innerClasses.isEmpty()) {
registerKeyboardShortcut('c', "#section-nested-classes");
}
if (!innerExceptions.isEmpty()) {
registerKeyboardShortcut('e', "#section-nested-exceptions");
}
}
@Override
protected Object getFromObject() {
return klass;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy