This commit is contained in:
Mark Probst 2018-02-12 19:39:11 -08:00
Родитель a839469367
Коммит 7fca47e143
5 изменённых файлов: 53 добавлений и 9 удалений

Просмотреть файл

@ -24,7 +24,14 @@ import { Sourcelike, sourcelikeToSource, serializeRenderResult } from "./Source"
import { trimEnd } from "lodash";
import { declarationsForGraph, DeclarationIR, cycleBreakerTypesForGraph, Declaration } from "./DeclarationIR";
import { TypeAttributeStoreView } from "./TypeGraph";
import { TypeAttributeKind, descriptionTypeAttributeKind } from "./TypeAttributes";
import { TypeAttributeKind, descriptionTypeAttributeKind, propertyDescriptionsTypeAttributeKind } from "./TypeAttributes";
function splitDescription(description: string | undefined): string[] | undefined {
if (description === undefined) return undefined;
description = description.trim();
if (description === "") return undefined;
return description.split("\n").map(l => l.trim());
}
export type ForbiddenWordsInfo = { names: (Name | string)[]; includeGlobalForbidden: boolean };
@ -136,10 +143,13 @@ export abstract class ConvenienceRenderer extends Renderer {
protected descriptionForType(t: Type): string[] | undefined {
let description = this.typeGraph.attributeStore.tryGet(descriptionTypeAttributeKind, t);
if (description === undefined) return undefined;
description = description.trim();
if (description === "") return undefined;
return description.split("\n").map(l => l.trim());
return splitDescription(description);
}
protected descriptionForClassProperty(c: ClassType, name: string): string[] | undefined {
const descriptions = this.typeGraph.attributeStore.tryGet(propertyDescriptionsTypeAttributeKind, c);
if (descriptions === undefined) return undefined;
return splitDescription(descriptions.get(name));
}
protected setUpNaming(): OrderedSet<Namespace> {

Просмотреть файл

@ -9,7 +9,7 @@ import { TypeGraphBuilder, TypeRef } from "./TypeBuilder";
import { TypeNames } from "./TypeNames";
import { unifyTypes } from "./UnifyClasses";
import { makeNamesTypeAttributes, modifyTypeNames, singularizeTypeNames } from "./TypeNames";
import { TypeAttributes, descriptionTypeAttributeKind } from "./TypeAttributes";
import { TypeAttributes, descriptionTypeAttributeKind, propertyDescriptionsTypeAttributeKind } from "./TypeAttributes";
enum PathElementKind {
Root,
@ -170,12 +170,25 @@ export function schemaToType(
function makeClass(path: Ref, attributes: TypeAttributes, properties: StringMap, requiredArray: string[]): TypeRef {
const required = Set(requiredArray);
const propertiesMap = Map(properties);
const propertyDescriptions = propertiesMap.map(propSchema => {
if (typeof propSchema === "object") {
const desc = propSchema.description;
if (typeof desc === "string") {
return desc;
}
}
return undefined;
}).filter(v => v !== undefined) as Map<string, string>;
if (!propertyDescriptions.isEmpty()) {
attributes = propertyDescriptionsTypeAttributeKind.setInAttributes(attributes, propertyDescriptions);
}
const result = typeBuilder.getUniqueClassType(attributes, true);
setTypeForPath(path, result);
// FIXME: We're using a Map instead of an OrderedMap here because we represent
// the JSON Schema as a JavaScript object, which has no map ordering. Ideally
// we would use a JSON parser that preserves order.
const props = Map(properties).map((propSchema, propName) => {
const props = propertiesMap.map((propSchema, propName) => {
const t = toType(
checkStringMap(propSchema),
path.push({ kind: PathElementKind.Property, name: propName }),

Просмотреть файл

@ -83,6 +83,11 @@ function isValueType(t: Type): boolean {
return primitiveValueTypeKinds.indexOf(kind) >= 0 || kind === "class" || kind === "enum";
}
function singleDescriptionComment(description: string[] | undefined): string {
if (description === undefined) return "";
return "// " + description.join("; ");
}
class GoRenderer extends ConvenienceRenderer {
private _topLevelUnmarshalNames = Map<Name, Name>();
@ -201,7 +206,8 @@ class GoRenderer extends ConvenienceRenderer {
let columns: Sourcelike[][] = [];
this.forEachClassProperty(c, "none", (name, jsonName, p) => {
const goType = this.goType(p.type, true);
columns.push([[name, " "], [goType, " "], ['`json:"', stringEscape(jsonName), '"`']]);
const comment = singleDescriptionComment(this.descriptionForClassProperty(c, jsonName));
columns.push([[name, " "], [goType, " "], ['`json:"', stringEscape(jsonName), '"`'], comment]);
});
this.emitDescription(this.descriptionForType(c));
this.emitStruct(className, columns);

Просмотреть файл

@ -65,4 +65,12 @@ export function combineTypeAttributes(attributeArray: TypeAttributes[]): TypeAtt
return first.mergeWith((aa, ab, kind) => kind.combine(aa, ab), ...rest);
}
export const descriptionTypeAttributeKind = new TypeAttributeKind<string>("description", undefined);
function combineDescriptions(a: string, b: string): string {
return a.trim() + "\n\n" + b.trim();
}
export const descriptionTypeAttributeKind = new TypeAttributeKind<string>("description", combineDescriptions);
export const propertyDescriptionsTypeAttributeKind = new TypeAttributeKind<Map<string, string>>(
"propertyDescriptions",
(a, b) => a.mergeWith(combineDescriptions, b)
);

Просмотреть файл

@ -10,6 +10,13 @@
"type": "string",
"enum": ["foo", "bar"],
"description": "An enumeration"
},
"foo": {
"type": "number"
},
"bar": {
"type": "boolean",
"description": "A pretty boolean"
}
},
"required": ["union", "enum"],