Skip to content

Commit 8590f0d

Browse files
authored
Fix decorator emit regression for static fields (microsoft#44933)
1 parent c0821ae commit 8590f0d

File tree

6 files changed

+48
-26
lines changed

6 files changed

+48
-26
lines changed

src/compiler/transformers/classFields.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -923,7 +923,7 @@ namespace ts {
923923
function getClassFacts(node: ClassLikeDeclaration) {
924924
let facts = ClassFacts.None;
925925
const original = getOriginalNode(node);
926-
if (isClassDeclaration(original) && some(original.decorators)) {
926+
if (isClassDeclaration(original) && classOrConstructorParameterIsDecorated(original)) {
927927
facts |= ClassFacts.ClassWasDecorated;
928928
}
929929
for (const member of node.members) {

src/compiler/transformers/ts.ts

+1-24
Original file line numberDiff line numberDiff line change
@@ -567,35 +567,12 @@ namespace ts {
567567
visitLexicalEnvironment(node.statements, sourceElementVisitor, context, /*start*/ 0, alwaysStrict));
568568
}
569569

570-
/**
571-
* Tests whether we should emit a __decorate call for a class declaration.
572-
*/
573-
function shouldEmitDecorateCallForClass(node: ClassDeclaration) {
574-
if (node.decorators && node.decorators.length > 0) {
575-
return true;
576-
}
577-
578-
const constructor = getFirstConstructorWithBody(node);
579-
if (constructor) {
580-
return forEach(constructor.parameters, shouldEmitDecorateCallForParameter);
581-
}
582-
583-
return false;
584-
}
585-
586-
/**
587-
* Tests whether we should emit a __decorate call for a parameter declaration.
588-
*/
589-
function shouldEmitDecorateCallForParameter(parameter: ParameterDeclaration) {
590-
return parameter.decorators !== undefined && parameter.decorators.length > 0;
591-
}
592-
593570
function getClassFacts(node: ClassDeclaration, staticProperties: readonly PropertyDeclaration[]) {
594571
let facts = ClassFacts.None;
595572
if (some(staticProperties)) facts |= ClassFacts.HasStaticInitializedProperties;
596573
const extendsClauseElement = getEffectiveBaseTypeNode(node);
597574
if (extendsClauseElement && skipOuterExpressions(extendsClauseElement.expression).kind !== SyntaxKind.NullKeyword) facts |= ClassFacts.IsDerivedClass;
598-
if (shouldEmitDecorateCallForClass(node)) facts |= ClassFacts.HasConstructorDecorators;
575+
if (classOrConstructorParameterIsDecorated(node)) facts |= ClassFacts.HasConstructorDecorators;
599576
if (childIsDecorated(node)) facts |= ClassFacts.HasMemberDecorators;
600577
if (isExportOfNamespace(node)) facts |= ClassFacts.IsExportOfNamespace;
601578
else if (isDefaultExternalModuleExport(node)) facts |= ClassFacts.IsDefaultExternalExport;

src/compiler/utilities.ts

+7
Original file line numberDiff line numberDiff line change
@@ -1868,12 +1868,19 @@ namespace ts {
18681868
return some((node as ClassDeclaration).members, m => nodeOrChildIsDecorated(m, node, parent!)); // TODO: GH#18217
18691869
case SyntaxKind.MethodDeclaration:
18701870
case SyntaxKind.SetAccessor:
1871+
case SyntaxKind.Constructor:
18711872
return some((node as FunctionLikeDeclaration).parameters, p => nodeIsDecorated(p, node, parent!)); // TODO: GH#18217
18721873
default:
18731874
return false;
18741875
}
18751876
}
18761877

1878+
export function classOrConstructorParameterIsDecorated(node: ClassDeclaration): boolean {
1879+
if (nodeIsDecorated(node)) return true;
1880+
const constructor = getFirstConstructorWithBody(node);
1881+
return !!constructor && childIsDecorated(constructor, node);
1882+
}
1883+
18771884
export function isJSXTagName(node: Node) {
18781885
const { parent } = node;
18791886
if (parent.kind === SyntaxKind.JsxOpeningElement ||

src/tsserver/nodeServer.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ namespace ts.server {
256256
/* eslint-enable no-restricted-globals */
257257

258258
if (typeof global !== "undefined" && global.gc) {
259-
sys.gc = () => global.gc!();
259+
sys.gc = () => global.gc?.();
260260
}
261261

262262
sys.require = (initialDir: string, moduleName: string): RequireResult => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//// [decoratorOnClassConstructorParameter5.ts]
2+
// https://github.com/microsoft/TypeScript/issues/44931
3+
interface IFoo { }
4+
declare const IFoo: any;
5+
class BulkEditPreviewProvider {
6+
static readonly Schema = 'vscode-bulkeditpreview';
7+
static emptyPreview = { scheme: BulkEditPreviewProvider.Schema };
8+
constructor(
9+
@IFoo private readonly _modeService: IFoo,
10+
) { }
11+
}
12+
13+
//// [decoratorOnClassConstructorParameter5.js]
14+
let BulkEditPreviewProvider = class BulkEditPreviewProvider {
15+
constructor(_modeService) {
16+
this._modeService = _modeService;
17+
}
18+
};
19+
BulkEditPreviewProvider.Schema = 'vscode-bulkeditpreview';
20+
BulkEditPreviewProvider.emptyPreview = { scheme: BulkEditPreviewProvider.Schema };
21+
BulkEditPreviewProvider = __decorate([
22+
__param(0, IFoo)
23+
], BulkEditPreviewProvider);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// @target: es2018
2+
// @experimentalDecorators: true
3+
// @noEmitHelpers: true
4+
// @noTypesAndSymbols: true
5+
6+
// https://github.com/microsoft/TypeScript/issues/44931
7+
interface IFoo { }
8+
declare const IFoo: any;
9+
class BulkEditPreviewProvider {
10+
static readonly Schema = 'vscode-bulkeditpreview';
11+
static emptyPreview = { scheme: BulkEditPreviewProvider.Schema };
12+
constructor(
13+
@IFoo private readonly _modeService: IFoo,
14+
) { }
15+
}

0 commit comments

Comments
 (0)