From a0a6aef6c6b77f02b8084263b13779e0b6855a31 Mon Sep 17 00:00:00 2001 From: Emily Ball Date: Wed, 15 Dec 2021 17:37:13 -0800 Subject: [PATCH 1/4] chore: refactor YmlFilesBuilder Break up YmlFilesBuilder into multiple builders to make it easier to follow code and make changes. This change doesn't change any code code, it just moves code into new files. --- .../java/com/microsoft/build/BuilderUtil.java | 201 ++++++ .../com/microsoft/build/ClassBuilder.java | 208 ++++++ .../com/microsoft/build/PackageBuilder.java | 48 ++ .../com/microsoft/build/ProjectBuilder.java | 55 ++ .../com/microsoft/build/ReferenceBuilder.java | 283 ++++++++ .../com/microsoft/build/YmlFilesBuilder.java | 662 ++---------------- .../com/microsoft/build/BuilderUtilTest.java | 113 +++ .../com/microsoft/build/ClassBuilderTest.java | 87 +++ .../microsoft/build/ReferenceBuilderTest.java | 113 +++ .../microsoft/build/YmlFilesBuilderTest.java | 197 +----- 10 files changed, 1156 insertions(+), 811 deletions(-) create mode 100644 third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/BuilderUtil.java create mode 100644 third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/ClassBuilder.java create mode 100644 third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/PackageBuilder.java create mode 100644 third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/ProjectBuilder.java create mode 100644 third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/ReferenceBuilder.java create mode 100644 third_party/docfx-doclet-143274/src/test/java/com/microsoft/build/BuilderUtilTest.java create mode 100644 third_party/docfx-doclet-143274/src/test/java/com/microsoft/build/ClassBuilderTest.java create mode 100644 third_party/docfx-doclet-143274/src/test/java/com/microsoft/build/ReferenceBuilderTest.java diff --git a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/BuilderUtil.java b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/BuilderUtil.java new file mode 100644 index 00000000..f5bef0f6 --- /dev/null +++ b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/BuilderUtil.java @@ -0,0 +1,201 @@ +/* + * Copyright 2021 Google LLC + * + * 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 + * + * https://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.microsoft.build; + +import com.microsoft.lookup.BaseLookup; +import com.microsoft.model.MetadataFile; +import com.microsoft.model.MetadataFileItem; +import com.microsoft.model.SpecViewModel; +import com.microsoft.util.YamlUtil; +import org.apache.commons.lang3.RegExUtils; +import org.apache.commons.lang3.StringUtils; + +import javax.lang.model.element.Element; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +final class BuilderUtil { + private static final Pattern XREF_LINK_PATTERN = Pattern.compile(".*?"); + private static final Pattern XREF_LINK_CONTENT_PATTERN = Pattern.compile("(?<=.*?)"); + private static final Pattern XREF_LINK_RESOLVE_PATTERN = Pattern.compile("(?\\w+)\\#(?\\w+)(\\((?.*)\\))?"); + public final static String[] LANGS = {"java"}; + + static String getDeprecatedSummary(String depMsg, String summary) { + String result = "

(deprecated) " + depMsg + "

"; + if (summary != null && !summary.equals("")) { + result = result + "\n" + summary; + } + return result; + } + + static String populateUidValues(String text, LookupContext lookupContext) { + if (StringUtils.isBlank(text)) { + return text; + } + + Matcher linkMatcher = XREF_LINK_PATTERN.matcher(text); + while (linkMatcher.find()) { + String link = linkMatcher.group(); + Matcher linkContentMatcher = XREF_LINK_CONTENT_PATTERN.matcher(link); + if (!linkContentMatcher.find()) { + continue; + } + + String linkContent = linkContentMatcher.group(); + String uid = resolveUidFromLinkContent(linkContent, lookupContext); + String updatedLink = linkContentMatcher.replaceAll(uid); + text = StringUtils.replace(text, link, updatedLink); + } + return text; + } + + /** + * The linkContent could be in following format + * #memeber + * Class#member + * Class#method() + * Class#method(params) + */ + static String resolveUidFromLinkContent(String linkContent, LookupContext lookupContext) { + if (StringUtils.isBlank(linkContent)) { + return ""; + } + + linkContent = linkContent.trim(); + + // complete class name for class internal link + if (linkContent.startsWith("#")) { + String firstKey = lookupContext.getOwnerUid(); + linkContent = firstKey + linkContent; + } + + // fuzzy resolve, target for items from project external references + String fuzzyResolvedUid = resolveUidFromReference(linkContent, lookupContext); + + // exact resolve in lookupContext + linkContent = linkContent.replace("#", "."); + String exactResolveUid = resolveUidByLookup(linkContent, lookupContext); + return exactResolveUid.isEmpty() ? fuzzyResolvedUid : exactResolveUid; + } + + static List splitUidWithGenericsIntoClassNames(String uid) { + uid = RegExUtils.removeAll(uid, "[>]+$"); + return Arrays.asList(StringUtils.split(uid, "<")); + } + + static List replaceUidAndSplit(String uid) { + String retValue = RegExUtils.replaceAll(uid, "\\<", "//", "//>//"); + retValue = RegExUtils.replaceAll(retValue, ",", "//,//"); + retValue = RegExUtils.replaceAll(retValue, "\\[\\]", "//[]//"); + + return Arrays.asList(StringUtils.split(retValue, "//")); + } + + static List getJavaSpec(List references) { + List specList = new ArrayList<>(); + + Optional.ofNullable(references).ifPresent( + ref -> references.forEach( + uid -> { + if (uid.equalsIgnoreCase("<") + || uid.equalsIgnoreCase(">") + || uid.equalsIgnoreCase(",") + || uid.equalsIgnoreCase("[]")) + specList.add(new SpecViewModel(null, uid)); + else if (uid != "") + specList.add(new SpecViewModel(uid, uid)); + }) + ); + + return specList; + } + + static void populateUidValues(List packageMetadataFiles, List classMetadataFiles) { + Lookup lookup = new Lookup(packageMetadataFiles, classMetadataFiles); + + classMetadataFiles.forEach(classMetadataFile -> { + LookupContext lookupContext = lookup.buildContext(classMetadataFile); + + for (MetadataFileItem item : classMetadataFile.getItems()) { + item.setSummary(YamlUtil.cleanupHtml( + populateUidValues(item.getSummary(), lookupContext) + )); + + Optional.ofNullable(item.getSyntax()).ifPresent(syntax -> { + Optional.ofNullable(syntax.getParameters()).ifPresent( + methodParams -> methodParams.forEach( + param -> { + param.setDescription(populateUidValues(param.getDescription(), lookupContext)); + }) + ); + Optional.ofNullable(syntax.getReturnValue()).ifPresent(returnValue -> + returnValue.setReturnDescription( + populateUidValues(syntax.getReturnValue().getReturnDescription(), lookupContext) + ) + ); + } + ); + } + }); + } + + /** + * this method is used to do fuzzy resolve + * "*" will be added at the end of uid for method for xerf service resolve purpose + */ + static String resolveUidFromReference(String linkContent, LookupContext lookupContext) { + String uid = ""; + Matcher matcher = XREF_LINK_RESOLVE_PATTERN.matcher(linkContent); + + if (matcher.find()) { + String className = matcher.group("class"); + String memberName = matcher.group("member"); + uid = resolveUidByLookup(className, lookupContext); + if (!uid.isEmpty()) { + uid = uid.concat(".").concat(memberName); + + // linkContent targets a method + if (!StringUtils.isBlank(matcher.group(3))) { + uid = uid.concat("*"); + } + } + } + return uid; + } + + static String resolveUidByLookup(String signature, LookupContext lookupContext) { + if (StringUtils.isBlank(signature) || lookupContext == null) { + return ""; + } + return lookupContext.containsKey(signature) ? lookupContext.resolve(signature) : ""; + } + + static void populateItemFields(MetadataFileItem item, BaseLookup lookup, T element) { + String name = lookup.extractName(element); + item.setName(name); + item.setNameWithType(lookup.extractNameWithType(element)); + item.setFullName(lookup.extractFullName(element)); + item.setType(lookup.extractType(element)); + item.setJavaType(lookup.extractJavaType(element)); + item.setSummary(lookup.extractSummary(element)); + item.setContent(lookup.extractContent(element)); + } +} diff --git a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/ClassBuilder.java b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/ClassBuilder.java new file mode 100644 index 00000000..1ac99543 --- /dev/null +++ b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/ClassBuilder.java @@ -0,0 +1,208 @@ +/* + * Copyright 2021 Google LLC + * + * 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 + * + * https://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.microsoft.build; + +import com.microsoft.lookup.ClassItemsLookup; +import com.microsoft.lookup.ClassLookup; +import com.microsoft.model.MetadataFile; +import com.microsoft.model.MetadataFileItem; +import com.microsoft.model.Status; +import com.microsoft.model.TocItem; +import com.microsoft.model.TocTypeMap; +import com.microsoft.util.ElementUtil; +import com.microsoft.util.Utils; + +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.util.ElementFilter; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static com.microsoft.build.BuilderUtil.LANGS; +import static com.microsoft.build.BuilderUtil.getDeprecatedSummary; +import static com.microsoft.build.BuilderUtil.populateItemFields; + +class ClassBuilder { + private ElementUtil elementUtil; + private ClassLookup classLookup; + private ClassItemsLookup classItemsLookup; + private String outputPath; + private ReferenceBuilder referenceBuilder; + + ClassBuilder(ElementUtil elementUtil, ClassLookup classLookup, ClassItemsLookup classItemsLookup, String outputPath, ReferenceBuilder referenceBuilder) { + this.elementUtil = elementUtil; + this.classLookup = classLookup; + this.classItemsLookup = classItemsLookup; + this.outputPath = outputPath; + this.referenceBuilder = referenceBuilder; + } + + void buildFilesForInnerClasses(Element element, TocTypeMap tocTypeMap, List container) { + for (TypeElement classElement : elementUtil.extractSortedElements(element)) { + String uid = classLookup.extractUid(classElement); + String name = classLookup.extractTocName(classElement); + String status = classLookup.extractStatus(classElement); + + if (tocTypeMap.get(classElement.getKind().name()) != null) { + if (classElement.getKind().name().equals(ElementKind.CLASS.name()) && name.contains("Exception")) { + tocTypeMap.get("EXCEPTION").add(new TocItem(uid, name, status)); + } else { + tocTypeMap.get(classElement.getKind().name()).add(new TocItem(uid, name, status)); + } + } else { + tocTypeMap.get(ElementKind.CLASS.name()).add(new TocItem(uid, name, status)); + } + + container.add(buildClassYmlFile(classElement)); + buildFilesForInnerClasses(classElement, tocTypeMap, container); + } + } + + private MetadataFile buildClassYmlFile(TypeElement classElement) { + String fileName = classLookup.extractHref(classElement); + MetadataFile classMetadataFile = new MetadataFile(outputPath, fileName); + addClassInfo(classElement, classMetadataFile); + addConstructorsInfo(classElement, classMetadataFile); + addMethodsInfo(classElement, classMetadataFile); + addFieldsInfo(classElement, classMetadataFile); + referenceBuilder.addReferencesInfo(classElement, classMetadataFile); + applyPostProcessing(classMetadataFile); + return classMetadataFile; + } + + private void addClassInfo(TypeElement classElement, MetadataFile classMetadataFile) { + MetadataFileItem classItem = new MetadataFileItem(LANGS, classLookup.extractUid(classElement)); + classItem.setId(classLookup.extractId(classElement)); + classItem.setParent(classLookup.extractParent(classElement)); + addChildren(classElement, classItem.getChildren()); + populateItemFields(classItem, classLookup, classElement); + classItem.setPackageName(classLookup.extractPackageName(classElement)); + classItem.setTypeParameters(classLookup.extractTypeParameters(classElement)); + classItem.setInheritance(classLookup.extractSuperclass(classElement)); + classItem.setInterfaces(classLookup.extractInterfaces(classElement)); + classItem.setInheritedMethods(classLookup.extractInheritedMethods(classElement)); + String depMsg = classLookup.extractDeprecatedDescription(classElement); + if (depMsg != null) { + classItem.setSummary(getDeprecatedSummary(depMsg, classItem.getSummary())); + classItem.setStatus(Status.DEPRECATED.toString()); + } + classMetadataFile.getItems().add(classItem); + } + + void addConstructorsInfo(TypeElement classElement, MetadataFile classMetadataFile) { + for (ExecutableElement constructorElement : ElementFilter.constructorsIn(classElement.getEnclosedElements())) { + MetadataFileItem constructorItem = buildMetadataFileItem(constructorElement); + constructorItem.setOverload(classItemsLookup.extractOverload(constructorElement)); + constructorItem.setContent(classItemsLookup.extractConstructorContent(constructorElement)); + constructorItem.setParameters(classItemsLookup.extractParameters(constructorElement)); + String depMsg = classItemsLookup.extractDeprecatedDescription(constructorElement); + if (depMsg != null) { + constructorItem.setSummary(getDeprecatedSummary(depMsg, constructorItem.getSummary())); + constructorItem.setStatus(Status.DEPRECATED.toString()); + } + classMetadataFile.getItems().add(constructorItem); + + referenceBuilder.addParameterReferences(constructorItem, classMetadataFile); + referenceBuilder.addOverloadReferences(constructorItem, classMetadataFile); + } + } + + private void addMethodsInfo(TypeElement classElement, MetadataFile classMetadataFile) { + ElementFilter.methodsIn(classElement.getEnclosedElements()).stream() + .filter(methodElement -> !Utils.isPrivateOrPackagePrivate(methodElement)) + .forEach(methodElement -> { + MetadataFileItem methodItem = buildMetadataFileItem(methodElement); + methodItem.setOverload(classItemsLookup.extractOverload(methodElement)); + methodItem.setContent(classItemsLookup.extractMethodContent(methodElement)); + methodItem.setExceptions(classItemsLookup.extractExceptions(methodElement)); + methodItem.setParameters(classItemsLookup.extractParameters(methodElement)); + methodItem.setReturn(classItemsLookup.extractReturn(methodElement)); + methodItem.setOverridden(classItemsLookup.extractOverridden(methodElement)); + String depMsg = classItemsLookup.extractDeprecatedDescription(methodElement); + if (depMsg != null) { + methodItem.setSummary(getDeprecatedSummary(depMsg, methodItem.getSummary())); + methodItem.setStatus(Status.DEPRECATED.toString()); + } + + classMetadataFile.getItems().add(methodItem); + referenceBuilder.addExceptionReferences(methodItem, classMetadataFile); + referenceBuilder.addParameterReferences(methodItem, classMetadataFile); + referenceBuilder.addReturnReferences(methodItem, classMetadataFile); + referenceBuilder.addOverloadReferences(methodItem, classMetadataFile); + }); + } + + private void addFieldsInfo(TypeElement classElement, MetadataFile classMetadataFile) { + ElementFilter.fieldsIn(classElement.getEnclosedElements()).stream() + .filter(fieldElement -> !Utils.isPrivateOrPackagePrivate(fieldElement)) + .forEach(fieldElement -> { + MetadataFileItem fieldItem = buildMetadataFileItem(fieldElement); + fieldItem.setContent(classItemsLookup.extractFieldContent(fieldElement)); + fieldItem.setReturn(classItemsLookup.extractReturn(fieldElement)); + String depMsg = classItemsLookup.extractDeprecatedDescription(fieldElement); + if (depMsg != null) { + fieldItem.setSummary(getDeprecatedSummary(depMsg, fieldItem.getSummary())); + fieldItem.setStatus(Status.DEPRECATED.toString()); + } + + classMetadataFile.getItems().add(fieldItem); + referenceBuilder.addReturnReferences(fieldItem, classMetadataFile); + }); + } + + private void applyPostProcessing(MetadataFile classMetadataFile) { + referenceBuilder.expandComplexGenericsInReferences(classMetadataFile); + } + + private MetadataFileItem buildMetadataFileItem(Element element) { + return new MetadataFileItem(LANGS, classItemsLookup.extractUid(element)) {{ + String name = classItemsLookup.extractName(element); + setId(classItemsLookup.extractId(element)); + setParent(classItemsLookup.extractParent(element)); + setName(name); + setNameWithType(classItemsLookup.extractNameWithType(element)); + setFullName(classItemsLookup.extractFullName(element)); + setType(classItemsLookup.extractType(element)); + setJavaType(classItemsLookup.extractJavaType(element)); + setPackageName(classItemsLookup.extractPackageName(element)); + setSummary(classItemsLookup.extractSummary(element)); + }}; + } + + private void addChildren(TypeElement classElement, List children) { + collect(classElement, children, ElementFilter::constructorsIn, classItemsLookup::extractUid); + collect(classElement, children, ElementFilter::methodsIn, classItemsLookup::extractUid); + collect(classElement, children, ElementFilter::fieldsIn, classItemsLookup::extractUid); + collect(classElement, children, ElementFilter::typesIn, String::valueOf); + } + + private void collect(TypeElement classElement, List children, + Function, List> selectFunc, + Function mapFunc) { + + List elements = selectFunc.apply(classElement.getEnclosedElements()); + children.addAll(filterPrivateElements(elements).stream() + .map(mapFunc).collect(Collectors.toList())); + } + + private List filterPrivateElements(List elements) { + return elements.stream() + .filter(element -> !Utils.isPrivateOrPackagePrivate(element)).collect(Collectors.toList()); + } +} diff --git a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/PackageBuilder.java b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/PackageBuilder.java new file mode 100644 index 00000000..42228bbd --- /dev/null +++ b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/PackageBuilder.java @@ -0,0 +1,48 @@ +/* + * Copyright 2021 Google LLC + * + * 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 + * + * https://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.microsoft.build; + +import com.microsoft.lookup.PackageLookup; +import com.microsoft.model.MetadataFile; +import com.microsoft.model.MetadataFileItem; + +import javax.lang.model.element.PackageElement; + +import static com.microsoft.build.BuilderUtil.LANGS; +import static com.microsoft.build.BuilderUtil.populateItemFields; + +class PackageBuilder { + private final PackageLookup packageLookup; + private final String outputPath; + private final ReferenceBuilder referenceBuilder; + + PackageBuilder(PackageLookup packageLookup, String outputPath, ReferenceBuilder referenceBuilder) { + this.packageLookup = packageLookup; + this.outputPath = outputPath; + this.referenceBuilder = referenceBuilder; + } + + MetadataFile buildPackageMetadataFile(PackageElement packageElement) { + String fileName = packageLookup.extractHref(packageElement); + MetadataFile packageMetadataFile = new MetadataFile(outputPath, fileName); + MetadataFileItem packageItem = new MetadataFileItem(LANGS, packageLookup.extractUid(packageElement)); + packageItem.setId(packageLookup.extractId(packageElement)); + referenceBuilder.addChildrenReferences(packageElement, packageItem.getChildren(), packageMetadataFile.getReferences()); + populateItemFields(packageItem, packageLookup, packageElement); + packageMetadataFile.getItems().add(packageItem); + return packageMetadataFile; + } +} diff --git a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/ProjectBuilder.java b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/ProjectBuilder.java new file mode 100644 index 00000000..f51f95d9 --- /dev/null +++ b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/ProjectBuilder.java @@ -0,0 +1,55 @@ +/* + * Copyright 2021 Google LLC + * + * 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 + * + * https://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.microsoft.build; + +import com.microsoft.model.MetadataFile; +import com.microsoft.model.MetadataFileItem; + +import java.util.ArrayList; +import java.util.List; + +import static com.microsoft.build.BuilderUtil.LANGS; + +class ProjectBuilder { + private final String projectName; + + ProjectBuilder(String projectName) { + this.projectName = projectName; + } + + void buildProjectMetadataFile(List packageItems, MetadataFile projectMetadataFile) { + MetadataFileItem projectItem = new MetadataFileItem(LANGS, projectName); + projectItem.setNameWithType(projectName); + projectItem.setFullName(projectName); + projectItem.setType("Namespace"); + projectItem.setJavaType("overview"); + + List children = new ArrayList<>(); + List references = new ArrayList<>(); + packageItems.stream().forEach(i -> { + children.add(i.getUid()); + MetadataFileItem refItem = new MetadataFileItem(i.getUid()); + refItem.setName(i.getName()); + refItem.setNameWithType(i.getNameWithType()); + refItem.setFullName(i.getFullName()); + references.add(refItem); + }); + + projectItem.getChildren().addAll(children); + projectMetadataFile.getReferences().addAll(references); + projectMetadataFile.getItems().add(projectItem); + } +} diff --git a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/ReferenceBuilder.java b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/ReferenceBuilder.java new file mode 100644 index 00000000..c1ed3387 --- /dev/null +++ b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/ReferenceBuilder.java @@ -0,0 +1,283 @@ +/* + * Copyright 2021 Google LLC + * + * 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 + * + * https://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.microsoft.build; + +import com.microsoft.lookup.ClassLookup; +import com.microsoft.model.MetadataFile; +import com.microsoft.model.MetadataFileItem; +import com.microsoft.model.SpecViewModel; +import com.microsoft.util.ElementUtil; +import jdk.javadoc.doclet.DocletEnvironment; +import org.apache.commons.lang3.RegExUtils; + +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.lang.model.util.ElementFilter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static com.microsoft.build.BuilderUtil.getJavaSpec; +import static com.microsoft.build.BuilderUtil.populateItemFields; +import static com.microsoft.build.BuilderUtil.replaceUidAndSplit; +import static com.microsoft.build.BuilderUtil.splitUidWithGenericsIntoClassNames; + +class ReferenceBuilder { + private final Pattern JAVA_PATTERN = Pattern.compile("^java.*"); + private final Pattern PROTOBUF_PATTERN = Pattern.compile("^com.google.protobuf.*"); + private final Pattern GAX_PATTERN = Pattern.compile("^com.google.api.gax.*"); + private final Pattern APICOMMON_PATTERN = Pattern.compile("^com.google.api.core.*"); + private final Pattern LONGRUNNING_PATTERN = Pattern.compile("^com.google.longrunning.*"); + private final Pattern ENDING_PATTERN = Pattern.compile(".*<\\?>$"); + private final String PRIMITIVE_URL = "https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html"; + private final String JAVA_BASE_URL = "https://docs.oracle.com/javase/8/docs/api/"; + private final DocletEnvironment environment; + private final ClassLookup classLookup; + private final ElementUtil elementUtil; + + ReferenceBuilder(DocletEnvironment environment, ClassLookup classLookup, ElementUtil elementUtil) { + this.environment = environment; + this.classLookup = classLookup; + this.elementUtil = elementUtil; + } + + MetadataFileItem buildClassReference(TypeElement classElement) { + MetadataFileItem referenceItem = new MetadataFileItem(classLookup.extractUid(classElement)); + referenceItem.setName(classLookup.extractName(classElement)); + referenceItem.setNameWithType(classLookup.extractNameWithType(classElement)); + referenceItem.setFullName(classLookup.extractFullName(classElement)); + return referenceItem; + } + + void addReferencesInfo(TypeElement classElement, MetadataFile classMetadataFile) { + MetadataFileItem classReference = new MetadataFileItem(classLookup.extractUid(classElement)); + classReference.setParent(classLookup.extractParent(classElement)); + populateItemFields(classReference, classLookup, classElement); + classReference.setTypeParameters(classLookup.extractTypeParameters(classElement)); + + addTypeParameterReferences(classReference, classMetadataFile); + addSuperclassAndInterfacesReferences(classElement, classMetadataFile); + addInnerClassesReferences(classElement, classMetadataFile); + } + + void addChildrenReferences(Element element, List packageChildren, + Set referencesCollector) { + for (TypeElement classElement : elementUtil.extractSortedElements(element)) { + referencesCollector.add(buildClassReference(classElement)); + + packageChildren.add(classLookup.extractUid(classElement)); + addChildrenReferences(classElement, packageChildren, referencesCollector); + } + } + + String getJavaReferenceHref(String uid) { + if (uid == null || uid.equals("")) { + return JAVA_BASE_URL; + } + // example1 uid: "java.lang.Object.equals(java.lang.Object)" + // example2 uid: "java.lang.Object" + String endURL = uid.replaceAll("", ""); + + Pattern argPattern = Pattern.compile(".*\\(.*\\).*"); + if (argPattern.matcher(endURL).find()) { + // example1 + // argumentSplit: ["java.lang.Object.equals", "java.lang.Object)"] + // nameSplit: ["java", "lang", "Object", "equals"] + List argumentSplit = Arrays.asList(endURL.split("\\(")); + List nameSplit = Arrays.asList(argumentSplit.get(0).split("\\.")); + + // className: "java/lang/Object" + // methodName: "#equals" + // argumentsName: "#java.lang.Object-" + String className = String.join("/", nameSplit.subList(0, nameSplit.size() - 1)); + String methodName = "#" + nameSplit.get(nameSplit.size() - 1); + String argumentsName = argumentSplit.get(1).replaceAll("[,)]", "-"); + + // endURL: "java/lang/Object.html#equals-java.lang.Object-" + endURL = className + ".html" + methodName + "-" + argumentsName; + } else { + // example2 + // endURL = java/lang/Object.html + endURL = endURL.replaceAll("\\.", "/"); + endURL = endURL + ".html"; + } + return JAVA_BASE_URL + endURL; + } + + void updateExternalReferences(List classMetadataFiles) { + classMetadataFiles.forEach(file -> file.getReferences() + .forEach(ref -> updateExternalReference(ref))); + } + + private void updateExternalReference(MetadataFileItem reference) { + String uid = reference.getUid(); + uid = updateReferenceUid(uid); + + if (isJavaPrimitive(uid)) { + reference.setHref(PRIMITIVE_URL); + return; + } + if (isJavaLibrary(uid)) { + reference.setHref(getJavaReferenceHref(uid)); + } + if (isExternalReference(uid)) { + reference.setIsExternal(true); + } + if (reference.getSpecForJava().size() > 0) { + for (SpecViewModel spec : reference.getSpecForJava()) { + String specUid = spec.getUid(); + if (specUid != null) { + if (isJavaPrimitive(specUid)) { + spec.setHref(PRIMITIVE_URL); + } + if (isJavaLibrary(specUid)) { + spec.setHref(getJavaReferenceHref(specUid)); + } + if (isExternalReference(specUid)) { + spec.setIsExternal(true); + } + } + } + } + } + + private String updateReferenceUid(String uid) { + if (ENDING_PATTERN.matcher(uid).find()) { + uid = uid.replace("", ""); + } + return uid; + } + + private boolean isExternalReference(String uid) { + return (PROTOBUF_PATTERN.matcher(uid).find() || GAX_PATTERN.matcher(uid).find() || APICOMMON_PATTERN.matcher(uid).find() || GAX_PATTERN.matcher(uid).find() || LONGRUNNING_PATTERN.matcher(uid).find()); + } + + private boolean isJavaPrimitive(String uid) { + return (uid.equals("boolean") || uid.equals("int") || uid.equals("byte") || uid.equals("long") || uid.equals("float") || uid.equals("double") || uid.equals("char") || uid.equals("short")); + } + + private boolean isJavaLibrary(String uid) { + return JAVA_PATTERN.matcher(uid).find(); + } + + void addParameterReferences(MetadataFileItem methodItem, MetadataFile classMetadataFile) { + classMetadataFile.getReferences().addAll( + methodItem.getSyntax().getParameters().stream() + .map(parameter -> buildRefItem(parameter.getType())) + .filter(o -> !classMetadataFile.getItems().contains(o)) + .collect(Collectors.toList())); + } + + void addReturnReferences(MetadataFileItem methodItem, MetadataFile classMetadataFile) { + classMetadataFile.getReferences().addAll( + Stream.of(methodItem.getSyntax().getReturnValue()) + .filter(Objects::nonNull) + .map(returnValue -> buildRefItem(returnValue.getReturnType())) + .filter(o -> !classMetadataFile.getItems().contains(o)) + .collect(Collectors.toList())); + } + + void addExceptionReferences(MetadataFileItem methodItem, MetadataFile classMetadataFile) { + classMetadataFile.getReferences().addAll( + methodItem.getExceptions().stream() + .map(exceptionItem -> buildRefItem(exceptionItem.getType())) + .filter(o -> !classMetadataFile.getItems().contains(o)) + .collect(Collectors.toList())); + } + + void addTypeParameterReferences(MetadataFileItem methodItem, MetadataFile classMetadataFile) { + classMetadataFile.getReferences().addAll( + methodItem.getSyntax().getTypeParameters().stream() + .map(typeParameter -> { + String id = typeParameter.getId(); + return new MetadataFileItem(id, id, false); + }).collect(Collectors.toList())); + } + + void addSuperclassAndInterfacesReferences(TypeElement classElement, MetadataFile classMetadataFile) { + classMetadataFile.getReferences().addAll(classLookup.extractReferences(classElement)); + } + + void addInnerClassesReferences(TypeElement classElement, MetadataFile classMetadataFile) { + classMetadataFile.getReferences().addAll( + ElementFilter.typesIn(elementUtil.extractSortedElements(classElement)).stream() + .map(this::buildClassReference) + .collect(Collectors.toList())); + } + + void addOverloadReferences(MetadataFileItem item, MetadataFile classMetadataFile) { + classMetadataFile.getReferences().add(new MetadataFileItem(item.getOverload()) {{ + setName(RegExUtils.removeAll(item.getName(), "\\(.*\\)$")); + setNameWithType(RegExUtils.removeAll(item.getNameWithType(), "\\(.*\\)$")); + setFullName(RegExUtils.removeAll(item.getFullName(), "\\(.*\\)$")); + setPackageName(item.getPackageName()); + }}); + } + + /** + * Replace one record in 'references' with several records in this way: + *
+     * a.b.c.List> ->
+     *     - a.b.c.List
+     *     - df.mn.ClassOne
+     *     - tr.T
+     * 
+ */ + void expandComplexGenericsInReferences(MetadataFile classMetadataFile) { + Set additionalItems = new LinkedHashSet<>(); + Iterator iterator = classMetadataFile.getReferences().iterator(); + while (iterator.hasNext()) { + MetadataFileItem item = iterator.next(); + String uid = item.getUid(); + if (!uid.endsWith("*") && uid.contains("<")) { + List classNames = splitUidWithGenericsIntoClassNames(uid); + additionalItems.addAll(classNames.stream() + .map(s -> new MetadataFileItem(s, classLookup.makeTypeShort(s), false)) + .collect(Collectors.toSet())); + } + } + // Remove items which already exist in 'items' section (compared by 'uid' field) + additionalItems.removeAll(classMetadataFile.getItems()); + + classMetadataFile.getReferences().addAll(additionalItems); + } + + MetadataFileItem buildRefItem(String uid) { + if (!uid.endsWith("*") && (uid.contains("<") || uid.contains("[]"))) { + return new MetadataFileItem(uid, getJavaSpec(replaceUidAndSplit(uid))); + } else { + List fullNameList = new ArrayList<>(); + + environment.getIncludedElements().forEach( + element -> elementUtil.extractSortedElements(element).forEach( + typeElement -> fullNameList.add(classLookup.extractFullName(typeElement))) + ); + + if (fullNameList.contains(uid)) { + return new MetadataFileItem(uid, classLookup.makeTypeShort(uid), false); + } else { + return new MetadataFileItem(uid, getJavaSpec(replaceUidAndSplit(uid))); + } + } + } +} diff --git a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/YmlFilesBuilder.java b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/YmlFilesBuilder.java index 98d434d3..1dfa0a71 100644 --- a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/YmlFilesBuilder.java +++ b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/YmlFilesBuilder.java @@ -1,51 +1,34 @@ package com.microsoft.build; -import com.microsoft.lookup.BaseLookup; import com.microsoft.lookup.ClassItemsLookup; import com.microsoft.lookup.ClassLookup; import com.microsoft.lookup.PackageLookup; -import com.microsoft.model.*; +import com.microsoft.model.MetadataFile; +import com.microsoft.model.MetadataFileItem; +import com.microsoft.model.TocFile; +import com.microsoft.model.TocItem; +import com.microsoft.model.TocTypeMap; import com.microsoft.util.ElementUtil; import com.microsoft.util.FileUtil; -import com.microsoft.util.Utils; -import com.microsoft.util.YamlUtil; import jdk.javadoc.doclet.DocletEnvironment; -import org.apache.commons.lang3.RegExUtils; -import org.apache.commons.lang3.StringUtils; -import javax.lang.model.element.*; -import javax.lang.model.util.ElementFilter; -import java.util.*; -import java.util.function.Function; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import javax.lang.model.element.PackageElement; +import java.util.ArrayList; +import java.util.List; import java.util.stream.Collectors; -import java.util.stream.Stream; +import static com.microsoft.build.BuilderUtil.populateUidValues; public class YmlFilesBuilder { - - private final static String[] LANGS = {"java"}; - private final Pattern XREF_LINK_PATTERN = Pattern.compile(".*?"); - private final Pattern XREF_LINK_CONTENT_PATTERN = Pattern.compile("(?<=.*?)"); - private final Pattern XREF_LINK_RESOLVE_PATTERN = Pattern.compile("(?\\w+)\\#(?\\w+)(\\((?.*)\\))?"); - private DocletEnvironment environment; private String outputPath; private ElementUtil elementUtil; private PackageLookup packageLookup; - private ClassItemsLookup classItemsLookup; - private ClassLookup classLookup; private String projectName; - - private final Pattern JAVA_PATTERN = Pattern.compile("^java.*"); - private final Pattern PROTOBUF_PATTERN = Pattern.compile("^com.google.protobuf.*"); - private final Pattern GAX_PATTERN = Pattern.compile("^com.google.api.gax.*"); - private final Pattern APICOMMON_PATTERN = Pattern.compile("^com.google.api.core.*"); - private final Pattern LONGRUNNING_PATTERN = Pattern.compile("^com.google.longrunning.*"); - private final Pattern ENDING_PATTERN = Pattern.compile(".*<\\?>$"); - private final String PRIMITIVE_URL = "https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html"; - private final String JAVA_BASE_URL = "https://docs.oracle.com/javase/8/docs/api/"; + private ProjectBuilder projectBuilder; + private PackageBuilder packageBuilder; + private ClassBuilder classBuilder; + private ReferenceBuilder referenceBuilder; public YmlFilesBuilder(DocletEnvironment environment, String outputPath, String[] excludePackages, String[] excludeClasses, String projectName) { @@ -53,30 +36,41 @@ public YmlFilesBuilder(DocletEnvironment environment, String outputPath, this.outputPath = outputPath; this.elementUtil = new ElementUtil(excludePackages, excludeClasses); this.packageLookup = new PackageLookup(environment); - this.classItemsLookup = new ClassItemsLookup(environment); - this.classLookup = new ClassLookup(environment); this.projectName = projectName; + this.projectBuilder = new ProjectBuilder(projectName); + ClassLookup classLookup = new ClassLookup(environment); + this.referenceBuilder = new ReferenceBuilder(environment, classLookup, elementUtil); + this.packageBuilder = new PackageBuilder(packageLookup, outputPath, referenceBuilder); + this.classBuilder = new ClassBuilder(elementUtil, classLookup, new ClassItemsLookup(environment), outputPath, referenceBuilder); } public boolean build() { - MetadataFile projectMetadataFile = new MetadataFile(outputPath,"overview.yml");; - List packageItems = new ArrayList<>(); + // table of contents + TocFile tocFile = new TocFile(outputPath, projectName); + // overview page + MetadataFile projectMetadataFile = new MetadataFile(outputPath, "overview.yml"); + // package summary pages List packageMetadataFiles = new ArrayList<>(); + // packages + List packageItems = new ArrayList<>(); + // class/enum/interface/etc. pages List classMetadataFiles = new ArrayList<>(); - TocFile tocFile = new TocFile(outputPath, projectName); - for (PackageElement packageElement : elementUtil.extractPackageElements(environment.getIncludedElements())) { - String uid = packageLookup.extractUid(packageElement); - String status = packageLookup.extractStatus(packageElement.getQualifiedName().toString()); - TocItem packageTocItem = new TocItem(uid, uid, status); - packageMetadataFiles.add(buildPackageMetadataFile(packageElement)); - packageTocItem.getItems().add(new TocItem(uid, "Package summary")); + for (PackageElement packageElement : + elementUtil.extractPackageElements(environment.getIncludedElements())) { + String packageUid = packageLookup.extractUid(packageElement); + String packageStatus = packageLookup.extractStatus(packageElement.getQualifiedName().toString()); + TocItem packageTocItem = new TocItem(packageUid, packageUid, packageStatus); + // build package summary + packageMetadataFiles.add(packageBuilder.buildPackageMetadataFile(packageElement)); + // add package summary to toc + packageTocItem.getItems().add(new TocItem(packageUid, "Package summary")); + tocFile.addTocItem(packageTocItem); + // build classes/interfaces/enums/exceptions/annotations TocTypeMap typeMap = new TocTypeMap(); - buildFilesForInnerClasses(packageElement,typeMap, classMetadataFiles); + classBuilder.buildFilesForInnerClasses(packageElement, typeMap, classMetadataFiles); packageTocItem.getItems().addAll(joinTocTypeItems(typeMap)); - - tocFile.addTocItem(packageTocItem); } for (MetadataFile packageFile : packageMetadataFiles) { @@ -91,10 +85,14 @@ public boolean build() { } } } - buildProjectMetadataFile(packageItems, projectMetadataFile); + // build project summary page + projectBuilder.buildProjectMetadataFile(packageItems, projectMetadataFile); + + // post-processing populateUidValues(packageMetadataFiles, classMetadataFiles); - updateExternalReferences(classMetadataFiles); + referenceBuilder.updateExternalReferences(classMetadataFiles); + // write to yaml files FileUtil.dumpToFile(projectMetadataFile); packageMetadataFiles.forEach(FileUtil::dumpToFile); classMetadataFiles.forEach(FileUtil::dumpToFile); @@ -103,7 +101,7 @@ public boolean build() { return true; } - List joinTocTypeItems(TocTypeMap tocTypeMap){ + List joinTocTypeItems(TocTypeMap tocTypeMap) { return tocTypeMap.getTitleList().stream() .filter(kindTitle -> tocTypeMap.get(kindTitle.getElementKind()).size() > 0) .flatMap(kindTitle -> { @@ -111,574 +109,4 @@ List joinTocTypeItems(TocTypeMap tocTypeMap){ return tocTypeMap.get(kindTitle.getElementKind()).stream(); }).collect(Collectors.toList()); } - - void buildFilesForInnerClasses(Element element, TocTypeMap tocTypeMap, List container) { - for (TypeElement classElement : elementUtil.extractSortedElements(element)) { - String uid = classLookup.extractUid(classElement); - String name = classLookup.extractTocName(classElement); - String status = classLookup.extractStatus(classElement); - - if (tocTypeMap.get(classElement.getKind().name()) != null) { - if (classElement.getKind().name().equals(ElementKind.CLASS.name()) && name.contains("Exception")) { - tocTypeMap.get("EXCEPTION").add(new TocItem(uid, name, status)); - } else { - tocTypeMap.get(classElement.getKind().name()).add(new TocItem(uid, name, status)); - } - } else { - tocTypeMap.get(ElementKind.CLASS.name()).add(new TocItem(uid, name, status)); - } - - container.add(buildClassYmlFile(classElement)); - buildFilesForInnerClasses(classElement, tocTypeMap, container); - } - } - - - void buildProjectMetadataFile(List packageItems, MetadataFile projectMetadataFile) { - MetadataFileItem projectItem = new MetadataFileItem(LANGS, projectName); - projectItem.setNameWithType(projectName); - projectItem.setFullName(projectName); - projectItem.setType("Namespace"); - projectItem.setJavaType("overview"); - - List children = new ArrayList<>(); - List references = new ArrayList<>(); - packageItems.stream().forEach(i -> { - children.add(i.getUid()); - MetadataFileItem refItem = new MetadataFileItem(i.getUid()); - refItem.setName(i.getName()); - refItem.setNameWithType(i.getNameWithType()); - refItem.setFullName(i.getFullName()); - references.add(refItem); - }); - - projectItem.getChildren().addAll(children); - projectMetadataFile.getReferences().addAll(references); - projectMetadataFile.getItems().add(projectItem); - } - - MetadataFile buildPackageMetadataFile(PackageElement packageElement) { - String fileName = packageLookup.extractHref(packageElement); - MetadataFile packageMetadataFile = new MetadataFile(outputPath, fileName); - MetadataFileItem packageItem = new MetadataFileItem(LANGS, packageLookup.extractUid(packageElement)); - packageItem.setId(packageLookup.extractId(packageElement)); - addChildrenReferences(packageElement, packageItem.getChildren(), packageMetadataFile.getReferences()); - populateItemFields(packageItem, packageLookup, packageElement); - packageMetadataFile.getItems().add(packageItem); - return packageMetadataFile; - } - - void addChildrenReferences(Element element, List packageChildren, - Set referencesCollector) { - for (TypeElement classElement : elementUtil.extractSortedElements(element)) { - referencesCollector.add(buildClassReference(classElement)); - - packageChildren.add(classLookup.extractUid(classElement)); - addChildrenReferences(classElement, packageChildren, referencesCollector); - } - } - - MetadataFileItem buildClassReference(TypeElement classElement) { - MetadataFileItem referenceItem = new MetadataFileItem(classLookup.extractUid(classElement)); - referenceItem.setName(classLookup.extractName(classElement)); - referenceItem.setNameWithType(classLookup.extractNameWithType(classElement)); - referenceItem.setFullName(classLookup.extractFullName(classElement)); - return referenceItem; - } - - void populateItemFields(MetadataFileItem item, BaseLookup lookup, T element) { - String name = lookup.extractName(element); - item.setName(name); - item.setNameWithType(lookup.extractNameWithType(element)); - item.setFullName(lookup.extractFullName(element)); - item.setType(lookup.extractType(element)); - item.setJavaType(lookup.extractJavaType(element)); - item.setSummary(lookup.extractSummary(element)); - item.setContent(lookup.extractContent(element)); - } - - MetadataFile buildClassYmlFile(TypeElement classElement) { - String fileName = classLookup.extractHref(classElement); - MetadataFile classMetadataFile = new MetadataFile(outputPath, fileName); - addClassInfo(classElement, classMetadataFile); - addConstructorsInfo(classElement, classMetadataFile); - addMethodsInfo(classElement, classMetadataFile); - addFieldsInfo(classElement, classMetadataFile); - addReferencesInfo(classElement, classMetadataFile); - applyPostProcessing(classMetadataFile); - return classMetadataFile; - } - - void addClassInfo(TypeElement classElement, MetadataFile classMetadataFile) { - MetadataFileItem classItem = new MetadataFileItem(LANGS, classLookup.extractUid(classElement)); - classItem.setId(classLookup.extractId(classElement)); - classItem.setParent(classLookup.extractParent(classElement)); - addChildren(classElement, classItem.getChildren()); - populateItemFields(classItem, classLookup, classElement); - classItem.setPackageName(classLookup.extractPackageName(classElement)); - classItem.setTypeParameters(classLookup.extractTypeParameters(classElement)); - classItem.setInheritance(classLookup.extractSuperclass(classElement)); - classItem.setInterfaces(classLookup.extractInterfaces(classElement)); - classItem.setInheritedMethods(classLookup.extractInheritedMethods(classElement)); - String depMsg = classLookup.extractDeprecatedDescription(classElement); - if (depMsg != null) { - classItem.setSummary(getDeprecatedSummary(depMsg, classItem.getSummary())); - classItem.setStatus(Status.DEPRECATED.toString()); - } - classMetadataFile.getItems().add(classItem); - } - - String getDeprecatedSummary(String depMsg, String summary){ - String result = "

(deprecated) " + depMsg + "

"; - if (summary != null && !summary.equals("")) { - result = result + "\n" + summary; - } - return result; - } - - void addChildren(TypeElement classElement, List children) { - collect(classElement, children, ElementFilter::constructorsIn, classItemsLookup::extractUid); - collect(classElement, children, ElementFilter::methodsIn, classItemsLookup::extractUid); - collect(classElement, children, ElementFilter::fieldsIn, classItemsLookup::extractUid); - collect(classElement, children, ElementFilter::typesIn, String::valueOf); - } - - List filterPrivateElements(List elements) { - return elements.stream() - .filter(element -> !Utils.isPrivateOrPackagePrivate(element)).collect(Collectors.toList()); - } - - void collect(TypeElement classElement, List children, - Function, List> selectFunc, - Function mapFunc) { - - List elements = selectFunc.apply(classElement.getEnclosedElements()); - children.addAll(filterPrivateElements(elements).stream() - .map(mapFunc).collect(Collectors.toList())); - } - - void addConstructorsInfo(TypeElement classElement, MetadataFile classMetadataFile) { - for (ExecutableElement constructorElement : ElementFilter.constructorsIn(classElement.getEnclosedElements())) { - MetadataFileItem constructorItem = buildMetadataFileItem(constructorElement); - constructorItem.setOverload(classItemsLookup.extractOverload(constructorElement)); - constructorItem.setContent(classItemsLookup.extractConstructorContent(constructorElement)); - constructorItem.setParameters(classItemsLookup.extractParameters(constructorElement)); - String depMsg = classItemsLookup.extractDeprecatedDescription(constructorElement); - if (depMsg != null) { - constructorItem.setSummary(getDeprecatedSummary(depMsg, constructorItem.getSummary())); - constructorItem.setStatus(Status.DEPRECATED.toString()); - } - classMetadataFile.getItems().add(constructorItem); - - addParameterReferences(constructorItem, classMetadataFile); - addOverloadReferences(constructorItem, classMetadataFile); - } - } - - void addMethodsInfo(TypeElement classElement, MetadataFile classMetadataFile) { - ElementFilter.methodsIn(classElement.getEnclosedElements()).stream() - .filter(methodElement -> !Utils.isPrivateOrPackagePrivate(methodElement)) - .forEach(methodElement -> { - MetadataFileItem methodItem = buildMetadataFileItem(methodElement); - methodItem.setOverload(classItemsLookup.extractOverload(methodElement)); - methodItem.setContent(classItemsLookup.extractMethodContent(methodElement)); - methodItem.setExceptions(classItemsLookup.extractExceptions(methodElement)); - methodItem.setParameters(classItemsLookup.extractParameters(methodElement)); - methodItem.setReturn(classItemsLookup.extractReturn(methodElement)); - methodItem.setOverridden(classItemsLookup.extractOverridden(methodElement)); - String depMsg = classItemsLookup.extractDeprecatedDescription(methodElement); - if (depMsg != null) { - methodItem.setSummary(getDeprecatedSummary(depMsg, methodItem.getSummary())); - methodItem.setStatus(Status.DEPRECATED.toString()); - } - - classMetadataFile.getItems().add(methodItem); - addExceptionReferences(methodItem, classMetadataFile); - addParameterReferences(methodItem, classMetadataFile); - addReturnReferences(methodItem, classMetadataFile); - addOverloadReferences(methodItem, classMetadataFile); - }); - } - - void addFieldsInfo(TypeElement classElement, MetadataFile classMetadataFile) { - ElementFilter.fieldsIn(classElement.getEnclosedElements()).stream() - .filter(fieldElement -> !Utils.isPrivateOrPackagePrivate(fieldElement)) - .forEach(fieldElement -> { - MetadataFileItem fieldItem = buildMetadataFileItem(fieldElement); - fieldItem.setContent(classItemsLookup.extractFieldContent(fieldElement)); - fieldItem.setReturn(classItemsLookup.extractReturn(fieldElement)); - String depMsg = classItemsLookup.extractDeprecatedDescription(fieldElement); - if (depMsg != null) { - fieldItem.setSummary(getDeprecatedSummary(depMsg, fieldItem.getSummary())); - fieldItem.setStatus(Status.DEPRECATED.toString()); - } - - classMetadataFile.getItems().add(fieldItem); - addReturnReferences(fieldItem, classMetadataFile); - }); - } - - void addReferencesInfo(TypeElement classElement, MetadataFile classMetadataFile) { - MetadataFileItem classReference = new MetadataFileItem(classLookup.extractUid(classElement)); - classReference.setParent(classLookup.extractParent(classElement)); - populateItemFields(classReference, classLookup, classElement); - classReference.setTypeParameters(classLookup.extractTypeParameters(classElement)); - - addTypeParameterReferences(classReference, classMetadataFile); - addSuperclassAndInterfacesReferences(classElement, classMetadataFile); - addInnerClassesReferences(classElement, classMetadataFile); - } - - MetadataFileItem buildMetadataFileItem(Element element) { - return new MetadataFileItem(LANGS, classItemsLookup.extractUid(element)) {{ - String name = classItemsLookup.extractName(element); - setId(classItemsLookup.extractId(element)); - setParent(classItemsLookup.extractParent(element)); - setName(name); - setNameWithType(classItemsLookup.extractNameWithType(element)); - setFullName(classItemsLookup.extractFullName(element)); - setType(classItemsLookup.extractType(element)); - setJavaType(classItemsLookup.extractJavaType(element)); - setPackageName(classItemsLookup.extractPackageName(element)); - setSummary(classItemsLookup.extractSummary(element)); - }}; - } - - protected String getJavaReferenceHref(String uid) { - if (uid == null || uid.equals("")) { - return JAVA_BASE_URL; - } - // example1 uid: "java.lang.Object.equals(java.lang.Object)" - // example2 uid: "java.lang.Object" - String endURL = uid.replaceAll("", ""); - - Pattern argPattern = Pattern.compile(".*\\(.*\\).*"); - if (argPattern.matcher(endURL).find()) { - // example1 - // argumentSplit: ["java.lang.Object.equals", "java.lang.Object)"] - // nameSplit: ["java", "lang", "Object", "equals"] - List argumentSplit = Arrays.asList(endURL.split("\\(")); - List nameSplit = Arrays.asList(argumentSplit.get(0).split("\\.")); - - // className: "java/lang/Object" - // methodName: "#equals" - // argumentsName: "#java.lang.Object-" - String className = String.join("/", nameSplit.subList(0, nameSplit.size() - 1)); - String methodName = "#" + nameSplit.get(nameSplit.size() - 1); - String argumentsName = argumentSplit.get(1).replaceAll("[,)]", "-"); - - // endURL: "java/lang/Object.html#equals-java.lang.Object-" - endURL = className + ".html" + methodName + "-" + argumentsName; - } else { - // example2 - // endURL = java/lang/Object.html - endURL = endURL.replaceAll("\\.", "/"); - endURL = endURL + ".html"; - } - return JAVA_BASE_URL + endURL; - } - - private void updateExternalReferences(List classMetadataFiles) { - classMetadataFiles.forEach(file -> file.getReferences() - .forEach(ref -> updateExternalReference(ref))); - } - - private void updateExternalReference(MetadataFileItem reference) { - String uid = reference.getUid(); - uid = updateReferenceUid(uid); - - if (isJavaPrimitive(uid)) { - reference.setHref(PRIMITIVE_URL); - return; - } - if (isJavaLibrary(uid)) { - reference.setHref(getJavaReferenceHref(uid)); - } - if (isExternalReference(uid)) { - reference.setIsExternal(true); - } - if (reference.getSpecForJava().size() > 0) { - for (SpecViewModel spec : reference.getSpecForJava()) { - String specUid = spec.getUid(); - if (specUid != null) { - if (isJavaPrimitive(specUid)) { - spec.setHref(PRIMITIVE_URL); - } - if (isJavaLibrary(specUid)) { - spec.setHref(getJavaReferenceHref(specUid)); - } - if (isExternalReference(specUid)) { - spec.setIsExternal(true); - } - } - } - } - } - - private String updateReferenceUid(String uid) { - if (ENDING_PATTERN.matcher(uid).find()) { - uid = uid.replace("", ""); - } - return uid; - } - - private boolean isExternalReference(String uid) { - return (PROTOBUF_PATTERN.matcher(uid).find() || GAX_PATTERN.matcher(uid).find() || APICOMMON_PATTERN.matcher(uid).find() || GAX_PATTERN.matcher(uid).find() || LONGRUNNING_PATTERN.matcher(uid).find()); - } - - private boolean isJavaPrimitive(String uid) { - return (uid.equals("boolean") || uid.equals("int") || uid.equals("byte") || uid.equals("long") || uid.equals("float") || uid.equals("double") || uid.equals("char") || uid.equals("short")); - } - - private boolean isJavaLibrary(String uid) { - return JAVA_PATTERN.matcher(uid).find(); - } - - void addParameterReferences(MetadataFileItem methodItem, MetadataFile classMetadataFile) { - classMetadataFile.getReferences().addAll( - methodItem.getSyntax().getParameters().stream() - .map(parameter -> buildRefItem(parameter.getType())) - .filter(o -> !classMetadataFile.getItems().contains(o)) - .collect(Collectors.toList())); - } - - void addReturnReferences(MetadataFileItem methodItem, MetadataFile classMetadataFile) { - classMetadataFile.getReferences().addAll( - Stream.of(methodItem.getSyntax().getReturnValue()) - .filter(Objects::nonNull) - .map(returnValue -> buildRefItem(returnValue.getReturnType())) - .filter(o -> !classMetadataFile.getItems().contains(o)) - .collect(Collectors.toList())); - } - - void addExceptionReferences(MetadataFileItem methodItem, MetadataFile classMetadataFile) { - classMetadataFile.getReferences().addAll( - methodItem.getExceptions().stream() - .map(exceptionItem -> buildRefItem(exceptionItem.getType())) - .filter(o -> !classMetadataFile.getItems().contains(o)) - .collect(Collectors.toList())); - } - - void addTypeParameterReferences(MetadataFileItem methodItem, MetadataFile classMetadataFile) { - classMetadataFile.getReferences().addAll( - methodItem.getSyntax().getTypeParameters().stream() - .map(typeParameter -> { - String id = typeParameter.getId(); - return new MetadataFileItem(id, id, false); - }).collect(Collectors.toList())); - } - - void addSuperclassAndInterfacesReferences(TypeElement classElement, MetadataFile classMetadataFile) { - classMetadataFile.getReferences().addAll(classLookup.extractReferences(classElement)); - } - - void addInnerClassesReferences(TypeElement classElement, MetadataFile classMetadataFile) { - classMetadataFile.getReferences().addAll( - ElementFilter.typesIn(elementUtil.extractSortedElements(classElement)).stream() - .map(this::buildClassReference) - .collect(Collectors.toList())); - } - - void addOverloadReferences(MetadataFileItem item, MetadataFile classMetadataFile) { - classMetadataFile.getReferences().add(new MetadataFileItem(item.getOverload()) {{ - setName(RegExUtils.removeAll(item.getName(), "\\(.*\\)$")); - setNameWithType(RegExUtils.removeAll(item.getNameWithType(), "\\(.*\\)$")); - setFullName(RegExUtils.removeAll(item.getFullName(), "\\(.*\\)$")); - setPackageName(item.getPackageName()); - }}); - } - - void applyPostProcessing(MetadataFile classMetadataFile) { - expandComplexGenericsInReferences(classMetadataFile); - } - - /** - * Replace one record in 'references' with several records in this way: - *
-     * a.b.c.List> ->
-     *     - a.b.c.List
-     *     - df.mn.ClassOne
-     *     - tr.T
-     * 
- */ - void expandComplexGenericsInReferences(MetadataFile classMetadataFile) { - Set additionalItems = new LinkedHashSet<>(); - Iterator iterator = classMetadataFile.getReferences().iterator(); - while (iterator.hasNext()) { - MetadataFileItem item = iterator.next(); - String uid = item.getUid(); - if (!uid.endsWith("*") && uid.contains("<")) { - List classNames = splitUidWithGenericsIntoClassNames(uid); - additionalItems.addAll(classNames.stream() - .map(s -> new MetadataFileItem(s, classLookup.makeTypeShort(s), false)) - .collect(Collectors.toSet())); - } - } - // Remove items which already exist in 'items' section (compared by 'uid' field) - additionalItems.removeAll(classMetadataFile.getItems()); - - classMetadataFile.getReferences().addAll(additionalItems); - } - - void populateUidValues(List packageMetadataFiles, List classMetadataFiles) { - Lookup lookup = new Lookup(packageMetadataFiles, classMetadataFiles); - - classMetadataFiles.forEach(classMetadataFile -> { - LookupContext lookupContext = lookup.buildContext(classMetadataFile); - - for (MetadataFileItem item : classMetadataFile.getItems()) { - item.setSummary(YamlUtil.cleanupHtml( - populateUidValues(item.getSummary(), lookupContext) - )); - - Optional.ofNullable(item.getSyntax()).ifPresent(syntax -> { - Optional.ofNullable(syntax.getParameters()).ifPresent( - methodParams -> methodParams.forEach( - param -> { - param.setDescription(populateUidValues(param.getDescription(), lookupContext)); - }) - ); - Optional.ofNullable(syntax.getReturnValue()).ifPresent(returnValue -> - returnValue.setReturnDescription( - populateUidValues(syntax.getReturnValue().getReturnDescription(), lookupContext) - ) - ); - } - ); - } - }); - } - - String populateUidValues(String text, LookupContext lookupContext) { - if (StringUtils.isBlank(text)) { - return text; - } - - Matcher linkMatcher = XREF_LINK_PATTERN.matcher(text); - while (linkMatcher.find()) { - String link = linkMatcher.group(); - Matcher linkContentMatcher = XREF_LINK_CONTENT_PATTERN.matcher(link); - if (!linkContentMatcher.find()) { - continue; - } - - String linkContent = linkContentMatcher.group(); - String uid = resolveUidFromLinkContent(linkContent, lookupContext); - String updatedLink = linkContentMatcher.replaceAll(uid); - text = StringUtils.replace(text, link, updatedLink); - } - return text; - } - - /** - * The linkContent could be in following format - * #memeber - * Class#member - * Class#method() - * Class#method(params) - */ - String resolveUidFromLinkContent(String linkContent, LookupContext lookupContext) { - if (StringUtils.isBlank(linkContent)) { - return ""; - } - - linkContent = linkContent.trim(); - - // complete class name for class internal link - if (linkContent.startsWith("#")) { - String firstKey = lookupContext.getOwnerUid(); - linkContent = firstKey + linkContent; - } - - // fuzzy resolve, target for items from project external references - String fuzzyResolvedUid = resolveUidFromReference(linkContent, lookupContext); - - // exact resolve in lookupContext - linkContent = linkContent.replace("#", "."); - String exactResolveUid = resolveUidByLookup(linkContent, lookupContext); - return exactResolveUid.isEmpty() ? fuzzyResolvedUid : exactResolveUid; - } - - List splitUidWithGenericsIntoClassNames(String uid) { - uid = RegExUtils.removeAll(uid, "[>]+$"); - return Arrays.asList(StringUtils.split(uid, "<")); - } - - MetadataFileItem buildRefItem(String uid) { - if (!uid.endsWith("*") && (uid.contains("<") || uid.contains("[]"))) { - return new MetadataFileItem(uid, getJavaSpec(replaceUidAndSplit(uid))); - } else { - List fullNameList = new ArrayList<>(); - - this.environment.getIncludedElements().forEach( - element -> elementUtil.extractSortedElements(element).forEach( - typeElement -> fullNameList.add(classLookup.extractFullName(typeElement))) - ); - - if (fullNameList.contains(uid)) { - return new MetadataFileItem(uid, classLookup.makeTypeShort(uid), false); - } else { - return new MetadataFileItem(uid, getJavaSpec(replaceUidAndSplit(uid))); - } - } - } - - List replaceUidAndSplit(String uid) { - String retValue = RegExUtils.replaceAll(uid, "\\<", "//", "//>//"); - retValue = RegExUtils.replaceAll(retValue, ",", "//,//"); - retValue = RegExUtils.replaceAll(retValue, "\\[\\]", "//[]//"); - - return Arrays.asList(StringUtils.split(retValue, "//")); - } - - List getJavaSpec(List references) { - List specList = new ArrayList<>(); - - Optional.ofNullable(references).ifPresent( - ref -> references.forEach( - uid -> { - if (uid.equalsIgnoreCase("<") - || uid.equalsIgnoreCase(">") - || uid.equalsIgnoreCase(",") - || uid.equalsIgnoreCase("[]")) - specList.add(new SpecViewModel(null, uid)); - else if (uid != "") - specList.add(new SpecViewModel(uid, uid)); - }) - ); - - return specList; - } - - /** - * this method is used to do fuzzy resolve - * "*" will be added at the end of uid for method for xerf service resolve purpose - */ - String resolveUidFromReference(String linkContent, LookupContext lookupContext) { - String uid = ""; - Matcher matcher = XREF_LINK_RESOLVE_PATTERN.matcher(linkContent); - - if (matcher.find()) { - String className = matcher.group("class"); - String memberName = matcher.group("member"); - uid = resolveUidByLookup(className, lookupContext); - if (!uid.isEmpty()) { - uid = uid.concat(".").concat(memberName); - - // linkContent targets a method - if (!StringUtils.isBlank(matcher.group(3))) { - uid = uid.concat("*"); - } - } - } - return uid; - } - - String resolveUidByLookup(String signature, LookupContext lookupContext) { - if (StringUtils.isBlank(signature) || lookupContext == null) { - return ""; - } - return lookupContext.containsKey(signature) ? lookupContext.resolve(signature) : ""; - } } diff --git a/third_party/docfx-doclet-143274/src/test/java/com/microsoft/build/BuilderUtilTest.java b/third_party/docfx-doclet-143274/src/test/java/com/microsoft/build/BuilderUtilTest.java new file mode 100644 index 00000000..03bdda31 --- /dev/null +++ b/third_party/docfx-doclet-143274/src/test/java/com/microsoft/build/BuilderUtilTest.java @@ -0,0 +1,113 @@ +/* + * Copyright 2021 Google LLC + * + * 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 + * + * https://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.microsoft.build; + +import com.microsoft.model.MetadataFile; +import com.microsoft.model.MetadataFileItem; +import com.microsoft.model.MethodParameter; +import com.microsoft.model.Syntax; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class BuilderUtilTest { + @Test + public void populateUidValues() { + MetadataFile classMetadataFile = new MetadataFile("output", "name"); + + MetadataFileItem ownerClassItem = buildMetadataFileItem("a.b.OwnerClass", "Not important summary value"); + ownerClassItem.setNameWithType("OwnerClass"); + MetadataFileItem item1 = buildMetadataFileItem("UID unknown class", "UnknownClass"); + populateSyntax(item1, "SomeClass#someMethod(String param)"); + MetadataFileItem item2 = buildMetadataFileItem("UID known class", "SomeClass#someMethod(String param)"); + MetadataFileItem item3 = buildMetadataFileItem("UID method only", "#someMethod2(String p1, String p2)"); + classMetadataFile.getItems().addAll(Arrays.asList(ownerClassItem, item1, item2, item3)); + + MetadataFileItem reference1 = new MetadataFileItem("a.b.SomeClass.someMethod(String param)"); + reference1.setNameWithType("SomeClass.someMethod(String param)"); + MetadataFileItem reference2 = new MetadataFileItem("a.b.OwnerClass.someMethod2(String p1, String p2)"); + reference2.setNameWithType("OwnerClass.someMethod2(String p1, String p2)"); + classMetadataFile.getReferences().addAll(Arrays.asList(reference1, reference2)); + + BuilderUtil.populateUidValues(Collections.emptyList(), Arrays.asList(classMetadataFile)); + + assertEquals("Wrong summary for unknown class", item1.getSummary(), + "Bla bla UnknownClass bla"); + assertEquals("Wrong syntax description", item1.getSyntax().getParameters().get(0).getDescription(), + "One two SomeClass#someMethod(String param) three"); + assertEquals("Wrong summary for known class", item2.getSummary(), + "Bla bla SomeClass#someMethod(String param) bla"); + assertEquals("Wrong summary for method", item3.getSummary(), + "Bla bla #someMethod2(String p1, String p2) bla"); + + } + + private MetadataFileItem buildMetadataFileItem(String uid, String value) { + MetadataFileItem item = new MetadataFileItem(uid); + item.setSummary( + String.format("Bla bla %s bla", value, value)); + return item; + } + + private void populateSyntax(MetadataFileItem item, String value) { + Syntax syntax = new Syntax(); + String methodParamDescription = String + .format("One two %s three", value, value); + syntax.setParameters( + Arrays.asList(new MethodParameter("method param id", "method param type", methodParamDescription))); + item.setSyntax(syntax); + } + + @Test + public void determineUidByLinkContent() { + Map lookup = new HashMap<>() {{ + put("SomeClass", "a.b.c.SomeClass"); + put("SomeClass.someMethod()", "a.b.c.SomeClass.someMethod()"); + put("SomeClass.someMethod(String param)", "a.b.c.SomeClass.someMethod(String param)"); + }}; + + LookupContext lookupContext = new LookupContext(lookup, lookup); + assertEquals("Wrong result for class", BuilderUtil. + resolveUidByLookup("SomeClass", lookupContext), "a.b.c.SomeClass"); + assertEquals("Wrong result for method", BuilderUtil. + resolveUidFromLinkContent("SomeClass#someMethod()", lookupContext), "a.b.c.SomeClass.someMethod()"); + assertEquals("Wrong result for method with param", BuilderUtil. + resolveUidFromLinkContent("SomeClass#someMethod(String param)", lookupContext), + "a.b.c.SomeClass.someMethod(String param)"); + + assertEquals("Wrong result for unknown class", BuilderUtil. + resolveUidByLookup("UnknownClass", lookupContext), ""); + assertEquals("Wrong result for null", BuilderUtil.resolveUidByLookup(null, lookupContext), ""); + assertEquals("Wrong result for whitespace", BuilderUtil.resolveUidByLookup(" ", lookupContext), ""); + } + + @Test + public void splitUidWithGenericsIntoClassNames() { + List result = BuilderUtil.splitUidWithGenericsIntoClassNames("a.b.c.List>"); + + assertEquals("Wrong result list size", result.size(), 3); + assertTrue("Wrong result list content", result.contains("a.b.c.List")); + assertTrue("Wrong result list content", result.contains("df.mn.ClassOne")); + assertTrue("Wrong result list content", result.contains("tr.T")); + } +} diff --git a/third_party/docfx-doclet-143274/src/test/java/com/microsoft/build/ClassBuilderTest.java b/third_party/docfx-doclet-143274/src/test/java/com/microsoft/build/ClassBuilderTest.java new file mode 100644 index 00000000..1a9d1ef0 --- /dev/null +++ b/third_party/docfx-doclet-143274/src/test/java/com/microsoft/build/ClassBuilderTest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2021 Google LLC + * + * 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 + * + * https://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.microsoft.build; + +import com.google.testing.compile.CompilationRule; +import com.microsoft.lookup.ClassItemsLookup; +import com.microsoft.lookup.ClassLookup; +import com.microsoft.model.MetadataFile; +import com.microsoft.model.MetadataFileItem; +import com.microsoft.util.ElementUtil; +import com.sun.source.util.DocTrees; +import jdk.javadoc.doclet.DocletEnvironment; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Mockito; + +import javax.lang.model.element.TypeElement; +import javax.lang.model.util.Elements; +import java.io.File; +import java.util.Collection; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +public class ClassBuilderTest { + @Rule + public CompilationRule rule = new CompilationRule(); + private Elements elements; + private ClassBuilder classBuilder; + private DocletEnvironment environment; + private DocTrees docTrees; + + @Before + public void setup() { + elements = rule.getElements(); + environment = Mockito.mock(DocletEnvironment.class); + docTrees = Mockito.mock(DocTrees.class); + ElementUtil elementUtil = new ElementUtil(new String[0], new String[0]); + ClassLookup classLookup = new ClassLookup(environment); + classBuilder = new ClassBuilder( + elementUtil, + classLookup, + new ClassItemsLookup(environment), + "./target", + new ReferenceBuilder(environment, classLookup, elementUtil)); + } + @Test + public void addConstructorsInfoWhenOnlyDefaultConstructor() { + TypeElement element = elements.getTypeElement("com.microsoft.samples.subpackage.Person"); + MetadataFile container = new MetadataFile("output", "name"); + when(environment.getElementUtils()).thenReturn(elements); + when(environment.getDocTrees()).thenReturn(docTrees); + + classBuilder.addConstructorsInfo(element, container); + + assertEquals("Wrong file name", container.getFileNameWithPath(), "output" + File.separator + "name"); + assertEquals("Container should contain constructor item", container.getItems().size(), 1); + } + + @Test + public void addConstructorsInfo() { + TypeElement element = elements.getTypeElement("com.microsoft.samples.SuperHero"); + MetadataFile container = new MetadataFile("output", "name"); + when(environment.getElementUtils()).thenReturn(elements); + when(environment.getDocTrees()).thenReturn(docTrees); + + classBuilder.addConstructorsInfo(element, container); + + assertEquals("Wrong file name", container.getFileNameWithPath(), "output" + File.separator + "name"); + Collection constructorItems = container.getItems(); + assertEquals("Container should contain 2 constructor items", constructorItems.size(), 2); + } +} diff --git a/third_party/docfx-doclet-143274/src/test/java/com/microsoft/build/ReferenceBuilderTest.java b/third_party/docfx-doclet-143274/src/test/java/com/microsoft/build/ReferenceBuilderTest.java new file mode 100644 index 00000000..4afc21d2 --- /dev/null +++ b/third_party/docfx-doclet-143274/src/test/java/com/microsoft/build/ReferenceBuilderTest.java @@ -0,0 +1,113 @@ +/* + * Copyright 2021 Google LLC + * + * 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 + * + * https://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.microsoft.build; + +import com.microsoft.lookup.ClassLookup; +import com.microsoft.model.MetadataFile; +import com.microsoft.model.MetadataFileItem; +import com.microsoft.util.ElementUtil; +import jdk.javadoc.doclet.DocletEnvironment; +import org.apache.commons.lang3.RegExUtils; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class ReferenceBuilderTest { + + private ReferenceBuilder referenceBuilder; + + @Before + public void setup() { + DocletEnvironment environment = Mockito.mock(DocletEnvironment.class); + ElementUtil elementUtil = new ElementUtil(new String[0], new String[0]); + ClassLookup classLookup = new ClassLookup(environment); + referenceBuilder = new ReferenceBuilder(environment, classLookup, elementUtil); + } + + @Test + public void expandComplexGenericsInReferences() { + MetadataFile classMetadataFile = new MetadataFile("path", "name"); + MetadataFileItem referenceItem = new MetadataFileItem("a.b.c.List>"); + Set references = classMetadataFile.getReferences(); + references.add(referenceItem); + + referenceBuilder.expandComplexGenericsInReferences(classMetadataFile); + + assertEquals("Wrong references amount", references.size(), 4); + + List content = references.stream().map(MetadataFileItem::getUid).collect(Collectors.toList()); + assertTrue("Wrong references content", content.contains("a.b.c.List")); + assertTrue("Wrong references content", content.contains("df.mn.ClassOne")); + assertTrue("Wrong references content", content.contains("tr.T")); + assertTrue("Wrong references content", content.contains("a.b.c.List>")); + } + + //todo add test case to cover reference item with in package + @Test + public void buildRefItem() { + buildRefItemAndCheckAssertions("java.lang.Some.String", "java.lang.Some.String", "String"); + buildRefItemAndCheckAssertions("java.lang.Some.String[]", "java.lang.Some.String[]", "String"); + } + + private void buildRefItemAndCheckAssertions(String initialValue, String expectedUid, String expectedName) { + MetadataFileItem result = referenceBuilder.buildRefItem(initialValue); + + assertEquals("Wrong uid", result.getUid(), expectedUid); + assertEquals("Wrong name", result.getSpecForJava().iterator().next().getUid(), RegExUtils.removeAll(expectedUid, "\\[\\]$")); + assertEquals("Wrong name", result.getSpecForJava().iterator().next().getName(), expectedName); + assertEquals("Wrong fullName", result.getSpecForJava().iterator().next().getFullName(), RegExUtils.removeAll(expectedUid, "\\[\\]$")); + } + + @Test + public void getJavaReferenceHref() { + String result1 = referenceBuilder.getJavaReferenceHref("java.lang.Object"); + String result2 = referenceBuilder.getJavaReferenceHref("java.lang.Object.equals(java.lang.Object)"); + String result3 = referenceBuilder.getJavaReferenceHref("java.lang.Object.notify()"); + String result4 = referenceBuilder.getJavaReferenceHref("java.util.List"); + String result5 = referenceBuilder.getJavaReferenceHref("java.lang.Object.wait(long,int)"); + String result6 = referenceBuilder.getJavaReferenceHref("java.lang.Object.getClass()"); + String result7 = referenceBuilder.getJavaReferenceHref("java.io.IOException"); + String result8 = referenceBuilder.getJavaReferenceHref("java.io.InputStream"); + String result9 = referenceBuilder.getJavaReferenceHref("java.lang.Enum.hashCode()"); + String result10 = referenceBuilder.getJavaReferenceHref("java.nio.ByteBuffer"); + String result11 = referenceBuilder.getJavaReferenceHref("java.lang.Enum.valueOf(java.lang.Class,java.lang.String)"); + String result12 = referenceBuilder.getJavaReferenceHref(""); + String result13 = referenceBuilder.getJavaReferenceHref(null); + + String baseURL = "https://docs.oracle.com/javase/8/docs/api/"; + + assertEquals(baseURL + "java/lang/Object.html", result1); + assertEquals(baseURL + "java/lang/Object.html#equals-java.lang.Object-", result2); + assertEquals(baseURL + "java/lang/Object.html#notify--", result3); + assertEquals(baseURL + "java/util/List.html", result4); + assertEquals(baseURL + "java/lang/Object.html#wait-long-int-", result5); + assertEquals(baseURL + "java/lang/Object.html#getClass--", result6); + assertEquals(baseURL + "java/io/IOException.html", result7); + assertEquals(baseURL + "java/io/InputStream.html", result8); + assertEquals(baseURL + "java/lang/Enum.html#hashCode--", result9); + assertEquals(baseURL + "java/nio/ByteBuffer.html", result10); + assertEquals(baseURL + "java/lang/Enum.html#valueOf-java.lang.Class-java.lang.String-", result11); + assertEquals(baseURL, result12); + assertEquals(baseURL, result13); + } +} diff --git a/third_party/docfx-doclet-143274/src/test/java/com/microsoft/build/YmlFilesBuilderTest.java b/third_party/docfx-doclet-143274/src/test/java/com/microsoft/build/YmlFilesBuilderTest.java index bd0aa3a3..c6d92d40 100644 --- a/third_party/docfx-doclet-143274/src/test/java/com/microsoft/build/YmlFilesBuilderTest.java +++ b/third_party/docfx-doclet-143274/src/test/java/com/microsoft/build/YmlFilesBuilderTest.java @@ -1,221 +1,31 @@ package com.microsoft.build; -import com.google.testing.compile.CompilationRule; -import com.microsoft.model.*; -import com.sun.source.util.DocTrees; +import com.microsoft.model.TocItem; +import com.microsoft.model.TocTypeMap; import jdk.javadoc.doclet.DocletEnvironment; -import org.apache.commons.lang3.RegExUtils; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import javax.lang.model.element.ElementKind; -import javax.lang.model.element.TypeElement; -import javax.lang.model.util.Elements; -import java.io.File; -import java.util.*; -import java.util.stream.Collectors; +import java.util.List; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class YmlFilesBuilderTest { - @Rule - public CompilationRule rule = new CompilationRule(); - private Elements elements; private YmlFilesBuilder ymlFilesBuilder; private DocletEnvironment environment; - private DocTrees docTrees; @Before public void setup() { - elements = rule.getElements(); environment = Mockito.mock(DocletEnvironment.class); - docTrees = Mockito.mock(DocTrees.class); ymlFilesBuilder = new YmlFilesBuilder(environment, "./target", new String[]{}, new String[]{}, "google-cloud-product"); } - @Test - public void addConstructorsInfoWhenOnlyDefaultConstructor() { - TypeElement element = elements.getTypeElement("com.microsoft.samples.subpackage.Person"); - MetadataFile container = new MetadataFile("output", "name"); - when(environment.getElementUtils()).thenReturn(elements); - when(environment.getDocTrees()).thenReturn(docTrees); - - ymlFilesBuilder.addConstructorsInfo(element, container); - - assertEquals("Wrong file name", container.getFileNameWithPath(), "output" + File.separator + "name"); - assertEquals("Container should contain constructor item", container.getItems().size(), 1); - } - - @Test - public void addConstructorsInfo() { - TypeElement element = elements.getTypeElement("com.microsoft.samples.SuperHero"); - MetadataFile container = new MetadataFile("output", "name"); - when(environment.getElementUtils()).thenReturn(elements); - when(environment.getDocTrees()).thenReturn(docTrees); - - ymlFilesBuilder.addConstructorsInfo(element, container); - - assertEquals("Wrong file name", container.getFileNameWithPath(), "output" + File.separator + "name"); - Collection constructorItems = container.getItems(); - assertEquals("Container should contain 2 constructor items", constructorItems.size(), 2); - } - - //todo add test case to cover reference item with in package - @Test - public void buildRefItem() { - buildRefItemAndCheckAssertions("java.lang.Some.String", "java.lang.Some.String", "String"); - buildRefItemAndCheckAssertions("java.lang.Some.String[]", "java.lang.Some.String[]", "String"); - } - - private void buildRefItemAndCheckAssertions(String initialValue, String expectedUid, String expectedName) { - MetadataFileItem result = ymlFilesBuilder.buildRefItem(initialValue); - - assertEquals("Wrong uid", result.getUid(), expectedUid); - assertEquals("Wrong name", result.getSpecForJava().iterator().next().getUid(), RegExUtils.removeAll(expectedUid, "\\[\\]$")); - assertEquals("Wrong name", result.getSpecForJava().iterator().next().getName(), expectedName); - assertEquals("Wrong fullName", result.getSpecForJava().iterator().next().getFullName(), RegExUtils.removeAll(expectedUid, "\\[\\]$")); - } - - @Test - public void populateUidValues() { - MetadataFile classMetadataFile = new MetadataFile("output", "name"); - - MetadataFileItem ownerClassItem = buildMetadataFileItem("a.b.OwnerClass", "Not important summary value"); - ownerClassItem.setNameWithType("OwnerClass"); - MetadataFileItem item1 = buildMetadataFileItem("UID unknown class", "UnknownClass"); - populateSyntax(item1, "SomeClass#someMethod(String param)"); - MetadataFileItem item2 = buildMetadataFileItem("UID known class", "SomeClass#someMethod(String param)"); - MetadataFileItem item3 = buildMetadataFileItem("UID method only", "#someMethod2(String p1, String p2)"); - classMetadataFile.getItems().addAll(Arrays.asList(ownerClassItem, item1, item2, item3)); - - MetadataFileItem reference1 = new MetadataFileItem("a.b.SomeClass.someMethod(String param)"); - reference1.setNameWithType("SomeClass.someMethod(String param)"); - MetadataFileItem reference2 = new MetadataFileItem("a.b.OwnerClass.someMethod2(String p1, String p2)"); - reference2.setNameWithType("OwnerClass.someMethod2(String p1, String p2)"); - classMetadataFile.getReferences().addAll(Arrays.asList(reference1, reference2)); - - ymlFilesBuilder.populateUidValues(Collections.emptyList(), Arrays.asList(classMetadataFile)); - - assertEquals("Wrong summary for unknown class", item1.getSummary(), - "Bla bla UnknownClass bla"); - assertEquals("Wrong syntax description", item1.getSyntax().getParameters().get(0).getDescription(), - "One two SomeClass#someMethod(String param) three"); - assertEquals("Wrong summary for known class", item2.getSummary(), - "Bla bla SomeClass#someMethod(String param) bla"); - assertEquals("Wrong summary for method", item3.getSummary(), - "Bla bla #someMethod2(String p1, String p2) bla"); - - } - - private MetadataFileItem buildMetadataFileItem(String uid, String value) { - MetadataFileItem item = new MetadataFileItem(uid); - item.setSummary( - String.format("Bla bla %s bla", value, value)); - return item; - } - - private void populateSyntax(MetadataFileItem item, String value) { - Syntax syntax = new Syntax(); - String methodParamDescription = String - .format("One two %s three", value, value); - syntax.setParameters( - Arrays.asList(new MethodParameter("method param id", "method param type", methodParamDescription))); - item.setSyntax(syntax); - } - - @Test - public void determineUidByLinkContent() { - Map lookup = new HashMap<>() {{ - put("SomeClass", "a.b.c.SomeClass"); - put("SomeClass.someMethod()", "a.b.c.SomeClass.someMethod()"); - put("SomeClass.someMethod(String param)", "a.b.c.SomeClass.someMethod(String param)"); - }}; - - LookupContext lookupContext = new LookupContext(lookup, lookup); - assertEquals("Wrong result for class", ymlFilesBuilder. - resolveUidByLookup("SomeClass", lookupContext), "a.b.c.SomeClass"); - assertEquals("Wrong result for method", ymlFilesBuilder. - resolveUidFromLinkContent("SomeClass#someMethod()", lookupContext), "a.b.c.SomeClass.someMethod()"); - assertEquals("Wrong result for method with param", ymlFilesBuilder. - resolveUidFromLinkContent("SomeClass#someMethod(String param)", lookupContext), - "a.b.c.SomeClass.someMethod(String param)"); - - assertEquals("Wrong result for unknown class", ymlFilesBuilder. - resolveUidByLookup("UnknownClass", lookupContext), ""); - assertEquals("Wrong result for null", ymlFilesBuilder.resolveUidByLookup(null, lookupContext), ""); - assertEquals("Wrong result for whitespace", ymlFilesBuilder.resolveUidByLookup(" ", lookupContext), ""); - } - - @Test - public void splitUidWithGenericsIntoClassNames() { - List result = ymlFilesBuilder.splitUidWithGenericsIntoClassNames("a.b.c.List>"); - - assertEquals("Wrong result list size", result.size(), 3); - assertTrue("Wrong result list content", result.contains("a.b.c.List")); - assertTrue("Wrong result list content", result.contains("df.mn.ClassOne")); - assertTrue("Wrong result list content", result.contains("tr.T")); - } - - @Test - public void expandComplexGenericsInReferences() { - MetadataFile classMetadataFile = new MetadataFile("path", "name"); - MetadataFileItem referenceItem = new MetadataFileItem("a.b.c.List>"); - Set references = classMetadataFile.getReferences(); - references.add(referenceItem); - - ymlFilesBuilder.expandComplexGenericsInReferences(classMetadataFile); - - assertEquals("Wrong references amount", references.size(), 4); - - List content = references.stream().map(MetadataFileItem::getUid).collect(Collectors.toList()); - assertTrue("Wrong references content", content.contains("a.b.c.List")); - assertTrue("Wrong references content", content.contains("df.mn.ClassOne")); - assertTrue("Wrong references content", content.contains("tr.T")); - assertTrue("Wrong references content", content.contains("a.b.c.List>")); - } - - - @Test - public void getJavaReferenceHref(){ - String result1 = ymlFilesBuilder.getJavaReferenceHref("java.lang.Object"); - String result2 = ymlFilesBuilder.getJavaReferenceHref("java.lang.Object.equals(java.lang.Object)"); - String result3 = ymlFilesBuilder.getJavaReferenceHref("java.lang.Object.notify()"); - String result4 = ymlFilesBuilder.getJavaReferenceHref("java.util.List"); - String result5 = ymlFilesBuilder.getJavaReferenceHref("java.lang.Object.wait(long,int)"); - String result6 = ymlFilesBuilder.getJavaReferenceHref("java.lang.Object.getClass()"); - String result7 = ymlFilesBuilder.getJavaReferenceHref("java.io.IOException"); - String result8 = ymlFilesBuilder.getJavaReferenceHref("java.io.InputStream"); - String result9 = ymlFilesBuilder.getJavaReferenceHref("java.lang.Enum.hashCode()"); - String result10 = ymlFilesBuilder.getJavaReferenceHref("java.nio.ByteBuffer"); - String result11 = ymlFilesBuilder.getJavaReferenceHref("java.lang.Enum.valueOf(java.lang.Class,java.lang.String)"); - String result12 = ymlFilesBuilder.getJavaReferenceHref(""); - String result13 = ymlFilesBuilder.getJavaReferenceHref(null); - - String baseURL = "https://docs.oracle.com/javase/8/docs/api/"; - - assertEquals(baseURL + "java/lang/Object.html", result1); - assertEquals(baseURL + "java/lang/Object.html#equals-java.lang.Object-", result2); - assertEquals(baseURL + "java/lang/Object.html#notify--", result3); - assertEquals(baseURL + "java/util/List.html", result4); - assertEquals(baseURL + "java/lang/Object.html#wait-long-int-", result5); - assertEquals(baseURL + "java/lang/Object.html#getClass--", result6); - assertEquals(baseURL + "java/io/IOException.html", result7); - assertEquals(baseURL + "java/io/InputStream.html", result8); - assertEquals(baseURL + "java/lang/Enum.html#hashCode--", result9); - assertEquals(baseURL + "java/nio/ByteBuffer.html", result10); - assertEquals(baseURL + "java/lang/Enum.html#valueOf-java.lang.Class-java.lang.String-", result11); - assertEquals(baseURL, result12); - assertEquals(baseURL, result13); - } - @Test public void joinTocTypeItems(){ TocTypeMap typeMap = new TocTypeMap(); @@ -248,5 +58,4 @@ public void joinTocTypeItems(){ assertEquals("Exceptions", tocItems.get(8).getHeading()); assertEquals(exceptionToc, tocItems.get(9)); } - } From d82768b026c502af89006ec713bf4eb97409a4c3 Mon Sep 17 00:00:00 2001 From: Emily Ball Date: Wed, 22 Dec 2021 16:30:37 -0800 Subject: [PATCH 2/4] feat: include support for @see tags chore: cleanup @deprecated support --- .../java/com/microsoft/build/BuilderUtil.java | 9 +- .../com/microsoft/build/ClassBuilder.java | 26 +----- .../com/microsoft/build/YmlFilesBuilder.java | 2 +- .../java/com/microsoft/lookup/BaseLookup.java | 87 +++++++++++++++++-- .../microsoft/lookup/ClassItemsLookup.java | 25 +++--- .../com/microsoft/lookup/ClassLookup.java | 33 ++----- .../com/microsoft/lookup/PackageLookup.java | 10 +-- .../lookup/ClassItemsLookupTest.java | 24 ----- .../com/microsoft/lookup/ClassLookupTest.java | 39 --------- .../microsoft/lookup/PackageLookupTest.java | 4 +- .../com.microsoft.samples.SuperHero.yml | 2 +- ...s.AgreementDetailsCollectionOperations.yml | 4 +- ...agreements.IAgreementDetailsCollection.yml | 2 +- ...oogle.RecognitionAudio.AudioSourceCase.yml | 2 +- .../com.microsoft.samples.google.v1beta.yml | 1 + ...com.microsoft.samples.google.v1p1alpha.yml | 1 + ...om.microsoft.samples.subpackage.Person.yml | 2 +- 17 files changed, 118 insertions(+), 155 deletions(-) diff --git a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/BuilderUtil.java b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/BuilderUtil.java index f5bef0f6..46214575 100644 --- a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/BuilderUtil.java +++ b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/BuilderUtil.java @@ -37,14 +37,6 @@ final class BuilderUtil { private static final Pattern XREF_LINK_RESOLVE_PATTERN = Pattern.compile("(?\\w+)\\#(?\\w+)(\\((?.*)\\))?"); public final static String[] LANGS = {"java"}; - static String getDeprecatedSummary(String depMsg, String summary) { - String result = "

(deprecated) " + depMsg + "

"; - if (summary != null && !summary.equals("")) { - result = result + "\n" + summary; - } - return result; - } - static String populateUidValues(String text, LookupContext lookupContext) { if (StringUtils.isBlank(text)) { return text; @@ -196,6 +188,7 @@ static void populateItemFields(MetadataFileItem item, BaseLo item.setType(lookup.extractType(element)); item.setJavaType(lookup.extractJavaType(element)); item.setSummary(lookup.extractSummary(element)); + item.setStatus(lookup.extractStatus(element)); item.setContent(lookup.extractContent(element)); } } diff --git a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/ClassBuilder.java b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/ClassBuilder.java index 1ac99543..e3a0f345 100644 --- a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/ClassBuilder.java +++ b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/ClassBuilder.java @@ -19,7 +19,6 @@ import com.microsoft.lookup.ClassLookup; import com.microsoft.model.MetadataFile; import com.microsoft.model.MetadataFileItem; -import com.microsoft.model.Status; import com.microsoft.model.TocItem; import com.microsoft.model.TocTypeMap; import com.microsoft.util.ElementUtil; @@ -35,7 +34,6 @@ import java.util.stream.Collectors; import static com.microsoft.build.BuilderUtil.LANGS; -import static com.microsoft.build.BuilderUtil.getDeprecatedSummary; import static com.microsoft.build.BuilderUtil.populateItemFields; class ClassBuilder { @@ -97,11 +95,8 @@ private void addClassInfo(TypeElement classElement, MetadataFile classMetadataFi classItem.setInheritance(classLookup.extractSuperclass(classElement)); classItem.setInterfaces(classLookup.extractInterfaces(classElement)); classItem.setInheritedMethods(classLookup.extractInheritedMethods(classElement)); - String depMsg = classLookup.extractDeprecatedDescription(classElement); - if (depMsg != null) { - classItem.setSummary(getDeprecatedSummary(depMsg, classItem.getSummary())); - classItem.setStatus(Status.DEPRECATED.toString()); - } + classItem.setSummary(classLookup.extractSummary(classElement)); + classItem.setStatus(classLookup.extractStatus(classElement)); classMetadataFile.getItems().add(classItem); } @@ -111,11 +106,6 @@ void addConstructorsInfo(TypeElement classElement, MetadataFile classMetadataFil constructorItem.setOverload(classItemsLookup.extractOverload(constructorElement)); constructorItem.setContent(classItemsLookup.extractConstructorContent(constructorElement)); constructorItem.setParameters(classItemsLookup.extractParameters(constructorElement)); - String depMsg = classItemsLookup.extractDeprecatedDescription(constructorElement); - if (depMsg != null) { - constructorItem.setSummary(getDeprecatedSummary(depMsg, constructorItem.getSummary())); - constructorItem.setStatus(Status.DEPRECATED.toString()); - } classMetadataFile.getItems().add(constructorItem); referenceBuilder.addParameterReferences(constructorItem, classMetadataFile); @@ -134,11 +124,6 @@ private void addMethodsInfo(TypeElement classElement, MetadataFile classMetadata methodItem.setParameters(classItemsLookup.extractParameters(methodElement)); methodItem.setReturn(classItemsLookup.extractReturn(methodElement)); methodItem.setOverridden(classItemsLookup.extractOverridden(methodElement)); - String depMsg = classItemsLookup.extractDeprecatedDescription(methodElement); - if (depMsg != null) { - methodItem.setSummary(getDeprecatedSummary(depMsg, methodItem.getSummary())); - methodItem.setStatus(Status.DEPRECATED.toString()); - } classMetadataFile.getItems().add(methodItem); referenceBuilder.addExceptionReferences(methodItem, classMetadataFile); @@ -155,12 +140,6 @@ private void addFieldsInfo(TypeElement classElement, MetadataFile classMetadataF MetadataFileItem fieldItem = buildMetadataFileItem(fieldElement); fieldItem.setContent(classItemsLookup.extractFieldContent(fieldElement)); fieldItem.setReturn(classItemsLookup.extractReturn(fieldElement)); - String depMsg = classItemsLookup.extractDeprecatedDescription(fieldElement); - if (depMsg != null) { - fieldItem.setSummary(getDeprecatedSummary(depMsg, fieldItem.getSummary())); - fieldItem.setStatus(Status.DEPRECATED.toString()); - } - classMetadataFile.getItems().add(fieldItem); referenceBuilder.addReturnReferences(fieldItem, classMetadataFile); }); @@ -182,6 +161,7 @@ private MetadataFileItem buildMetadataFileItem(Element element) { setJavaType(classItemsLookup.extractJavaType(element)); setPackageName(classItemsLookup.extractPackageName(element)); setSummary(classItemsLookup.extractSummary(element)); + setStatus(classItemsLookup.extractStatus(element)); }}; } diff --git a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/YmlFilesBuilder.java b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/YmlFilesBuilder.java index 1dfa0a71..94cd8abe 100644 --- a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/YmlFilesBuilder.java +++ b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/build/YmlFilesBuilder.java @@ -59,7 +59,7 @@ public boolean build() { for (PackageElement packageElement : elementUtil.extractPackageElements(environment.getIncludedElements())) { String packageUid = packageLookup.extractUid(packageElement); - String packageStatus = packageLookup.extractStatus(packageElement.getQualifiedName().toString()); + String packageStatus = packageLookup.extractStatus(packageElement); TocItem packageTocItem = new TocItem(packageUid, packageUid, packageStatus); // build package summary packageMetadataFiles.add(packageBuilder.buildPackageMetadataFile(packageElement)); diff --git a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/BaseLookup.java b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/BaseLookup.java index c386302c..c702aaaf 100644 --- a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/BaseLookup.java +++ b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/BaseLookup.java @@ -1,21 +1,31 @@ package com.microsoft.lookup; import com.microsoft.lookup.model.ExtendedMetadataFileItem; -import com.microsoft.model.*; +import com.microsoft.model.ExceptionItem; +import com.microsoft.model.MetadataFileItem; +import com.microsoft.model.MethodParameter; +import com.microsoft.model.Return; +import com.microsoft.model.TypeParameter; import com.microsoft.util.YamlUtil; +import com.sun.source.doctree.DeprecatedTree; import com.sun.source.doctree.DocCommentTree; import com.sun.source.doctree.DocTree; import com.sun.source.doctree.LinkTree; import com.sun.source.doctree.LiteralTree; +import com.sun.source.doctree.SeeTree; import jdk.javadoc.doclet.DocletEnvironment; import org.apache.commons.lang3.RegExUtils; import org.apache.commons.lang3.StringUtils; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -157,6 +167,20 @@ public String extractOverridden(T key) { return resolve(key).getOverridden(); } + public String extractStatus(T element) { + Optional docCommentTree = getDocCommentTree(element); + if (docCommentTree.isPresent()) { + boolean isDeprecated = docCommentTree.get().getBlockTags().stream() + .filter(docTree -> docTree.getKind().equals(DocTree.Kind.DEPRECATED)) + .findFirst() + .isPresent(); + if (isDeprecated){ + return DocTree.Kind.DEPRECATED.name().toLowerCase(); + } + } + return null; + } + protected String determineType(T element) { return elementKindLookup.get(element.getKind()); } @@ -166,10 +190,38 @@ protected String determinePackageName(T element) { } protected String determineComment(T element) { - return getDocCommentTree(element) - .map(DocCommentTree::getFullBody) - .map(this::replaceLinksAndCodes) - .orElse(null); + Optional docCommentTree = getDocCommentTree(element); + if (docCommentTree.isPresent()) { + String comment = docCommentTree + .map(DocCommentTree::getFullBody) + .map(this::replaceLinksAndCodes) + .orElse(null); + return replaceBlockTags(docCommentTree.get(), comment); + } + return null; + } + + /** + * Provides support for @deprecated and @see tags + */ + String replaceBlockTags(DocCommentTree docCommentTree, String comment) { + List seeItems = new ArrayList<>(); + String commentWithBlockTags = comment; + for (DocTree blockTag : docCommentTree.getBlockTags()) { + switch (blockTag.getKind()) { + case DEPRECATED: + commentWithBlockTags = getDeprecatedSummary((DeprecatedTree) blockTag).concat(comment); + break; + case SEE: + seeItems.add(getSeeTagRef((SeeTree) blockTag)); + break; + default: + } + } + if (!seeItems.isEmpty()) { + commentWithBlockTags = commentWithBlockTags.concat(getSeeAlsoSummary(seeItems)); + } + return commentWithBlockTags; } /** @@ -231,4 +283,23 @@ public String makeTypeShort(String value) { .map(s -> RegExUtils.removeAll(s, "\\b[a-z0-9_.]+\\.")) .collect(Collectors.joining("<")); } + + private String getSeeAlsoSummary(List seeItems) { + return String.format("\nSee Also: %s\n", String.join(", ", seeItems)); + } + + private String getDeprecatedSummary(DeprecatedTree deprecatedTree) { + return String.format("\nDeprecated. %s\n\n", + replaceLinksAndCodes(deprecatedTree.getBody())); + } + + private String getSeeTagRef(SeeTree seeTree) { + String ref = seeTree.getReference().stream() + .map(r -> String.valueOf(r)).collect(Collectors.joining("")); + // if it's already a tag, use that otherwise build xref tag + if (ref.matches("^<.+>.*")) { + return ref; + } + return String.format("%1$s", ref); + } } diff --git a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/ClassItemsLookup.java b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/ClassItemsLookup.java index 009b67dd..1e60bd45 100644 --- a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/ClassItemsLookup.java +++ b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/ClassItemsLookup.java @@ -14,6 +14,7 @@ import javax.lang.model.type.TypeKind; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; public class ClassItemsLookup extends BaseLookup { @@ -63,7 +64,7 @@ protected ExtendedMetadataFileItem buildMetadataFileItem(Element element) { result.setReturn(extractReturn(exeElement)); if (exeElement.getKind() == ElementKind.METHOD) { result.setOverridden(extractOverriddenUid(utils.overriddenMethod(exeElement))); - result.setSummary(getInheritedInlineCommentString(exeElement)); + result.setSummary(determineComment(exeElement)); } } result.setNameWithType(String.format("%s.%s", classSNameWithGenericsSupport, result.getName())); @@ -79,15 +80,6 @@ protected ExtendedMetadataFileItem buildMetadataFileItem(Element element) { return result; } - public String extractDeprecatedDescription(Element element) { - return getDocCommentTree(element).map(docTree -> docTree.getBlockTags().stream() - .filter(o -> o.getKind() == DocTree.Kind.DEPRECATED) - .map(o -> (DeprecatedTree) o) - .map(o -> replaceLinksAndCodes(o.getBody())) - .findFirst().orElse(null) - ).orElse(null); - } - List extractParameters(ExecutableElement element) { return element.getParameters().stream().map(o -> { String paramName = String.valueOf(o.getSimpleName()); @@ -156,19 +148,28 @@ String extractOverriddenUid(ExecutableElement ovr) { return ""; } + private String determineComment(ExecutableElement methodElement) { + String inheritedInlineComment = getInheritedInlineCommentString(methodElement); + Optional docCommentTree = getDocCommentTree(methodElement); + if (docCommentTree.isPresent()){ + return replaceBlockTags(docCommentTree.get(), inheritedInlineComment); + } + return inheritedInlineComment; + } + /** * If the item being inherited from is declared from external compiled package, * or is declared in the packages like java.lang.Object, * comments may be not available as doclet resolves from byte code. */ - String getInheritedInlineCommentString(ExecutableElement exeElement) { + private String getInheritedInlineCommentString(ExecutableElement exeElement) { CommentHelper ch = getInheritedInlineTags(new CommentHelper(exeElement, utils)); // Remove unresolved "@inheritDoc" tag. List dctree = utils.removeBlockTag(ch.inlineTags, DocTree.Kind.INHERIT_DOC); return replaceLinksAndCodes(dctree); } - CommentHelper getInheritedInlineTags(CommentHelper input) { + private CommentHelper getInheritedInlineTags(CommentHelper input) { CommentHelper output = input.copy(); if (!output.hasInheritDocTag() && !output.isSimpleOverride()) { return output; diff --git a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/ClassLookup.java b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/ClassLookup.java index 2d323863..91f097cc 100644 --- a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/ClassLookup.java +++ b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/ClassLookup.java @@ -2,22 +2,23 @@ import com.microsoft.lookup.model.ExtendedMetadataFileItem; import com.microsoft.model.MetadataFileItem; -import com.microsoft.model.Status; import com.microsoft.model.TypeParameter; import com.microsoft.util.Utils; -import com.sun.source.doctree.DeprecatedTree; -import com.sun.source.doctree.DocTree; import jdk.javadoc.doclet.DocletEnvironment; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; -import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; public class ClassLookup extends BaseLookup { @@ -57,28 +58,6 @@ protected ExtendedMetadataFileItem buildMetadataFileItem(TypeElement classElemen return result; } - public String extractStatus(TypeElement classElement) { - DocTree deprecated = getDocCommentTree(classElement) - .map(docTree -> docTree.getBlockTags().stream() - .filter(o -> o.getKind() == DocTree.Kind.DEPRECATED) - .findFirst().orElse(null) - ).orElse(null); - - if (deprecated != null) { - return Status.DEPRECATED.toString(); - } - return null; - } - - public String extractDeprecatedDescription(TypeElement classElement) { - return getDocCommentTree(classElement).map(docTree -> docTree.getBlockTags().stream() - .filter(o -> o.getKind() == DocTree.Kind.DEPRECATED) - .map(o -> (DeprecatedTree) o) - .map(o -> replaceLinksAndCodes(o.getBody())) - .findFirst().orElse(null) - ).orElse(null); - } - void populateContent(TypeElement classElement, String shortNameWithGenericsSupport, ExtendedMetadataFileItem container) { String type = elementKindLookup.get(classElement.getKind()); diff --git a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/PackageLookup.java b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/PackageLookup.java index 9d1e9216..afc4a55d 100644 --- a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/PackageLookup.java +++ b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/PackageLookup.java @@ -5,7 +5,6 @@ import jdk.javadoc.doclet.DocletEnvironment; import javax.lang.model.element.PackageElement; -import javax.lang.model.element.TypeElement; public class PackageLookup extends BaseLookup { @@ -31,7 +30,8 @@ protected ExtendedMetadataFileItem buildMetadataFileItem(PackageElement packageE return result; } - public String extractStatus(String name) { + public String extractStatus(PackageElement packageElement) { + String name = String.valueOf(packageElement.getQualifiedName()); if (name.contains(Status.ALPHA.toString())) { return Status.ALPHA.toString(); } @@ -46,9 +46,9 @@ String determinePackageContent(PackageElement packageElement) { } public String extractJavaType(PackageElement element) { - String javatype = element.getKind().name().toLowerCase().replaceAll("_",""); - if (javatype.equals("package")){ - return javatype; + String javaType = element.getKind().name().toLowerCase().replaceAll("_", ""); + if (javaType.equals("package")) { + return javaType; } return null; } diff --git a/third_party/docfx-doclet-143274/src/test/java/com/microsoft/lookup/ClassItemsLookupTest.java b/third_party/docfx-doclet-143274/src/test/java/com/microsoft/lookup/ClassItemsLookupTest.java index cecc9784..ed5ce1a2 100644 --- a/third_party/docfx-doclet-143274/src/test/java/com/microsoft/lookup/ClassItemsLookupTest.java +++ b/third_party/docfx-doclet-143274/src/test/java/com/microsoft/lookup/ClassItemsLookupTest.java @@ -265,28 +265,4 @@ public void determineTypeForEnumConstant() { assertEquals(classItemsLookup.determineType(element.getEnclosedElements().get(0)), "Field"); assertEquals(classItemsLookup.determineType(element.getEnclosedElements().get(1)), "Field"); } - - @Test - public void extractDeprecatedDescription() { - TypeElement element = elements.getTypeElement("com.microsoft.samples.agreements.AgreementDetailsCollectionOperations"); - ExecutableElement method = ElementFilter.methodsIn(element.getEnclosedElements()).get(0); - String depMsg = "Deprecated Message :("; - - when(environment.getDocTrees()).thenReturn(docTrees); - when(docTrees.getDocCommentTree(method)).thenReturn(docCommentTree); - doReturn(Arrays.asList(deprecatedTree)).when(docCommentTree).getBlockTags(); - when(deprecatedTree.getKind()).thenReturn(Kind.DEPRECATED); - - doReturn(Arrays.asList(textTree)).when(deprecatedTree).getBody(); - when(textTree.getKind()).thenReturn(Kind.TEXT); - when(textTree.toString()).thenReturn(depMsg); - - String result = classItemsLookup.extractDeprecatedDescription(method); - - verify(environment).getDocTrees(); - verify(docTrees).getDocCommentTree(method); - verify(docCommentTree).getBlockTags(); - verify(deprecatedTree).getKind(); - assertEquals("Wrong description", result, depMsg); - } } diff --git a/third_party/docfx-doclet-143274/src/test/java/com/microsoft/lookup/ClassLookupTest.java b/third_party/docfx-doclet-143274/src/test/java/com/microsoft/lookup/ClassLookupTest.java index 21d9a2c6..9ec0557b 100644 --- a/third_party/docfx-doclet-143274/src/test/java/com/microsoft/lookup/ClassLookupTest.java +++ b/third_party/docfx-doclet-143274/src/test/java/com/microsoft/lookup/ClassLookupTest.java @@ -168,45 +168,6 @@ public void determineTypeForClass() { assertEquals(classLookup.determineType(element), "Class"); } - @Test - public void extractDeprecatedDescription() { - TypeElement element = elements.getTypeElement("com.microsoft.samples.agreements.AgreementDetailsCollectionOperations"); - String depMsg = "Deprecated Message :("; - - when(environment.getDocTrees()).thenReturn(docTrees); - when(docTrees.getDocCommentTree(element)).thenReturn(docCommentTree); - doReturn(Arrays.asList(deprecatedTree)).when(docCommentTree).getBlockTags(); - when(deprecatedTree.getKind()).thenReturn(DocTree.Kind.DEPRECATED); - - doReturn(Arrays.asList(textTree)).when(deprecatedTree).getBody(); - when(textTree.getKind()).thenReturn(DocTree.Kind.TEXT); - when(textTree.toString()).thenReturn(depMsg); - - String result = classLookup.extractDeprecatedDescription(element); - - verify(environment).getDocTrees(); - verify(docTrees).getDocCommentTree(element); - verify(docCommentTree).getBlockTags(); - verify(deprecatedTree).getKind(); - assertEquals("Wrong description", result, depMsg); - } - - @Test - public void extractDeprecatedDescriptionNull() { - TypeElement element = elements.getTypeElement("com.microsoft.samples.agreements.AgreementDetailsCollectionOperations"); - - when(environment.getDocTrees()).thenReturn(docTrees); - when(docTrees.getDocCommentTree(element)).thenReturn(docCommentTree); - doReturn(Arrays.asList()).when(docCommentTree).getBlockTags(); - - String result = classLookup.extractDeprecatedDescription(element); - - verify(environment).getDocTrees(); - verify(docTrees).getDocCommentTree(element); - verify(docCommentTree).getBlockTags(); - assertEquals("Wrong description", result, null); - } - @Test public void extractStatusDeprecated() { TypeElement element = elements.getTypeElement("com.microsoft.samples.agreements.AgreementDetailsCollectionOperations"); diff --git a/third_party/docfx-doclet-143274/src/test/java/com/microsoft/lookup/PackageLookupTest.java b/third_party/docfx-doclet-143274/src/test/java/com/microsoft/lookup/PackageLookupTest.java index 77fb3684..90408fb7 100644 --- a/third_party/docfx-doclet-143274/src/test/java/com/microsoft/lookup/PackageLookupTest.java +++ b/third_party/docfx-doclet-143274/src/test/java/com/microsoft/lookup/PackageLookupTest.java @@ -46,8 +46,8 @@ public void extractPackageStatus() { PackageElement elementBeta = elements.getPackageElement("com.microsoft.samples.google.v1beta"); PackageElement elementAlpha = elements.getPackageElement("com.microsoft.samples.google.v1p1alpha"); - String resultA = packageLookup.extractStatus(elementAlpha.getQualifiedName().toString()); - String resultB = packageLookup.extractStatus(elementBeta.getQualifiedName().toString()); + String resultA = packageLookup.extractStatus(elementAlpha); + String resultB = packageLookup.extractStatus(elementBeta); assertEquals("Wrong result", resultA, Status.ALPHA.toString()); assertEquals("Wrong result", resultB, Status.BETA.toString()); diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.SuperHero.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.SuperHero.yml index 543bfec2..0804e4c8 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.SuperHero.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.SuperHero.yml @@ -254,7 +254,7 @@ items: overload: "com.microsoft.samples.SuperHero.successfullyAttacked*" type: "Method" package: "com.microsoft.samples" - summary: "

(deprecated) As of version 1.1, use . . . instead

\n

This is a simple description of the method. . .\n Superman!\n

" + summary: "\nDeprecated. As of version 1.1, use . . . instead\n\n

This is a simple description of the method. . .\n Superman!\n

\nSee Also: HERO-402\n" syntax: content: "public int successfullyAttacked(int incomingDamage, String damageType)" parameters: diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.agreements.AgreementDetailsCollectionOperations.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.agreements.AgreementDetailsCollectionOperations.yml index 22c01beb..2ce93c0d 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.agreements.AgreementDetailsCollectionOperations.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.agreements.AgreementDetailsCollectionOperations.yml @@ -13,7 +13,7 @@ items: fullName: "com.microsoft.samples.agreements.AgreementDetailsCollectionOperations" type: "Class" package: "com.microsoft.samples.agreements" - summary: "

(deprecated) Use AgreementMetaData instead.

\nAgreement details collection operations implementation class." + summary: "\nDeprecated. Use AgreementMetaData instead.\n\nAgreement details collection operations implementation class." syntax: content: "public class AgreementDetailsCollectionOperations extends BasePartnerComponentString implements IAgreementDetailsCollection" inheritance: @@ -66,7 +66,7 @@ items: overload: "com.microsoft.samples.agreements.AgreementDetailsCollectionOperations.get*" type: "Method" package: "com.microsoft.samples.agreements" - summary: "

(deprecated) Some text

\nRetrieves the agreement details." + summary: "\nDeprecated. Some text\n\nRetrieves the agreement details." syntax: content: "public ResourceCollection get()" return: diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.agreements.IAgreementDetailsCollection.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.agreements.IAgreementDetailsCollection.yml index 8afb653a..088a3262 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.agreements.IAgreementDetailsCollection.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.agreements.IAgreementDetailsCollection.yml @@ -12,7 +12,7 @@ items: fullName: "com.microsoft.samples.agreements.IAgreementDetailsCollection" type: "Interface" package: "com.microsoft.samples.agreements" - summary: "

(deprecated) This one is deprecated :(

\nEncapsulates the operations on the agreement metadata collection." + summary: "\nDeprecated. This one is deprecated :(\n\nEncapsulates the operations on the agreement metadata collection." syntax: content: "public interface IAgreementDetailsCollection" status: "deprecated" diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.RecognitionAudio.AudioSourceCase.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.RecognitionAudio.AudioSourceCase.yml index 8b389ba6..134a6841 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.RecognitionAudio.AudioSourceCase.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.RecognitionAudio.AudioSourceCase.yml @@ -146,7 +146,7 @@ items: overload: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase.valueOf*" type: "Method" package: "com.microsoft.samples.google" - summary: "

(deprecated) Use #forNumber(int) instead.

" + summary: "\nDeprecated. Use #forNumber(int) instead.\n\n" syntax: content: "public static RecognitionAudio.AudioSourceCase valueOf(int value)" parameters: diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.v1beta.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.v1beta.yml index 2fe445d3..0e86ea88 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.v1beta.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.v1beta.yml @@ -12,6 +12,7 @@ items: type: "Namespace" syntax: content: "package com.microsoft.samples.google.v1beta" + status: "beta" javaType: "package" references: - uid: "com.microsoft.samples.google.v1beta.SpeechClient" diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.v1p1alpha.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.v1p1alpha.yml index 19fbd1f3..314148de 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.v1p1alpha.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.v1p1alpha.yml @@ -12,6 +12,7 @@ items: type: "Namespace" syntax: content: "package com.microsoft.samples.google.v1p1alpha" + status: "alpha" javaType: "package" references: - uid: "com.microsoft.samples.google.v1p1alpha.SpeechClient" diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.subpackage.Person.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.subpackage.Person.yml index 53fcb271..c994836c 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.subpackage.Person.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.subpackage.Person.yml @@ -21,7 +21,7 @@ items: fullName: "com.microsoft.samples.subpackage.Person" type: "Class" package: "com.microsoft.samples.subpackage" - summary: "Class that describes some person\n\n This comment has links to:\n
    \n
  • Owner class Person
  • \n
  • Its inner class Person.IdentificationInfo
  • \n
  • Its method Person#setLastName(String lastName)
  • \n
  • Its method without params Person#setLastName()
  • \n
  • Its public field Person#age
  • \n
  • Another class which used here Set
  • \n
  • Another class which not used here List
  • \n
  • Broken link sdfdsagdsfghfgh
  • \n
  • Plain link someContent
  • \n
  • Link that starts from '#' #setLastName()
  • \n
  • Link with label WordOne
  • \n
\n\n This is an \"at\" symbol: @" + summary: "Class that describes some person\n\n This comment has links to:\n
    \n
  • Owner class Person
  • \n
  • Its inner class Person.IdentificationInfo
  • \n
  • Its method Person#setLastName(String lastName)
  • \n
  • Its method without params Person#setLastName()
  • \n
  • Its public field Person#age
  • \n
  • Another class which used here Set
  • \n
  • Another class which not used here List
  • \n
  • Broken link sdfdsagdsfghfgh
  • \n
  • Plain link someContent
  • \n
  • Link that starts from '#' #setLastName()
  • \n
  • Link with label WordOne
  • \n
\n\n This is an \"at\" symbol: @\nSee Also: Display\n" syntax: content: "public class Person" typeParameters: From 717d65aa21a93594a3e2b61e2aee9dcc3b746d10 Mon Sep 17 00:00:00 2001 From: Emily Ball Date: Wed, 22 Dec 2021 16:34:30 -0800 Subject: [PATCH 3/4] chore: comment --- .../src/main/java/com/microsoft/lookup/BaseLookup.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/BaseLookup.java b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/BaseLookup.java index c702aaaf..c2e29a1c 100644 --- a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/BaseLookup.java +++ b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/BaseLookup.java @@ -202,7 +202,7 @@ protected String determineComment(T element) { } /** - * Provides support for @deprecated and @see tags + * Provides support for deprecated and see tags */ String replaceBlockTags(DocCommentTree docCommentTree, String comment) { List seeItems = new ArrayList<>(); From dd8d1404c958434bc81d115fc8c7ed232b41ff5b Mon Sep 17 00:00:00 2001 From: Emily Ball Date: Tue, 28 Dec 2021 11:33:05 -0800 Subject: [PATCH 4/4] feat: include static field/method javaType --- .../java/com/microsoft/lookup/BaseLookup.java | 2 +- .../microsoft/lookup/ClassItemsLookup.java | 27 ++++++++-- .../com/microsoft/lookup/PackageLookup.java | 2 +- .../lookup/ClassItemsLookupTest.java | 51 ++++++++++++++++++- ...ceptionHandler.Interceptor.RetryResult.yml | 5 ++ ...com.microsoft.samples.ExceptionHandler.yml | 2 + ...t.samples.google.ProductSearchSettings.yml | 10 ++++ ...oogle.RecognitionAudio.AudioSourceCase.yml | 7 +++ ...rosoft.samples.google.RecognitionAudio.yml | 2 + ....microsoft.samples.google.SpeechClient.yml | 3 ++ ...icrosoft.samples.google.SpeechSettings.yml | 10 ++++ ...oft.samples.google.ValidationException.yml | 3 ++ ...oft.samples.google.v1beta.SpeechClient.yml | 3 ++ ....samples.google.v1p1alpha.SpeechClient.yml | 3 ++ ...ckage.Person.IdentificationInfo.Gender.yml | 4 ++ ...om.microsoft.samples.subpackage.Person.yml | 1 + 16 files changed, 128 insertions(+), 7 deletions(-) diff --git a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/BaseLookup.java b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/BaseLookup.java index c2e29a1c..6ca5f715 100644 --- a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/BaseLookup.java +++ b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/BaseLookup.java @@ -174,7 +174,7 @@ public String extractStatus(T element) { .filter(docTree -> docTree.getKind().equals(DocTree.Kind.DEPRECATED)) .findFirst() .isPresent(); - if (isDeprecated){ + if (isDeprecated) { return DocTree.Kind.DEPRECATED.name().toLowerCase(); } } diff --git a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/ClassItemsLookup.java b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/ClassItemsLookup.java index 1e60bd45..d3e8d2a3 100644 --- a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/ClassItemsLookup.java +++ b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/ClassItemsLookup.java @@ -6,11 +6,20 @@ import com.microsoft.model.Return; import com.microsoft.util.CommentHelper; import com.microsoft.util.Utils; -import com.sun.source.doctree.*; +import com.sun.source.doctree.DocCommentTree; +import com.sun.source.doctree.DocTree; import com.sun.source.doctree.DocTree.Kind; +import com.sun.source.doctree.ParamTree; +import com.sun.source.doctree.ReturnTree; +import com.sun.source.doctree.ThrowsTree; import jdk.javadoc.doclet.DocletEnvironment; -import javax.lang.model.element.*; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeKind; import java.util.ArrayList; import java.util.List; @@ -151,7 +160,7 @@ String extractOverriddenUid(ExecutableElement ovr) { private String determineComment(ExecutableElement methodElement) { String inheritedInlineComment = getInheritedInlineCommentString(methodElement); Optional docCommentTree = getDocCommentTree(methodElement); - if (docCommentTree.isPresent()){ + if (docCommentTree.isPresent()) { return replaceBlockTags(docCommentTree.get(), inheritedInlineComment); } return inheritedInlineComment; @@ -198,4 +207,16 @@ private CommentHelper getInheritedInlineTags(CommentHelper input) { return output; } + + public String extractJavaType(Element element) { + if (element.getModifiers().contains(Modifier.STATIC)) { + if (element.getKind().equals(ElementKind.METHOD)) { + return "static method"; + } + if (element.getKind().equals(ElementKind.FIELD) || element.getKind().equals(ElementKind.ENUM_CONSTANT)) { + return "static field"; + } + } + return null; + } } diff --git a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/PackageLookup.java b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/PackageLookup.java index afc4a55d..8f939d49 100644 --- a/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/PackageLookup.java +++ b/third_party/docfx-doclet-143274/src/main/java/com/microsoft/lookup/PackageLookup.java @@ -46,7 +46,7 @@ String determinePackageContent(PackageElement packageElement) { } public String extractJavaType(PackageElement element) { - String javaType = element.getKind().name().toLowerCase().replaceAll("_", ""); + String javaType = element.getKind().name().toLowerCase(); if (javaType.equals("package")) { return javaType; } diff --git a/third_party/docfx-doclet-143274/src/test/java/com/microsoft/lookup/ClassItemsLookupTest.java b/third_party/docfx-doclet-143274/src/test/java/com/microsoft/lookup/ClassItemsLookupTest.java index ed5ce1a2..2f990ade 100644 --- a/third_party/docfx-doclet-143274/src/test/java/com/microsoft/lookup/ClassItemsLookupTest.java +++ b/third_party/docfx-doclet-143274/src/test/java/com/microsoft/lookup/ClassItemsLookupTest.java @@ -4,8 +4,14 @@ import com.microsoft.model.ExceptionItem; import com.microsoft.model.MethodParameter; import com.microsoft.model.Return; -import com.sun.source.doctree.*; +import com.sun.source.doctree.DeprecatedTree; +import com.sun.source.doctree.DocCommentTree; import com.sun.source.doctree.DocTree.Kind; +import com.sun.source.doctree.IdentifierTree; +import com.sun.source.doctree.ParamTree; +import com.sun.source.doctree.ReturnTree; +import com.sun.source.doctree.TextTree; +import com.sun.source.doctree.ThrowsTree; import com.sun.source.util.DocTrees; import jdk.javadoc.doclet.DocletEnvironment; import org.junit.Before; @@ -15,6 +21,7 @@ import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; +import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; @@ -22,10 +29,14 @@ import javax.lang.model.util.Elements; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class ClassItemsLookupTest { @@ -33,6 +44,8 @@ public class ClassItemsLookupTest { @Rule public CompilationRule rule = new CompilationRule(); private Elements elements; + private List allGenderElements; + private List allPersonElements; private DocletEnvironment environment; private DocTrees docTrees; private DocCommentTree docCommentTree; @@ -47,6 +60,10 @@ public class ClassItemsLookupTest { @Before public void setup() { elements = rule.getElements(); + allGenderElements = elements.getTypeElement("com.microsoft.samples.subpackage.Person.IdentificationInfo.Gender") + .getEnclosedElements().stream().collect(Collectors.toList()); + allPersonElements = elements.getTypeElement("com.microsoft.samples.subpackage.Person") + .getEnclosedElements().stream().collect(Collectors.toList()); environment = Mockito.mock(DocletEnvironment.class); docTrees = Mockito.mock(DocTrees.class); docCommentTree = Mockito.mock(DocCommentTree.class); @@ -265,4 +282,34 @@ public void determineTypeForEnumConstant() { assertEquals(classItemsLookup.determineType(element.getEnclosedElements().get(0)), "Field"); assertEquals(classItemsLookup.determineType(element.getEnclosedElements().get(1)), "Field"); } + + @Test + public void testExtractJavaTypeStaticMethod() { + Element staticMethod = getElementByName(allGenderElements,"valueOf(java.lang.String)"); + assertEquals("Wrong javaType","static method", classItemsLookup.extractJavaType(staticMethod)); + } + + @Test + public void testExtractJavaTypeStaticField() { + Element field = getElementByName(allGenderElements,"FEMALE"); + assertEquals("Wrong javaType", "static field", classItemsLookup.extractJavaType(field)); + } + + @Test + public void testExtractJavaTypeNonStatic() { + Element constructor = getElementByName(allGenderElements,"Gender()"); + assertEquals("Wrong javaType",null, classItemsLookup.extractJavaType(constructor)); + + Element nonStaticMethod = getElementByName(allPersonElements,"getFirstName()"); + assertEquals("Wrong javaType",null, classItemsLookup.extractJavaType(nonStaticMethod)); + + Element nonStaticField = getElementByName(allPersonElements,"age"); + assertEquals("Wrong javaType",null, classItemsLookup.extractJavaType(nonStaticField)); + } + + private Element getElementByName(List elements, String name) { + return elements.stream() + .filter(e -> e.toString().equals(name)) + .findFirst().orElse(null); + } } diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult.yml index 870375f3..96e630fa 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult.yml @@ -53,6 +53,7 @@ items: content: "public static final ExceptionHandler.Interceptor.RetryResult CONTINUE_EVALUATION" return: type: "com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult" + javaType: "static field" - uid: "com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult.NO_RETRY" id: "NO_RETRY" parent: "com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult" @@ -67,6 +68,7 @@ items: content: "public static final ExceptionHandler.Interceptor.RetryResult NO_RETRY" return: type: "com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult" + javaType: "static field" - uid: "com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult.RETRY" id: "RETRY" parent: "com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult" @@ -81,6 +83,7 @@ items: content: "public static final ExceptionHandler.Interceptor.RetryResult RETRY" return: type: "com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult" + javaType: "static field" - uid: "com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult.RetryResult()" id: "RetryResult()" parent: "com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult" @@ -112,6 +115,7 @@ items: type: "java.lang.String" return: type: "com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult" + javaType: "static method" - uid: "com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult.values()" id: "values()" parent: "com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult" @@ -127,6 +131,7 @@ items: content: "public static ExceptionHandler.Interceptor.RetryResult[] values()" return: type: "com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult[]" + javaType: "static method" references: - uid: "com.microsoft.samples.ExceptionHandler.Interceptor.RetryResult.RetryResult*" name: "RetryResult" diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.ExceptionHandler.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.ExceptionHandler.yml index d1928ffb..bb3dbec5 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.ExceptionHandler.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.ExceptionHandler.yml @@ -112,6 +112,7 @@ items: content: "public static ExceptionHandler getDefaultInstance()" return: type: "com.microsoft.samples.ExceptionHandler" + javaType: "static method" - uid: "com.microsoft.samples.ExceptionHandler.hashCode()" id: "hashCode()" parent: "com.microsoft.samples.ExceptionHandler" @@ -143,6 +144,7 @@ items: content: "public static ExceptionHandler.Builder newBuilder()" return: type: "com.microsoft.samples.ExceptionHandler.Builder" + javaType: "static method" - uid: "com.microsoft.samples.ExceptionHandler.shouldRetry(java.lang.Throwable,java.lang.Object)" id: "shouldRetry(java.lang.Throwable,java.lang.Object)" parent: "com.microsoft.samples.ExceptionHandler" diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.ProductSearchSettings.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.ProductSearchSettings.yml index fcb4b7e9..aa11ba23 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.ProductSearchSettings.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.ProductSearchSettings.yml @@ -128,6 +128,7 @@ items: type: "com.microsoft.samples.google.ProductSearchSettings" exceptions: - type: "java.io.IOException" + javaType: "static method" - uid: "com.microsoft.samples.google.ProductSearchSettings.createProductSetSettings()" id: "createProductSetSettings()" parent: "com.microsoft.samples.google.ProductSearchSettings" @@ -191,6 +192,7 @@ items: content: "public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder()" return: type: "com.google.api.gax.rpc.ApiClientHeaderProvider.Builder" + javaType: "static method" - uid: "com.microsoft.samples.google.ProductSearchSettings.defaultCredentialsProviderBuilder()" id: "defaultCredentialsProviderBuilder()" parent: "com.microsoft.samples.google.ProductSearchSettings" @@ -207,6 +209,7 @@ items: content: "public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder()" return: type: "com.google.api.gax.core.GoogleCredentialsProvider.Builder" + javaType: "static method" - uid: "com.microsoft.samples.google.ProductSearchSettings.defaultExecutorProviderBuilder()" id: "defaultExecutorProviderBuilder()" parent: "com.microsoft.samples.google.ProductSearchSettings" @@ -223,6 +226,7 @@ items: content: "public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder()" return: type: "com.google.api.gax.core.InstantiatingExecutorProvider.Builder" + javaType: "static method" - uid: "com.microsoft.samples.google.ProductSearchSettings.defaultGrpcTransportProviderBuilder()" id: "defaultGrpcTransportProviderBuilder()" parent: "com.microsoft.samples.google.ProductSearchSettings" @@ -239,6 +243,7 @@ items: content: "public static InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder()" return: type: "com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.Builder" + javaType: "static method" - uid: "com.microsoft.samples.google.ProductSearchSettings.defaultTransportChannelProvider()" id: "defaultTransportChannelProvider()" parent: "com.microsoft.samples.google.ProductSearchSettings" @@ -254,6 +259,7 @@ items: content: "public static TransportChannelProvider defaultTransportChannelProvider()" return: type: "com.google.api.gax.rpc.TransportChannelProvider" + javaType: "static method" - uid: "com.microsoft.samples.google.ProductSearchSettings.deleteProductSetSettings()" id: "deleteProductSetSettings()" parent: "com.microsoft.samples.google.ProductSearchSettings" @@ -318,6 +324,7 @@ items: content: "public static String getDefaultEndpoint()" return: type: "java.lang.String" + javaType: "static method" - uid: "com.microsoft.samples.google.ProductSearchSettings.getDefaultServiceScopes()" id: "getDefaultServiceScopes()" parent: "com.microsoft.samples.google.ProductSearchSettings" @@ -334,6 +341,7 @@ items: content: "public static List getDefaultServiceScopes()" return: type: "java.util.List" + javaType: "static method" - uid: "com.microsoft.samples.google.ProductSearchSettings.getProductSetSettings()" id: "getProductSetSettings()" parent: "com.microsoft.samples.google.ProductSearchSettings" @@ -494,6 +502,7 @@ items: content: "public static ProductSearchSettings.Builder newBuilder()" return: type: "com.microsoft.samples.google.ProductSearchSettings.Builder" + javaType: "static method" - uid: "com.microsoft.samples.google.ProductSearchSettings.newBuilder(com.google.api.gax.rpc.ClientContext)" id: "newBuilder(com.google.api.gax.rpc.ClientContext)" parent: "com.microsoft.samples.google.ProductSearchSettings" @@ -513,6 +522,7 @@ items: type: "com.google.api.gax.rpc.ClientContext" return: type: "com.microsoft.samples.google.ProductSearchSettings.Builder" + javaType: "static method" - uid: "com.microsoft.samples.google.ProductSearchSettings.purgeProductsOperationSettings()" id: "purgeProductsOperationSettings()" parent: "com.microsoft.samples.google.ProductSearchSettings" diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.RecognitionAudio.AudioSourceCase.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.RecognitionAudio.AudioSourceCase.yml index 134a6841..3ceed122 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.RecognitionAudio.AudioSourceCase.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.RecognitionAudio.AudioSourceCase.yml @@ -58,6 +58,7 @@ items: content: "public static final RecognitionAudio.AudioSourceCase AUDIOSOURCE_NOT_SET" return: type: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase" + javaType: "static field" - uid: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase.AudioSourceCase(int)" id: "AudioSourceCase(int)" parent: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase" @@ -88,6 +89,7 @@ items: content: "public static final RecognitionAudio.AudioSourceCase CONTENT" return: type: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase" + javaType: "static field" - uid: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase.URI" id: "URI" parent: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase" @@ -102,6 +104,7 @@ items: content: "public static final RecognitionAudio.AudioSourceCase URI" return: type: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase" + javaType: "static field" - uid: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase.forNumber(int)" id: "forNumber(int)" parent: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase" @@ -120,6 +123,7 @@ items: type: "int" return: type: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase" + javaType: "static method" - uid: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase.getNumber()" id: "getNumber()" parent: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase" @@ -157,6 +161,7 @@ items: type: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase" description: "The enum associated with the given number." status: "deprecated" + javaType: "static method" - uid: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase.valueOf(java.lang.String)" id: "valueOf(java.lang.String)" parent: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase" @@ -175,6 +180,7 @@ items: type: "java.lang.String" return: type: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase" + javaType: "static method" - uid: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase.values()" id: "values()" parent: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase" @@ -190,6 +196,7 @@ items: content: "public static RecognitionAudio.AudioSourceCase[] values()" return: type: "com.microsoft.samples.google.RecognitionAudio.AudioSourceCase[]" + javaType: "static method" references: - uid: "int" href: "https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html" diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.RecognitionAudio.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.RecognitionAudio.yml index 429de39c..147c3183 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.RecognitionAudio.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.RecognitionAudio.yml @@ -133,6 +133,7 @@ items: content: "public static final int CONTENT_FIELD_NUMBER" return: type: "int" + javaType: "static field" - uid: "com.microsoft.samples.google.RecognitionAudio.RecognitionAudio()" id: "RecognitionAudio()" parent: "com.microsoft.samples.google.RecognitionAudio" @@ -194,6 +195,7 @@ items: content: "public static final int URI_FIELD_NUMBER" return: type: "int" + javaType: "static field" - uid: "com.microsoft.samples.google.RecognitionAudio.getAudioSourceCase()" id: "getAudioSourceCase()" parent: "com.microsoft.samples.google.RecognitionAudio" diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.SpeechClient.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.SpeechClient.yml index 2b5f6b5b..7600053c 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.SpeechClient.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.SpeechClient.yml @@ -138,6 +138,7 @@ items: type: "com.microsoft.samples.google.SpeechClient" exceptions: - type: "java.io.IOException" + javaType: "static method" - uid: "com.microsoft.samples.google.SpeechClient.create(com.google.cloud.speech.v1p1beta1.stub.SpeechStub)" id: "create(com.google.cloud.speech.v1p1beta1.stub.SpeechStub)" parent: "com.microsoft.samples.google.SpeechClient" @@ -157,6 +158,7 @@ items: type: "com.google.cloud.speech.v1p1beta1.stub.SpeechStub" return: type: "com.microsoft.samples.google.SpeechClient" + javaType: "static method" - uid: "com.microsoft.samples.google.SpeechClient.create(com.microsoft.samples.google.SpeechSettings)" id: "create(com.microsoft.samples.google.SpeechSettings)" parent: "com.microsoft.samples.google.SpeechClient" @@ -178,6 +180,7 @@ items: type: "com.microsoft.samples.google.SpeechClient" exceptions: - type: "java.io.IOException" + javaType: "static method" - uid: "com.microsoft.samples.google.SpeechClient.getOperationsClient()" id: "getOperationsClient()" parent: "com.microsoft.samples.google.SpeechClient" diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.SpeechSettings.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.SpeechSettings.yml index 16a482b0..faffd422 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.SpeechSettings.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.SpeechSettings.yml @@ -95,6 +95,7 @@ items: type: "com.microsoft.samples.google.SpeechSettings" exceptions: - type: "java.io.IOException" + javaType: "static method" - uid: "com.microsoft.samples.google.SpeechSettings.defaultApiClientHeaderProviderBuilder()" id: "defaultApiClientHeaderProviderBuilder()" parent: "com.microsoft.samples.google.SpeechSettings" @@ -110,6 +111,7 @@ items: content: "public static ApiClientHeaderProvider.Builder defaultApiClientHeaderProviderBuilder()" return: type: "com.google.api.gax.rpc.ApiClientHeaderProvider.Builder" + javaType: "static method" - uid: "com.microsoft.samples.google.SpeechSettings.defaultCredentialsProviderBuilder()" id: "defaultCredentialsProviderBuilder()" parent: "com.microsoft.samples.google.SpeechSettings" @@ -126,6 +128,7 @@ items: content: "public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilder()" return: type: "com.google.api.gax.core.GoogleCredentialsProvider.Builder" + javaType: "static method" - uid: "com.microsoft.samples.google.SpeechSettings.defaultExecutorProviderBuilder()" id: "defaultExecutorProviderBuilder()" parent: "com.microsoft.samples.google.SpeechSettings" @@ -142,6 +145,7 @@ items: content: "public static InstantiatingExecutorProvider.Builder defaultExecutorProviderBuilder()" return: type: "com.google.api.gax.core.InstantiatingExecutorProvider.Builder" + javaType: "static method" - uid: "com.microsoft.samples.google.SpeechSettings.defaultGrpcTransportProviderBuilder()" id: "defaultGrpcTransportProviderBuilder()" parent: "com.microsoft.samples.google.SpeechSettings" @@ -158,6 +162,7 @@ items: content: "public static InstantiatingGrpcChannelProvider.Builder defaultGrpcTransportProviderBuilder()" return: type: "com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.Builder" + javaType: "static method" - uid: "com.microsoft.samples.google.SpeechSettings.defaultTransportChannelProvider()" id: "defaultTransportChannelProvider()" parent: "com.microsoft.samples.google.SpeechSettings" @@ -173,6 +178,7 @@ items: content: "public static TransportChannelProvider defaultTransportChannelProvider()" return: type: "com.google.api.gax.rpc.TransportChannelProvider" + javaType: "static method" - uid: "com.microsoft.samples.google.SpeechSettings.getDefaultEndpoint()" id: "getDefaultEndpoint()" parent: "com.microsoft.samples.google.SpeechSettings" @@ -189,6 +195,7 @@ items: content: "public static String getDefaultEndpoint()" return: type: "java.lang.String" + javaType: "static method" - uid: "com.microsoft.samples.google.SpeechSettings.getDefaultServiceScopes()" id: "getDefaultServiceScopes()" parent: "com.microsoft.samples.google.SpeechSettings" @@ -205,6 +212,7 @@ items: content: "public static List getDefaultServiceScopes()" return: type: "java.util.List" + javaType: "static method" - uid: "com.microsoft.samples.google.SpeechSettings.longRunningRecognizeOperationSettings()" id: "longRunningRecognizeOperationSettings()" parent: "com.microsoft.samples.google.SpeechSettings" @@ -253,6 +261,7 @@ items: content: "public static SpeechSettings.Builder newBuilder()" return: type: "com.microsoft.samples.google.SpeechSettings.Builder" + javaType: "static method" - uid: "com.microsoft.samples.google.SpeechSettings.newBuilder(com.google.api.gax.rpc.ClientContext)" id: "newBuilder(com.google.api.gax.rpc.ClientContext)" parent: "com.microsoft.samples.google.SpeechSettings" @@ -272,6 +281,7 @@ items: type: "com.google.api.gax.rpc.ClientContext" return: type: "com.microsoft.samples.google.SpeechSettings.Builder" + javaType: "static method" - uid: "com.microsoft.samples.google.SpeechSettings.recognizeSettings()" id: "recognizeSettings()" parent: "com.microsoft.samples.google.SpeechSettings" diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.ValidationException.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.ValidationException.yml index ac1fa8b9..49324c70 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.ValidationException.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.ValidationException.yml @@ -83,6 +83,7 @@ items: summary: "Clears the validation context." syntax: content: "public static void popCurrentThreadValidationContext()" + javaType: "static method" - uid: "com.microsoft.samples.google.ValidationException.pushCurrentThreadValidationContext(com.microsoft.samples.google.ValidationException.Supplier)" id: "pushCurrentThreadValidationContext(com.microsoft.samples.google.ValidationException.Supplier)" parent: "com.microsoft.samples.google.ValidationException" @@ -100,6 +101,7 @@ items: parameters: - id: "supplier" type: "com.microsoft.samples.google.ValidationException.Supplier" + javaType: "static method" - uid: "com.microsoft.samples.google.ValidationException.pushCurrentThreadValidationContext(java.lang.String)" id: "pushCurrentThreadValidationContext(java.lang.String)" parent: "com.microsoft.samples.google.ValidationException" @@ -116,6 +118,7 @@ items: parameters: - id: "context" type: "java.lang.String" + javaType: "static method" references: - uid: "java.lang.String" href: "https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.v1beta.SpeechClient.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.v1beta.SpeechClient.yml index 6a6c1f22..4b03fd5b 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.v1beta.SpeechClient.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.v1beta.SpeechClient.yml @@ -138,6 +138,7 @@ items: type: "com.microsoft.samples.google.v1beta.SpeechClient" exceptions: - type: "java.io.IOException" + javaType: "static method" - uid: "com.microsoft.samples.google.v1beta.SpeechClient.create(com.google.cloud.speech.v1p1beta1.stub.SpeechStub)" id: "create(com.google.cloud.speech.v1p1beta1.stub.SpeechStub)" parent: "com.microsoft.samples.google.v1beta.SpeechClient" @@ -157,6 +158,7 @@ items: type: "com.google.cloud.speech.v1p1beta1.stub.SpeechStub" return: type: "com.microsoft.samples.google.v1beta.SpeechClient" + javaType: "static method" - uid: "com.microsoft.samples.google.v1beta.SpeechClient.create(com.microsoft.samples.google.SpeechSettings)" id: "create(com.microsoft.samples.google.SpeechSettings)" parent: "com.microsoft.samples.google.v1beta.SpeechClient" @@ -178,6 +180,7 @@ items: type: "com.microsoft.samples.google.v1beta.SpeechClient" exceptions: - type: "java.io.IOException" + javaType: "static method" - uid: "com.microsoft.samples.google.v1beta.SpeechClient.getOperationsClient()" id: "getOperationsClient()" parent: "com.microsoft.samples.google.v1beta.SpeechClient" diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.v1p1alpha.SpeechClient.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.v1p1alpha.SpeechClient.yml index f19a072a..5ad0e5d2 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.v1p1alpha.SpeechClient.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.google.v1p1alpha.SpeechClient.yml @@ -138,6 +138,7 @@ items: type: "com.microsoft.samples.google.v1p1alpha.SpeechClient" exceptions: - type: "java.io.IOException" + javaType: "static method" - uid: "com.microsoft.samples.google.v1p1alpha.SpeechClient.create(com.google.cloud.speech.v1p1beta1.stub.SpeechStub)" id: "create(com.google.cloud.speech.v1p1beta1.stub.SpeechStub)" parent: "com.microsoft.samples.google.v1p1alpha.SpeechClient" @@ -157,6 +158,7 @@ items: type: "com.google.cloud.speech.v1p1beta1.stub.SpeechStub" return: type: "com.microsoft.samples.google.v1p1alpha.SpeechClient" + javaType: "static method" - uid: "com.microsoft.samples.google.v1p1alpha.SpeechClient.create(com.microsoft.samples.google.SpeechSettings)" id: "create(com.microsoft.samples.google.SpeechSettings)" parent: "com.microsoft.samples.google.v1p1alpha.SpeechClient" @@ -178,6 +180,7 @@ items: type: "com.microsoft.samples.google.v1p1alpha.SpeechClient" exceptions: - type: "java.io.IOException" + javaType: "static method" - uid: "com.microsoft.samples.google.v1p1alpha.SpeechClient.getOperationsClient()" id: "getOperationsClient()" parent: "com.microsoft.samples.google.v1p1alpha.SpeechClient" diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.subpackage.Person.IdentificationInfo.Gender.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.subpackage.Person.IdentificationInfo.Gender.yml index d20b6979..ede81fa9 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.subpackage.Person.IdentificationInfo.Gender.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.subpackage.Person.IdentificationInfo.Gender.yml @@ -52,6 +52,7 @@ items: content: "public static final Person.IdentificationInfo.Gender FEMALE" return: type: "com.microsoft.samples.subpackage.Person.IdentificationInfo.Gender" + javaType: "static field" - uid: "com.microsoft.samples.subpackage.Person.IdentificationInfo.Gender.Gender()" id: "Gender()" parent: "com.microsoft.samples.subpackage.Person.IdentificationInfo.Gender" @@ -79,6 +80,7 @@ items: content: "public static final Person.IdentificationInfo.Gender MALE" return: type: "com.microsoft.samples.subpackage.Person.IdentificationInfo.Gender" + javaType: "static field" - uid: "com.microsoft.samples.subpackage.Person.IdentificationInfo.Gender.valueOf(java.lang.String)" id: "valueOf(java.lang.String)" parent: "com.microsoft.samples.subpackage.Person.IdentificationInfo.Gender" @@ -97,6 +99,7 @@ items: type: "java.lang.String" return: type: "com.microsoft.samples.subpackage.Person.IdentificationInfo.Gender" + javaType: "static method" - uid: "com.microsoft.samples.subpackage.Person.IdentificationInfo.Gender.values()" id: "values()" parent: "com.microsoft.samples.subpackage.Person.IdentificationInfo.Gender" @@ -112,6 +115,7 @@ items: content: "public static Person.IdentificationInfo.Gender[] values()" return: type: "com.microsoft.samples.subpackage.Person.IdentificationInfo.Gender[]" + javaType: "static method" references: - uid: "com.microsoft.samples.subpackage.Person.IdentificationInfo.Gender.Gender*" name: "Gender" diff --git a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.subpackage.Person.yml b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.subpackage.Person.yml index c994836c..1a071f68 100644 --- a/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.subpackage.Person.yml +++ b/third_party/docfx-doclet-143274/src/test/resources/expected-generated-files/com.microsoft.samples.subpackage.Person.yml @@ -86,6 +86,7 @@ items: type: "com.microsoft.samples.subpackage.Person" return: type: "com.microsoft.samples.subpackage.Person" + javaType: "static method" - uid: "com.microsoft.samples.subpackage.Person.getFirstName()" id: "getFirstName()" parent: "com.microsoft.samples.subpackage.Person"