Skip to content

Commit

Permalink
Make the JSDocInfoPrinter a bit prettier:
Browse files Browse the repository at this point in the history
- Include a * on every line
- Optionally print block, param, and return descriptions
- Add spaces between multiple template names

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=242039032
  • Loading branch information
johnplaisted authored and brad4d committed Apr 5, 2019
1 parent 248523c commit ff42048
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 60 deletions.
81 changes: 69 additions & 12 deletions src/com/google/javascript/jscomp/JSDocInfoPrinter.java
Expand Up @@ -38,9 +38,19 @@
public final class JSDocInfoPrinter {

private final boolean useOriginalName;
private final boolean printDesc;

JSDocInfoPrinter(boolean useOriginalName) {
public JSDocInfoPrinter(boolean useOriginalName) {
this(useOriginalName, false);
}

/**
* @param useOriginalName Whether to use the original name field when printing types.
* @param printDesc Whether to print block, param, and return descriptions.
*/
public JSDocInfoPrinter(boolean useOriginalName, boolean printDesc) {
this.useOriginalName = useOriginalName;
this.printDesc = printDesc;
}

public String print(JSDocInfo info) {
Expand Down Expand Up @@ -108,7 +118,10 @@ public String print(JSDocInfo info) {

String description = info.getDescription();
if (description != null) {
parts.add("@desc " + description + '\n');
if (description.contains("\n")) {
multiline = true;
}
parts.add("@desc " + description);
}

if (info.makesDicts()) {
Expand Down Expand Up @@ -162,13 +175,14 @@ public String print(JSDocInfo info) {
if (info.getParameterCount() > 0) {
multiline = true;
for (String name : info.getParameterNames()) {
parts.add("@param " + buildParamType(name, info.getParameterType(name)));
parts.add("@param " + buildParamType(info, name));
}
}

if (info.hasReturnType()) {
multiline = true;
parts.add(buildAnnotationWithType("return", info.getReturnType()));
parts.add(
buildAnnotationWithType("return", info.getReturnType(), info.getReturnDescription()));
}

if (!info.getThrownTypes().isEmpty()) {
Expand All @@ -177,7 +191,7 @@ public String print(JSDocInfo info) {

ImmutableList<String> names = info.getTemplateTypeNames();
if (!names.isEmpty()) {
parts.add("@template " + Joiner.on(',').join(names));
parts.add("@template " + Joiner.on(", ").join(names));
multiline = true;
}

Expand Down Expand Up @@ -262,16 +276,36 @@ public String print(JSDocInfo info) {
parts.add("@closurePrimitive {" + info.getClosurePrimitiveId() + "}");
}

parts.add("*/");
if (printDesc && info.getBlockDescription() != null) {
String cleaned = info.getBlockDescription().replaceAll("\n\\s*\\*\\s*", "\n");
if (!cleaned.isEmpty()) {
multiline = true;
cleaned = cleaned.trim();
if (parts.size() > 1) {
// If there is more than one part - the opening "/**" - then add blank line between the
// description and everything else.
cleaned += '\n';
}
parts.add(1, cleaned);
}
}

StringBuilder sb = new StringBuilder();
if (multiline) {
Joiner.on("\n ").appendTo(sb, parts);
Joiner.on("\n").appendTo(sb, parts);
} else {
Joiner.on(" ").appendTo(sb, parts);
sb.append(" */");
}
sb.append((multiline) ? "\n" : " ");
return sb.toString();
// Ensure all lines start with " *", and then ensure all non blank lines have a space after
// the *.
String s = sb.toString().replaceAll("\n", "\n *").replaceAll("\n \\*([^ \n])", "\n * $1");
if (multiline) {
s += "\n */\n";
} else {
s += " ";
}
return s;
}

private Node stripBang(Node typeNode) {
Expand All @@ -282,22 +316,45 @@ private Node stripBang(Node typeNode) {
}

private String buildAnnotationWithType(String annotation, JSTypeExpression type) {
return buildAnnotationWithType(annotation, type.getRoot());
return buildAnnotationWithType(annotation, type, null);
}

private String buildAnnotationWithType(
String annotation, JSTypeExpression type, String description) {
return buildAnnotationWithType(annotation, type.getRoot(), description);
}

private String buildAnnotationWithType(String annotation, Node type) {
return buildAnnotationWithType(annotation, type, null);
}

private String buildAnnotationWithType(String annotation, Node type, String description) {
StringBuilder sb = new StringBuilder();
sb.append("@");
sb.append(annotation);
sb.append(" {");
appendTypeNode(sb, type);
sb.append("}");
if (description != null) {
sb.append(" ");
sb.append(description);
}
return sb.toString();
}

private String buildParamType(String name, JSTypeExpression type) {
private String buildParamType(JSDocInfo info, String name) {
JSTypeExpression type = info.getParameterType(name);
if (type != null) {
return "{" + typeNode(type.getRoot()) + "} " + name;
String p =
"{"
+ typeNode(type.getRoot())
+ "} "
+ name
+ (printDesc && info.getDescriptionForParameter(name) != null
// Don't add a leading space; the parser retained it.
? info.getDescriptionForParameter(name)
: "");
return p.trim();
} else {
return name;
}
Expand Down
51 changes: 26 additions & 25 deletions test/com/google/javascript/jscomp/CodePrinterTest.java
Expand Up @@ -1790,7 +1790,7 @@ public void testReturnWithTypeAnnotation() {
lines(
"function f() {",
" return (/**",
" @return {number}",
" * @return {number}",
" */",
" function() {",
" return 42;",
Expand All @@ -1804,8 +1804,8 @@ public void testDeprecatedAnnotationIncludesNewline() {
String js =
LINE_JOINER.join(
"/**",
" @type {number}",
" @deprecated See {@link replacementClass} for more details.",
" * @type {number}",
" * @deprecated See {@link replacementClass} for more details.",
" */",
"var x;",
"");
Expand Down Expand Up @@ -2651,9 +2651,9 @@ public void testPreserveTypeAnnotations2() {

assertPrintSame(
LINE_JOINER.join(
"/**",
" @const",
" @suppress {const,duplicate}",
"/**", //
" * @const",
" * @suppress {const,duplicate}",
" */",
"var ns={}"));
}
Expand Down Expand Up @@ -3336,25 +3336,26 @@ public void testGoogScope() {
+ " alert(Quux.someProperty);\n"
+ "}\n"
+ "}); // goog.scope\n";
String expectedCode = ""
+ "/** @const */ var $jscomp = $jscomp || {};\n"
+ "/** @const */ $jscomp.scope = {};\n"
+ "/** @const */ var foo = {};\n"
+ "/** @const */ foo.bar = {};\n"
+ "goog.provide('foo.bar');\n"
+ "goog.require('baz.qux.Quux');\n"
+ "goog.require('foo.ScopedType');\n"
+ "/**\n"
+ " @param {ScopedType} obj\n"
+ " */\n"
+ "var fn = /**\n"
+ " @param {ScopedType} obj\n"
+ " */\n"
+ "function(obj) {\n"
+ " alert(STR);\n"
+ " alert(Quux.someProperty);\n"
+ "};\n"
+ "var STR = '3';\n";
String expectedCode =
""
+ "/** @const */ var $jscomp = $jscomp || {};\n"
+ "/** @const */ $jscomp.scope = {};\n"
+ "/** @const */ var foo = {};\n"
+ "/** @const */ foo.bar = {};\n"
+ "goog.provide('foo.bar');\n"
+ "goog.require('baz.qux.Quux');\n"
+ "goog.require('foo.ScopedType');\n"
+ "/**\n"
+ " * @param {ScopedType} obj\n"
+ " */\n"
+ "var fn = /**\n"
+ " * @param {ScopedType} obj\n"
+ " */\n"
+ "function(obj) {\n"
+ " alert(STR);\n"
+ " alert(Quux.someProperty);\n"
+ "};\n"
+ "var STR = '3';\n";

CompilerOptions compilerOptions = new CompilerOptions();
compilerOptions.setClosurePass(true);
Expand Down
8 changes: 4 additions & 4 deletions test/com/google/javascript/jscomp/ExternExportsPassTest.java
Expand Up @@ -1692,13 +1692,13 @@ public void testNamespaceDefinitionInExterns() {
"goog.exportSymbol('ns.subns.Foo', ns.subns.Foo);"),
lines(
"/**",
" @const",
" @suppress {const,duplicate}",
" * @const",
" * @suppress {const,duplicate}",
" */",
"var ns = {};",
"/**",
" @const",
" @suppress {const,duplicate}",
" * @const",
" * @suppress {const,duplicate}",
" */",
"ns.subns = {};",
"/**",
Expand Down

0 comments on commit ff42048

Please sign in to comment.