Skip to content

Commit

Permalink
Fixed handling class fields with declare keyword
Browse files Browse the repository at this point in the history
Fixes #32
  • Loading branch information
timocov committed Mar 29, 2023
1 parent 4bdddf4 commit 32d1878
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 3 deletions.
5 changes: 5 additions & 0 deletions src/transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
splitTransientSymbol,
getClassOfMemberSymbol,
hasDecorators,
hasModifier,
} from './typescript-helpers';

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

if (symbolDeclarations.some((decl: ts.Declaration) => hasModifier(decl, ts.SyntaxKind.DeclareKeyword))) {
return putToCache(nodeSymbol, VisibilityType.External);
}

if (nodeSymbol.escapedName === 'prototype') {
// accessing to prototype
return putToCache(nodeSymbol, VisibilityType.External);
Expand Down
4 changes: 2 additions & 2 deletions src/typescript-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,6 @@ interface BreakingTypeScriptApi {
getModifiers(node: ts.Node): readonly ts.Modifier[] | undefined;
}

function isBreakingTypeScriptApi(compiler: unknown): compiler is BreakingTypeScriptApi {
return 'canHaveDecorators' in ts;
function isBreakingTypeScriptApi(compiler: object): compiler is BreakingTypeScriptApi {
return 'canHaveDecorators' in compiler;
}
40 changes: 39 additions & 1 deletion tests/functional-test-cases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,52 @@ function checkDiagnosticsErrors(diagnostics: readonly ts.Diagnostic[]): void {
assert.strictEqual(diagnostics.length, 0, ts.formatDiagnostics(diagnostics, formatDiagnosticsHost).trim());
}

const enum Constants {
NoInputsWereFoundDiagnosticCode = 18003,
}

const parseConfigHost: ts.ParseConfigHost = {
useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames,
readDirectory: ts.sys.readDirectory,
fileExists: ts.sys.fileExists,
readFile: ts.sys.readFile,
};

function getCompilerOptions(configFileName: string): ts.CompilerOptions | null {
if (!fs.existsSync(configFileName)) {
return null;
}

const configParseResult = ts.readConfigFile(configFileName, ts.sys.readFile);

checkDiagnosticsErrors(configParseResult.error !== undefined ? [configParseResult.error] : []);

const compilerOptionsParseResult = ts.parseJsonConfigFileContent(
configParseResult.config,
parseConfigHost,
path.resolve(path.dirname(configFileName)),
undefined,
configFileName
);

// we don't want to raise an error if no inputs found in a config file
// because this error is mostly for CLI, but we'll pass an inputs in createProgram
const diagnostics = compilerOptionsParseResult.errors
.filter((d: ts.Diagnostic) => d.code !== Constants.NoInputsWereFoundDiagnosticCode);

checkDiagnosticsErrors(diagnostics);

return compilerOptionsParseResult.options;
}

describe(`Functional tests for typescript v${ts.versionMajorMinor}`, () => {
for (const testCase of getTestCases()) {
it(testCase.name, () => {
const program = ts.createProgram({
rootNames: [testCase.inputFileName],
options: {
experimentalDecorators: true,
target: ts.ScriptTarget.ES5,
...getCompilerOptions(path.join(testCase.inputFileName, '..', 'tsconfig.json')),
},
});

Expand Down
5 changes: 5 additions & 0 deletions tests/test-cases/decorators/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"experimentalDecorators": true
}
}
9 changes: 9 additions & 0 deletions tests/test-cases/useDefineForClassFields-and-declare/input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Class {
public declare publicField: number;
protected declare protectedField: number;
private declare privateField: number;

public method() {
console.log(this.publicField, this.protectedField, this.privateField);
}
}
13 changes: 13 additions & 0 deletions tests/test-cases/useDefineForClassFields-and-declare/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
var Class = /** @class */ (function () {
function Class() {
}
Object.defineProperty(Class.prototype, "_internal_method", {
enumerable: false,
configurable: true,
writable: true,
value: function () {
console.log(this.publicField, this.protectedField, this.privateField);
}
});
return Class;
}());
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"target": "es5",
"useDefineForClassFields": true
}
}

0 comments on commit 32d1878

Please sign in to comment.