Skip to content

Commit

Permalink
CLI: Several improvements to tsd-jsdoc emitted comments
Browse files Browse the repository at this point in the history
  • Loading branch information
dcodeIO committed Apr 17, 2017
1 parent ff85800 commit 2dcae25
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 294 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# [6.8.0](https://github.com/dcodeIO/protobuf.js/releases/tag/6.8.0)

## Breaking
[:hash:](https://github.com/dcodeIO/protobuf.js/commit/ff858003f525db542cbb270777b6fab3a230c9bb) Replaced Buffer and Long types with interfaces and removed stubs<br />
[:hash:](https://github.com/dcodeIO/protobuf.js/commit/22f907c49adbbdf09b72bde5299271dbe0ee9cbe) Removed Message#toObject in favor of having just the static version (unnecessary static code otherwise)<br />
[:hash:](https://github.com/dcodeIO/protobuf.js/commit/c97b61811248df002f1fb93557b982bc0aa27309) Everything uses interfaces now instead of typedefs (SomethingProperties is now ISomething)<br />
[:hash:](https://github.com/dcodeIO/protobuf.js/commit/b9f179064f3ddf683f13e0d4e17840301be64010) ReflectionObject#toJSON properly omits explicit undefined values<br />
[:hash:](https://github.com/dcodeIO/protobuf.js/commit/7a6f98b5e74f9e9142f9be3ba0683caeaff916c4) Initial implementation of TypeScript decorators<br />
Expand All @@ -19,6 +21,9 @@
[:hash:](https://github.com/dcodeIO/protobuf.js/commit/3939667ef1f37b025bd7f9476015890496d50e00) Added 'json' conversion option for proto3 JSON mapping compatibility of NaN and Infinity + additional documentation of util.toJSONOptions, see [#351](https://github.com/dcodeIO/protobuf.js/issues/351)<br />

## CLI
[:hash:](https://github.com/dcodeIO/protobuf.js/commit/ff858003f525db542cbb270777b6fab3a230c9bb) Further TypeScript definition improvements<br />
[:hash:](https://github.com/dcodeIO/protobuf.js/commit/22f907c49adbbdf09b72bde5299271dbe0ee9cbe) Relieved tsd files from unnecessary comments<br />
[:hash:](https://github.com/dcodeIO/protobuf.js/commit/22f907c49adbbdf09b72bde5299271dbe0ee9cbe) Generate TS namespaces for vars and functions with properties<br />
[:hash:](https://github.com/dcodeIO/protobuf.js/commit/b355115e619c6595ac9d91897cfe628ef0e46054) Prefer @tstype over @type when generating typedefs (tsd-jsdoc)<br />

## Docs
Expand All @@ -28,6 +33,7 @@
[:hash:](https://github.com/dcodeIO/protobuf.js/commit/35a663757efe188bea552aef017837bc6c6a481a) Additional docs on TS/decorators usage<br />

## Other
[:hash:](https://github.com/dcodeIO/protobuf.js/commit/22f907c49adbbdf09b72bde5299271dbe0ee9cbe) Regenerated dist files<br />
[:hash:](https://github.com/dcodeIO/protobuf.js/commit/5bc3541d2da19e2857dc884f743d37c27e8e21f2) Even more documentation and typings for ext/descriptor<br />
[:hash:](https://github.com/dcodeIO/protobuf.js/commit/773e6347b57e4a5236b1ef0bb8d361e4b233caf7) ext/descriptor docs<br />
[:hash:](https://github.com/dcodeIO/protobuf.js/commit/773e6347b57e4a5236b1ef0bb8d361e4b233caf7) Decorators coverage<br />
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ The npm package depends on [@types/node](https://www.npmjs.com/package/@types/no

#### Using the JS API

The API shown above works pretty much the same with TypeScript. However, because everything is typed, accessing fields on instances of dynamically generated message classes requires either (1) using bracket-notation (i.e. `message["awesomeField"]`), (2) explicit casts or (3) the use of a [typings file generated for its static counterpart](#pbts-for-typescript).
The API shown above works pretty much the same with TypeScript. However, because everything is typed, accessing fields on instances of dynamically generated message classes requires either using bracket-notation (i.e. `message["awesomeField"]`) or explicit casts. Alternatively, it is possible to use a [typings file generated for its static counterpart](#pbts-for-typescript).

```ts
import { load } from "protobufjs"; // respectively "./node_modules/protobufjs"
Expand Down Expand Up @@ -509,7 +509,7 @@ let decoded = AwesomeMessage.decode(buffer);

The library also includes an early implementation of [decorators](https://www.typescriptlang.org/docs/handbook/decorators.html).

**Note** that this API is rather new in protobuf.js (and probably buggy) and that decorators are an experimental feature in TypeScript. Also note that declaration order is important depending on the JS target. For example, `@Field.d(2, AwesomeArrayMessage)` requires that `AwesomeArrayMessage` has been defined earlier when targeting `ES5`.
**Note** that decorators are an experimental feature in TypeScript and that declaration order is important depending on the JS target. For example, `@Field.d(2, AwesomeArrayMessage)` requires that `AwesomeArrayMessage` has been defined earlier when targeting `ES5`.

```ts
import { Message, Type, Field, OneOf } from "protobufjs/light"; // respectively "./node_modules/protobufjs/light.js"
Expand Down
104 changes: 81 additions & 23 deletions cli/lib/tsd-jsdoc/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,38 @@ function writeln() {
indentWritten = false;
}

var skipTagsRe = /@(type|tstype|const|memberof|name|exports|interface|extends|implements|constructor|function|template|property|this|typedef|variation|example|returns \{undefined})[^@$]*/g,
skipTypeRe = /(@[^ ]+) \{[^\s$]+}/g;
var keepTags = [
"param",
"returns",
"throws",
"see"
];

// parses a comment into text and tags
function parseComment(comment) {
var lines = comment.replace(/^ *\/\*\* *|^ *\*\/| *\*\/ *$|^ *\* */mg, "").trim().split(/\r?\n/g);
var desc;
var text = [];
var tags = null;
for (var i = 0; i < lines.length; ++i) {
var match = /^@(\w+)\b/.exec(lines[i]);
if (match) {
if (!tags) {
tags = [];
desc = text;
}
text = [];
tags.push({ name: match[1], text: text });
lines[i] = lines[i].substring(match[1].length + 1).trim();
}
if (lines[i].length || text.length)
text.push(lines[i]);
}
return {
text: desc || text,
tags: tags || []
};
}

// writes a comment
function writeComment(comment, otherwiseNewline) {
Expand All @@ -144,26 +174,40 @@ function writeComment(comment, otherwiseNewline) {
writeln();
return;
}
comment = comment.replace(skipTagsRe, "").trim();
if (comment.charAt(comment.length - 1) !== "/")
comment += "/";
var lines = comment.split(/\r?\n/g);
if (lines.length === 3) {
writeln();
writeln("/*" + lines[1].trim() + " */");
} else {
var first = true;
lines.forEach(function(line) {
line = line.trim().replace(/^\*/, " *").replace(skipTypeRe, "$1");
if (line.length) {
if (first) {
writeln();
first = false;

if (typeof comment !== "object")
comment = parseComment(comment);
comment.tags = comment.tags.filter(function(tag) {
return keepTags.indexOf(tag.name) > -1 && (tag.name !== "returns" || tag.text[0] !== "{undefined}");
});
writeln();
if (!comment.tags.length && comment.text.length < 2) {
writeln("/** " + comment.text[0] + " */");
return;
}
writeln("/**");
comment.text.forEach(function(line) {
writeln(" * ", line);
});
comment.tags.forEach(function(tag) {
var started = false;
if (tag.text.length) {
tag.text.forEach(function(line, i) {
if (i > 0)
write(" * ");
else if (tag.name !== "throws")
line = line.replace(/^\{[^\s]*} ?/, "");
if (!line.length)
return;
if (!started) {
write(" * @", tag.name, " ");
started = true;
}
writeln(line);
}
});
}
});
}
});
writeln(" */");
}

// recursively replaces all occurencies of re's match
Expand All @@ -184,12 +228,17 @@ function replaceRecursive(name, re, fn) {

// tests if an element is considered to be a class or class-like
function isClassLike(element) {
return element && (element.kind === "class" || element.kind === "interface" || element.kind === "mixin");
return isClass(element) || isInterface(element);
}

// tests if an element is considered to be a class
function isClass(element) {
return element && element.kind === "class";
}

// tests if an element is considered to be an interface
function isInterface(element) {
return element && element.kind === "interface";
return element && (element.kind === "interface" || element.kind === "mixin");
}

// tests if an element is considered to be a namespace
Expand Down Expand Up @@ -254,7 +303,16 @@ function getTypeOf(element) {
// begins writing the definition of the specified element
function begin(element, is_interface) {
if (!seen[element.longname]) {
writeComment(element.comment, is_interface || isInterface(element) || isClassLike(element) || isNamespace(element) || element.isEnum || element.scope === "global");
if (isClass(element)) {
var comment = parseComment(element.comment);
var classdesc = comment.tags.find(function(tag) { return tag.name === "classdesc"; });
if (classdesc) {
comment.text = classdesc.text;
comment.tags = [];
}
writeComment(comment, true);
} else
writeComment(element.comment, is_interface || isClassLike(element) || isNamespace(element) || element.isEnum || element.scope === "global");
seen[element.longname] = element;
} else
writeln();
Expand Down
1 change: 1 addition & 0 deletions cli/targets/static.js
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ function buildType(ref, type) {
"Constructs a new " + type.name + ".",
type.comment ? "@classdesc " + type.comment : null,
"@constructor",
// "@extends $protobuf.Message<" + exportName(type) + ">",
"@param {" + exportName(type, true) + "=} [" + (config.beautify ? "properties" : "p") + "] Properties to set",
type.parent instanceof protobuf.Root ? "@name " + escapeName(type.name) : "@memberof " + exportName(type.parent)
]);
Expand Down
Loading

0 comments on commit 2dcae25

Please sign in to comment.