Skip to content

Commit 0c34883

Browse files
committed
Added ignoreDecorated option to ignore "decorated" fields and not to rename them
Fixes #31
1 parent c7d143a commit 0c34883

File tree

7 files changed

+87
-6
lines changed

7 files changed

+87
-6
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,13 @@ const colors: Record<string, string> = {
225225
// ...
226226
```
227227

228+
### ignoreDecorated
229+
230+
*Default: `false`*
231+
232+
Whether fields that were decorated should be renamed.
233+
A field is treated as "decorated" if itself or any its parent (on type level) has a decorator.
234+
228235
## How to use the custom transformer
229236

230237
Unfortunately, TypeScript itself does not currently provide any easy way to use custom transformers (see <https://github.com/Microsoft/TypeScript/issues/14419>).

src/transformer.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
isSymbolClassMember,
1212
splitTransientSymbol,
1313
getClassOfMemberSymbol,
14+
hasDecorators,
1415
} from './typescript-helpers';
1516

1617
export interface RenameOptions {
@@ -43,13 +44,20 @@ export interface RenameOptions {
4344
* @example ''
4445
*/
4546
publicJSDocTag: string;
47+
48+
/**
49+
* Whether fields that were decorated should be renamed.
50+
* A field is treated as "decorated" if itself or any its parent (on type level) has a decorator.
51+
*/
52+
ignoreDecorated: boolean;
4653
}
4754

4855
const defaultOptions: RenameOptions = {
4956
entrySourceFiles: [],
5057
privatePrefix: '_private_',
5158
internalPrefix: '_internal_',
5259
publicJSDocTag: 'public',
60+
ignoreDecorated: false,
5361
};
5462

5563
const enum VisibilityType {
@@ -444,20 +452,22 @@ function createTransformerFactory(program: ts.Program, options?: Partial<RenameO
444452
return putToCache(nodeSymbol, VisibilityType.External);
445453
}
446454

447-
if (isPrivateClassMember(nodeSymbol)) {
448-
return putToCache(nodeSymbol, VisibilityType.Private);
449-
}
450-
451455
if (nodeSymbol.escapedName === 'prototype') {
452456
// accessing to prototype
453457
return putToCache(nodeSymbol, VisibilityType.External);
454458
}
455459

456-
if (fullOptions.publicJSDocTag.length !== 0) {
460+
if (fullOptions.publicJSDocTag.length !== 0 || fullOptions.ignoreDecorated) {
457461
for (const declaration of symbolDeclarations) {
458462
let currentNode: ts.Node = declaration;
459463
while (!ts.isSourceFile(currentNode)) {
460-
if (getNodeJSDocComment(currentNode).includes(`@${fullOptions.publicJSDocTag}`)) {
464+
if (fullOptions.publicJSDocTag.length !== 0
465+
&& getNodeJSDocComment(currentNode).includes(`@${fullOptions.publicJSDocTag}`)
466+
) {
467+
return putToCache(nodeSymbol, VisibilityType.External);
468+
}
469+
470+
if (fullOptions.ignoreDecorated && hasDecorators(currentNode)) {
461471
return putToCache(nodeSymbol, VisibilityType.External);
462472
}
463473

@@ -466,6 +476,10 @@ function createTransformerFactory(program: ts.Program, options?: Partial<RenameO
466476
}
467477
}
468478

479+
if (isPrivateClassMember(nodeSymbol)) {
480+
return putToCache(nodeSymbol, VisibilityType.Private);
481+
}
482+
469483
if (exportsSymbolTree.isSymbolAccessibleFromExports(nodeSymbol)) {
470484
return putToCache(nodeSymbol, VisibilityType.External);
471485
}

src/typescript-helpers.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,23 @@ export function hasModifier(node: ts.Node, modifier: ts.SyntaxKind): boolean {
145145
return getModifiers(node).some(mod => mod.kind === modifier);
146146
}
147147

148+
function getDecorators(node: ts.Node): readonly unknown[] {
149+
if (isBreakingTypeScriptApi(ts)) {
150+
if (!ts.canHaveDecorators(node)) {
151+
return [];
152+
}
153+
154+
return ts.getDecorators(node) || [];
155+
}
156+
157+
// eslint-disable-next-line deprecation/deprecation
158+
return node.decorators || [];
159+
}
160+
161+
export function hasDecorators(node: ts.Node): boolean {
162+
return getDecorators(node).length !== 0;
163+
}
164+
148165
export function isConstructorParameter(node: ts.Node): node is ts.ParameterDeclaration {
149166
return ts.isParameter(node) &&
150167
ts.isConstructorDeclaration(node.parent as ts.Node) &&

tests/functional-test-cases.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ describe(`Functional tests for typescript v${ts.versionMajorMinor}`, () => {
7474
const program = ts.createProgram({
7575
rootNames: [testCase.inputFileName],
7676
options: {
77+
experimentalDecorators: true,
7778
target: ts.ScriptTarget.ES5,
7879
},
7980
});
@@ -89,6 +90,7 @@ describe(`Functional tests for typescript v${ts.versionMajorMinor}`, () => {
8990
privatePrefix: '_private_',
9091
internalPrefix: '_internal_',
9192
publicJSDocTag: 'public',
93+
ignoreDecorated: true,
9294
}
9395
);
9496

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
declare const foo: any;
2+
3+
class Foo {
4+
@foo private field = 1;
5+
}
6+
7+
@foo
8+
class Foo2 {
9+
private field = 1;
10+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5+
return c > 3 && r && Object.defineProperty(target, key, r), r;
6+
};
7+
var Foo = /** @class */ (function () {
8+
function Foo() {
9+
this.field = 1;
10+
}
11+
__decorate([
12+
foo
13+
], Foo.prototype, "field", void 0);
14+
return Foo;
15+
}());
16+
var Foo2 = /** @class */ (function () {
17+
function Foo2() {
18+
this.field = 1;
19+
}
20+
Foo2 = __decorate([
21+
foo
22+
], Foo2);
23+
return Foo2;
24+
}());

tests/test-cases/tsconfig.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "../../tsconfig.base.json",
3+
"compilerOptions": {
4+
"noUnusedLocals": false,
5+
"experimentalDecorators": true
6+
}
7+
}

0 commit comments

Comments
 (0)