Skip to content

Commit 32d1878

Browse files
committed
Fixed handling class fields with declare keyword
Fixes #32
1 parent 4bdddf4 commit 32d1878

File tree

7 files changed

+79
-3
lines changed

7 files changed

+79
-3
lines changed

src/transformer.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
splitTransientSymbol,
1313
getClassOfMemberSymbol,
1414
hasDecorators,
15+
hasModifier,
1516
} from './typescript-helpers';
1617

1718
export interface RenameOptions {
@@ -452,6 +453,10 @@ function createTransformerFactory(program: ts.Program, options?: Partial<RenameO
452453
return putToCache(nodeSymbol, VisibilityType.External);
453454
}
454455

456+
if (symbolDeclarations.some((decl: ts.Declaration) => hasModifier(decl, ts.SyntaxKind.DeclareKeyword))) {
457+
return putToCache(nodeSymbol, VisibilityType.External);
458+
}
459+
455460
if (nodeSymbol.escapedName === 'prototype') {
456461
// accessing to prototype
457462
return putToCache(nodeSymbol, VisibilityType.External);

src/typescript-helpers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,6 @@ interface BreakingTypeScriptApi {
209209
getModifiers(node: ts.Node): readonly ts.Modifier[] | undefined;
210210
}
211211

212-
function isBreakingTypeScriptApi(compiler: unknown): compiler is BreakingTypeScriptApi {
213-
return 'canHaveDecorators' in ts;
212+
function isBreakingTypeScriptApi(compiler: object): compiler is BreakingTypeScriptApi {
213+
return 'canHaveDecorators' in compiler;
214214
}

tests/functional-test-cases.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,52 @@ function checkDiagnosticsErrors(diagnostics: readonly ts.Diagnostic[]): void {
6868
assert.strictEqual(diagnostics.length, 0, ts.formatDiagnostics(diagnostics, formatDiagnosticsHost).trim());
6969
}
7070

71+
const enum Constants {
72+
NoInputsWereFoundDiagnosticCode = 18003,
73+
}
74+
75+
const parseConfigHost: ts.ParseConfigHost = {
76+
useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames,
77+
readDirectory: ts.sys.readDirectory,
78+
fileExists: ts.sys.fileExists,
79+
readFile: ts.sys.readFile,
80+
};
81+
82+
function getCompilerOptions(configFileName: string): ts.CompilerOptions | null {
83+
if (!fs.existsSync(configFileName)) {
84+
return null;
85+
}
86+
87+
const configParseResult = ts.readConfigFile(configFileName, ts.sys.readFile);
88+
89+
checkDiagnosticsErrors(configParseResult.error !== undefined ? [configParseResult.error] : []);
90+
91+
const compilerOptionsParseResult = ts.parseJsonConfigFileContent(
92+
configParseResult.config,
93+
parseConfigHost,
94+
path.resolve(path.dirname(configFileName)),
95+
undefined,
96+
configFileName
97+
);
98+
99+
// we don't want to raise an error if no inputs found in a config file
100+
// because this error is mostly for CLI, but we'll pass an inputs in createProgram
101+
const diagnostics = compilerOptionsParseResult.errors
102+
.filter((d: ts.Diagnostic) => d.code !== Constants.NoInputsWereFoundDiagnosticCode);
103+
104+
checkDiagnosticsErrors(diagnostics);
105+
106+
return compilerOptionsParseResult.options;
107+
}
108+
71109
describe(`Functional tests for typescript v${ts.versionMajorMinor}`, () => {
72110
for (const testCase of getTestCases()) {
73111
it(testCase.name, () => {
74112
const program = ts.createProgram({
75113
rootNames: [testCase.inputFileName],
76114
options: {
77-
experimentalDecorators: true,
78115
target: ts.ScriptTarget.ES5,
116+
...getCompilerOptions(path.join(testCase.inputFileName, '..', 'tsconfig.json')),
79117
},
80118
});
81119

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"compilerOptions": {
3+
"experimentalDecorators": true
4+
}
5+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class Class {
2+
public declare publicField: number;
3+
protected declare protectedField: number;
4+
private declare privateField: number;
5+
6+
public method() {
7+
console.log(this.publicField, this.protectedField, this.privateField);
8+
}
9+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
var Class = /** @class */ (function () {
2+
function Class() {
3+
}
4+
Object.defineProperty(Class.prototype, "_internal_method", {
5+
enumerable: false,
6+
configurable: true,
7+
writable: true,
8+
value: function () {
9+
console.log(this.publicField, this.protectedField, this.privateField);
10+
}
11+
});
12+
return Class;
13+
}());
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es5",
4+
"useDefineForClassFields": true
5+
}
6+
}

0 commit comments

Comments
 (0)