From 060a098f85002defc0f231c07c1b9589162ded5c Mon Sep 17 00:00:00 2001 From: makana Date: Fri, 13 Oct 2017 10:23:41 +0200 Subject: [PATCH 1/2] Added Readonly flag, moved Abstract flag assignment to declaration factory - Added a reflection flag for readonly properties - Moved the abstract flag assignment to declaration factory, fixes the issue that abstract accessors were not considered before --- src/lib/converter/factories/declaration.ts | 2 + src/lib/converter/nodes/class.ts | 6 +- src/lib/converter/nodes/function.ts | 9 +- src/lib/converter/nodes/variable.ts | 15 +- src/lib/models/reflections/abstract.ts | 20 +- src/test/converter/class/class.ts | 12 + src/test/converter/class/specs.json | 172 +++++++++++- .../constructor-properties/specs.json | 6 +- .../specs/classes/_classes_.genericclass.html | 2 +- .../classes/_classes_.nongenericclass.html | 2 +- .../renderer/specs/modules/_variables_.html | 262 ++++++++++++++++++ 11 files changed, 466 insertions(+), 42 deletions(-) create mode 100644 src/test/renderer/specs/modules/_variables_.html diff --git a/src/lib/converter/factories/declaration.ts b/src/lib/converter/factories/declaration.ts index 690ed0194..d06e7c99d 100644 --- a/src/lib/converter/factories/declaration.ts +++ b/src/lib/converter/factories/declaration.ts @@ -134,6 +134,8 @@ function setupDeclaration(context: Context, reflection: DeclarationReflection, n reflection.setFlag(ReflectionFlag.Protected, !!(modifiers & ts.ModifierFlags.Protected)); reflection.setFlag(ReflectionFlag.Public, !!(modifiers & ts.ModifierFlags.Public)); reflection.setFlag(ReflectionFlag.Optional, !!(node['questionToken'])); + reflection.setFlag(ReflectionFlag.Abstract, !!(modifiers & ts.ModifierFlags.Abstract)); + reflection.setFlag(ReflectionFlag.Readonly, !!(modifiers & ts.ModifierFlags.Readonly)); if ( context.isInherit && diff --git a/src/lib/converter/nodes/class.ts b/src/lib/converter/nodes/class.ts index 30a092f99..6e08fa96c 100644 --- a/src/lib/converter/nodes/class.ts +++ b/src/lib/converter/nodes/class.ts @@ -1,7 +1,7 @@ import * as ts from 'typescript'; import * as _ts from '../../ts-internal'; -import { Reflection, ReflectionFlag, ReflectionKind, DeclarationReflection } from '../../models/index'; +import { Reflection, ReflectionKind, DeclarationReflection } from '../../models/index'; import { createDeclaration } from '../factories/index'; import { Context } from '../context'; import { Component, ConverterNodeComponent } from '../components'; @@ -29,10 +29,6 @@ export class ClassConverter extends ConverterNodeComponent reflection = context.scope; } else { reflection = createDeclaration(context, node, ReflectionKind.Class); - // set possible abstract flag here, where node is not the inherited parent - if (node.modifiers && node.modifiers.some( m => m.kind === ts.SyntaxKind.AbstractKeyword )) { - reflection.setFlag(ReflectionFlag.Abstract, true); - } } context.withScope(reflection, node.typeParameters, () => { diff --git a/src/lib/converter/nodes/function.ts b/src/lib/converter/nodes/function.ts index e651c35d1..1b47ee478 100644 --- a/src/lib/converter/nodes/function.ts +++ b/src/lib/converter/nodes/function.ts @@ -1,6 +1,6 @@ import * as ts from 'typescript'; -import { Reflection, ReflectionFlag, ReflectionKind } from '../../models/index'; +import { Reflection, ReflectionKind } from '../../models/index'; import { createDeclaration, createSignature } from '../factories/index'; import { Context } from '../context'; import { Converter } from '../converter'; @@ -30,13 +30,6 @@ export class FunctionConverter extends ConverterNodeComponent node, kind); - if (method // child inheriting will return null on createDeclaration - && kind & ReflectionKind.Method - && node.modifiers - && node.modifiers.some( m => m.kind === ts.SyntaxKind.AbstractKeyword )) { - method.setFlag(ReflectionFlag.Abstract, true); - } - context.withScope(method, () => { if (!hasBody || !method.signatures) { const signature = createSignature(context, node, method.name, ReflectionKind.CallSignature); diff --git a/src/lib/converter/nodes/variable.ts b/src/lib/converter/nodes/variable.ts index 76b6feed4..57b7cc2a2 100644 --- a/src/lib/converter/nodes/variable.ts +++ b/src/lib/converter/nodes/variable.ts @@ -62,24 +62,15 @@ export class VariableConverter extends ConverterNodeComponent { + if (kind === ReflectionKind.Variable && node.parent) { if (node.parent.flags & ts.NodeFlags.Const) { variable.setFlag(ReflectionFlag.Const, true); } else if (node.parent.flags & ts.NodeFlags.Let) { variable.setFlag(ReflectionFlag.Let, true); } - break; - case ReflectionKind.Property: - if (variable // child inheriting will return null on createDeclaration - && node.modifiers - && node.modifiers.some( m => m.kind === ts.SyntaxKind.AbstractKeyword )) { - variable.setFlag(ReflectionFlag.Abstract, true); - } - break; - } + } - context.withScope(variable, () => { if (node.initializer) { switch (node.initializer.kind) { case ts.SyntaxKind.ArrowFunction: diff --git a/src/lib/models/reflections/abstract.ts b/src/lib/models/reflections/abstract.ts index 277d97776..5453f5dcf 100644 --- a/src/lib/models/reflections/abstract.ts +++ b/src/lib/models/reflections/abstract.ts @@ -79,7 +79,8 @@ export enum ReflectionFlag { ConstructorProperty = 1024, Abstract = 2048, Const = 4096, - Let = 8192 + Let = 8192, + Readonly = 16384 } const relevantFlags: ReflectionFlag[] = [ @@ -92,7 +93,8 @@ const relevantFlags: ReflectionFlag[] = [ ReflectionFlag.Rest, ReflectionFlag.Abstract, ReflectionFlag.Let, - ReflectionFlag.Const + ReflectionFlag.Const, + ReflectionFlag.Readonly ]; export interface ReflectionFlags extends Array { @@ -152,6 +154,11 @@ export interface ReflectionFlags extends Array { isConst?: boolean; isLet?: boolean; + + /** + * Is this a readonly property? + */ + isReadonly?: boolean; } export interface DefaultValueContainer extends Reflection { @@ -422,9 +429,18 @@ export abstract class Reflection { break; case ReflectionFlag.Let: this.flags.isLet = value; + if (value) { + this.setFlag(ReflectionFlag.Const, false); + } break; case ReflectionFlag.Const: this.flags.isConst = value; + if (value) { + this.setFlag(ReflectionFlag.Let, false); + } + break; + case ReflectionFlag.Readonly: + this.flags.isReadonly = value; break; } } diff --git a/src/test/converter/class/class.ts b/src/test/converter/class/class.ts index c315d3882..61518bc3c 100644 --- a/src/test/converter/class/class.ts +++ b/src/test/converter/class/class.ts @@ -80,10 +80,22 @@ export abstract class TestAbstractClass { abstract myAbstractProperty: string; protected abstract myAbstractMethod(): void; + + abstract get myAbstractAccessor(): number; + abstract set myAbstractAccessor(value: number); } export class TestAbstractClassImplementation extends TestAbstractClass { myAbstractProperty: string; protected myAbstractMethod(): void { } + + get myAbstractAccessor(): number + { + return 1; + } + set myAbstractAccessor(value: number) + { + + } } \ No newline at end of file diff --git a/src/test/converter/class/specs.json b/src/test/converter/class/specs.json index d8d9ce427..5a9c3c3fc 100644 --- a/src/test/converter/class/specs.json +++ b/src/test/converter/class/specs.json @@ -45,6 +45,67 @@ "name": "string" } }, + { + "id": 38, + "name": "myAbstractAccessor", + "kind": 262144, + "kindString": "Accessor", + "flags": { + "isExported": true, + "isAbstract": true + }, + "getSignature": [ + { + "id": 39, + "name": "__get", + "kind": 524288, + "kindString": "Get signature", + "flags": {}, + "type": { + "type": "intrinsic", + "name": "number" + } + } + ], + "setSignature": [ + { + "id": 40, + "name": "__set", + "kind": 1048576, + "kindString": "Set signature", + "flags": {}, + "parameters": [ + { + "id": 41, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "type": { + "type": "intrinsic", + "name": "number" + } + } + ], + "type": { + "type": "intrinsic", + "name": "any" + } + } + ], + "sources": [ + { + "fileName": "class.ts", + "line": 84, + "character": 35 + }, + { + "fileName": "class.ts", + "line": 85, + "character": 35 + } + ] + }, { "id": 36, "name": "myAbstractMethod", @@ -85,6 +146,13 @@ 35 ] }, + { + "title": "Accessors", + "kind": 262144, + "children": [ + 38 + ] + }, { "title": "Methods", "kind": 2048, @@ -104,12 +172,12 @@ { "type": "reference", "name": "TestAbstractClassImplementation", - "id": 38 + "id": 42 } ] }, { - "id": 38, + "id": 42, "name": "TestAbstractClassImplementation", "kind": 128, "kindString": "Class", @@ -118,7 +186,7 @@ }, "children": [ { - "id": 39, + "id": 43, "name": "myAbstractProperty", "kind": 1024, "kindString": "Property", @@ -128,7 +196,7 @@ "sources": [ { "fileName": "class.ts", - "line": 86, + "line": 89, "character": 22 } ], @@ -143,7 +211,82 @@ } }, { - "id": 40, + "id": 46, + "name": "myAbstractAccessor", + "kind": 262144, + "kindString": "Accessor", + "flags": { + "isExported": true + }, + "getSignature": [ + { + "id": 47, + "name": "__get", + "kind": 524288, + "kindString": "Get signature", + "flags": {}, + "type": { + "type": "intrinsic", + "name": "number" + }, + "overwrites": { + "type": "reference", + "name": "TestAbstractClass.myAbstractAccessor", + "id": 38 + } + } + ], + "setSignature": [ + { + "id": 48, + "name": "__set", + "kind": 1048576, + "kindString": "Set signature", + "flags": {}, + "parameters": [ + { + "id": 49, + "name": "value", + "kind": 32768, + "kindString": "Parameter", + "flags": {}, + "type": { + "type": "intrinsic", + "name": "number" + } + } + ], + "type": { + "type": "intrinsic", + "name": "void" + }, + "overwrites": { + "type": "reference", + "name": "TestAbstractClass.myAbstractAccessor", + "id": 38 + } + } + ], + "sources": [ + { + "fileName": "class.ts", + "line": 93, + "character": 26 + }, + { + "fileName": "class.ts", + "line": 97, + "character": 26 + } + ], + "overwrites": { + "type": "reference", + "name": "TestAbstractClass.myAbstractAccessor", + "id": 38 + } + }, + { + "id": 44, "name": "myAbstractMethod", "kind": 2048, "kindString": "Method", @@ -153,7 +296,7 @@ }, "signatures": [ { - "id": 41, + "id": 45, "name": "myAbstractMethod", "kind": 4096, "kindString": "Call signature", @@ -172,7 +315,7 @@ "sources": [ { "fileName": "class.ts", - "line": 88, + "line": 91, "character": 30 } ], @@ -188,21 +331,28 @@ "title": "Properties", "kind": 1024, "children": [ - 39 + 43 + ] + }, + { + "title": "Accessors", + "kind": 262144, + "children": [ + 46 ] }, { "title": "Methods", "kind": 2048, "children": [ - 40 + 44 ] } ], "sources": [ { "fileName": "class.ts", - "line": 85, + "line": 88, "character": 44 } ], @@ -949,7 +1099,7 @@ "kind": 128, "children": [ 34, - 38, + 42, 2, 16 ] diff --git a/src/test/converter/constructor-properties/specs.json b/src/test/converter/constructor-properties/specs.json index 100275466..d8ac389dd 100644 --- a/src/test/converter/constructor-properties/specs.json +++ b/src/test/converter/constructor-properties/specs.json @@ -104,7 +104,8 @@ "kind": 1024, "kindString": "Property", "flags": { - "isConstructorProperty": true + "isConstructorProperty": true, + "isReadonly": true }, "comment": { "shortText": "Vector name\n" @@ -317,7 +318,8 @@ "kind": 1024, "kindString": "Property", "flags": { - "isConstructorProperty": true + "isConstructorProperty": true, + "isReadonly": true }, "comment": { "shortText": "Vector name\n" diff --git a/src/test/renderer/specs/classes/_classes_.genericclass.html b/src/test/renderer/specs/classes/_classes_.genericclass.html index b9047df25..8f2143284 100644 --- a/src/test/renderer/specs/classes/_classes_.genericclass.html +++ b/src/test/renderer/specs/classes/_classes_.genericclass.html @@ -249,7 +249,7 @@

Private p4

-

p5

+

Readonly p5

p5: string
-

p5

+

Readonly p5

p5: string