Skip to content

Commit b8c8dbc

Browse files
committed
Merge pull request #4386 from Microsoft/importDeclarationAndDecorator
Resolve the decorator type as type and check if the symbol has value.
2 parents 1ca28b7 + 2defe94 commit b8c8dbc

File tree

34 files changed

+1377
-3
lines changed

34 files changed

+1377
-3
lines changed

src/compiler/checker.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11384,9 +11384,16 @@ namespace ts {
1138411384
// serialize the type metadata.
1138511385
if (node && node.kind === SyntaxKind.TypeReference) {
1138611386
let root = getFirstIdentifier((<TypeReferenceNode>node).typeName);
11387-
let rootSymbol = resolveName(root, root.text, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
11388-
if (rootSymbol && rootSymbol.flags & SymbolFlags.Alias && !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) {
11389-
markAliasSymbolAsReferenced(rootSymbol);
11387+
let meaning = root.parent.kind === SyntaxKind.TypeReference ? SymbolFlags.Type : SymbolFlags.Namespace;
11388+
// Resolve type so we know which symbol is referenced
11389+
let rootSymbol = resolveName(root, root.text, meaning | SymbolFlags.Alias, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined);
11390+
// Resolved symbol is alias
11391+
if (rootSymbol && rootSymbol.flags & SymbolFlags.Alias) {
11392+
let aliasTarget = resolveAlias(rootSymbol);
11393+
// If alias has value symbol - mark alias as referenced
11394+
if (aliasTarget.flags & SymbolFlags.Value && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) {
11395+
markAliasSymbolAsReferenced(rootSymbol);
11396+
}
1139011397
}
1139111398
}
1139211399
}
@@ -14402,6 +14409,10 @@ namespace ts {
1440214409

1440314410
// Resolve the symbol as a type so that we can provide a more useful hint for the type serializer.
1440414411
let typeSymbol = resolveEntityName(typeName, SymbolFlags.Type, /*ignoreErrors*/ true);
14412+
// We might not be able to resolve type symbol so use unknown type in that case (eg error case)
14413+
if (!typeSymbol) {
14414+
return TypeReferenceSerializationKind.ObjectType;
14415+
}
1440514416
let type = getDeclaredTypeOfSymbol(typeSymbol);
1440614417
if (type === unknownType) {
1440714418
return TypeReferenceSerializationKind.Unknown;

src/compiler/emitter.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,6 +1552,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
15521552
else if (isNameOfNestedRedeclaration(node)) {
15531553
write(getGeneratedNameForNode(node));
15541554
}
1555+
else if (nodeIsSynthesized(node)) {
1556+
write(node.text);
1557+
}
15551558
else {
15561559
writeTextOfNode(currentSourceFile, node);
15571560
}

tests/baselines/reference/decoratorMetadata.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
3434
var __metadata = (this && this.__metadata) || function (k, v) {
3535
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
3636
};
37+
var service_1 = require("./service");
3738
var MyComponent = (function () {
3839
function MyComponent(Service) {
3940
this.Service = Service;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//// [tests/cases/compiler/decoratorMetadataWithImportDeclarationNameCollision.ts] ////
2+
3+
//// [db.ts]
4+
export class db {
5+
public doSomething() {
6+
}
7+
}
8+
9+
//// [service.ts]
10+
import {db} from './db';
11+
function someDecorator(target) {
12+
return target;
13+
}
14+
@someDecorator
15+
class MyClass {
16+
db: db;
17+
18+
constructor(db: db) {
19+
this.db = db;
20+
this.db.doSomething();
21+
}
22+
}
23+
export {MyClass};
24+
25+
26+
//// [db.js]
27+
var db = (function () {
28+
function db() {
29+
}
30+
db.prototype.doSomething = function () {
31+
};
32+
return db;
33+
})();
34+
exports.db = db;
35+
//// [service.js]
36+
var db_1 = require('./db');
37+
function someDecorator(target) {
38+
return target;
39+
}
40+
var MyClass = (function () {
41+
function MyClass(db) {
42+
this.db = db;
43+
this.db.doSomething();
44+
}
45+
MyClass = __decorate([
46+
someDecorator,
47+
__metadata('design:paramtypes', [db_1.db])
48+
], MyClass);
49+
return MyClass;
50+
})();
51+
exports.MyClass = MyClass;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
=== tests/cases/compiler/db.ts ===
2+
export class db {
3+
>db : Symbol(db, Decl(db.ts, 0, 0))
4+
5+
public doSomething() {
6+
>doSomething : Symbol(doSomething, Decl(db.ts, 0, 17))
7+
}
8+
}
9+
10+
=== tests/cases/compiler/service.ts ===
11+
import {db} from './db';
12+
>db : Symbol(db, Decl(service.ts, 0, 8))
13+
14+
function someDecorator(target) {
15+
>someDecorator : Symbol(someDecorator, Decl(service.ts, 0, 24))
16+
>target : Symbol(target, Decl(service.ts, 1, 23))
17+
18+
return target;
19+
>target : Symbol(target, Decl(service.ts, 1, 23))
20+
}
21+
@someDecorator
22+
>someDecorator : Symbol(someDecorator, Decl(service.ts, 0, 24))
23+
24+
class MyClass {
25+
>MyClass : Symbol(MyClass, Decl(service.ts, 3, 1))
26+
27+
db: db;
28+
>db : Symbol(db, Decl(service.ts, 5, 15))
29+
>db : Symbol(db, Decl(service.ts, 0, 8))
30+
31+
constructor(db: db) {
32+
>db : Symbol(db, Decl(service.ts, 8, 16))
33+
>db : Symbol(db, Decl(service.ts, 0, 8))
34+
35+
this.db = db;
36+
>this.db : Symbol(db, Decl(service.ts, 5, 15))
37+
>this : Symbol(MyClass, Decl(service.ts, 3, 1))
38+
>db : Symbol(db, Decl(service.ts, 5, 15))
39+
>db : Symbol(db, Decl(service.ts, 8, 16))
40+
41+
this.db.doSomething();
42+
>this.db.doSomething : Symbol(db.doSomething, Decl(db.ts, 0, 17))
43+
>this.db : Symbol(db, Decl(service.ts, 5, 15))
44+
>this : Symbol(MyClass, Decl(service.ts, 3, 1))
45+
>db : Symbol(db, Decl(service.ts, 5, 15))
46+
>doSomething : Symbol(db.doSomething, Decl(db.ts, 0, 17))
47+
}
48+
}
49+
export {MyClass};
50+
>MyClass : Symbol(MyClass, Decl(service.ts, 13, 8))
51+
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
=== tests/cases/compiler/db.ts ===
2+
export class db {
3+
>db : db
4+
5+
public doSomething() {
6+
>doSomething : () => void
7+
}
8+
}
9+
10+
=== tests/cases/compiler/service.ts ===
11+
import {db} from './db';
12+
>db : typeof db
13+
14+
function someDecorator(target) {
15+
>someDecorator : (target: any) => any
16+
>target : any
17+
18+
return target;
19+
>target : any
20+
}
21+
@someDecorator
22+
>someDecorator : (target: any) => any
23+
24+
class MyClass {
25+
>MyClass : MyClass
26+
27+
db: db;
28+
>db : db
29+
>db : db
30+
31+
constructor(db: db) {
32+
>db : db
33+
>db : db
34+
35+
this.db = db;
36+
>this.db = db : db
37+
>this.db : db
38+
>this : MyClass
39+
>db : db
40+
>db : db
41+
42+
this.db.doSomething();
43+
>this.db.doSomething() : void
44+
>this.db.doSomething : () => void
45+
>this.db : db
46+
>this : MyClass
47+
>db : db
48+
>doSomething : () => void
49+
}
50+
}
51+
export {MyClass};
52+
>MyClass : typeof MyClass
53+
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//// [tests/cases/compiler/decoratorMetadataWithImportDeclarationNameCollision2.ts] ////
2+
3+
//// [db.ts]
4+
export class db {
5+
public doSomething() {
6+
}
7+
}
8+
9+
//// [service.ts]
10+
import {db as Database} from './db';
11+
function someDecorator(target) {
12+
return target;
13+
}
14+
@someDecorator
15+
class MyClass {
16+
db: Database;
17+
18+
constructor(db: Database) { // no collision
19+
this.db = db;
20+
this.db.doSomething();
21+
}
22+
}
23+
export {MyClass};
24+
25+
26+
//// [db.js]
27+
var db = (function () {
28+
function db() {
29+
}
30+
db.prototype.doSomething = function () {
31+
};
32+
return db;
33+
})();
34+
exports.db = db;
35+
//// [service.js]
36+
var db_1 = require('./db');
37+
function someDecorator(target) {
38+
return target;
39+
}
40+
var MyClass = (function () {
41+
function MyClass(db) {
42+
this.db = db;
43+
this.db.doSomething();
44+
}
45+
MyClass = __decorate([
46+
someDecorator,
47+
__metadata('design:paramtypes', [db_1.db])
48+
], MyClass);
49+
return MyClass;
50+
})();
51+
exports.MyClass = MyClass;
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
=== tests/cases/compiler/db.ts ===
2+
export class db {
3+
>db : Symbol(db, Decl(db.ts, 0, 0))
4+
5+
public doSomething() {
6+
>doSomething : Symbol(doSomething, Decl(db.ts, 0, 17))
7+
}
8+
}
9+
10+
=== tests/cases/compiler/service.ts ===
11+
import {db as Database} from './db';
12+
>db : Symbol(Database, Decl(service.ts, 0, 8))
13+
>Database : Symbol(Database, Decl(service.ts, 0, 8))
14+
15+
function someDecorator(target) {
16+
>someDecorator : Symbol(someDecorator, Decl(service.ts, 0, 36))
17+
>target : Symbol(target, Decl(service.ts, 1, 23))
18+
19+
return target;
20+
>target : Symbol(target, Decl(service.ts, 1, 23))
21+
}
22+
@someDecorator
23+
>someDecorator : Symbol(someDecorator, Decl(service.ts, 0, 36))
24+
25+
class MyClass {
26+
>MyClass : Symbol(MyClass, Decl(service.ts, 3, 1))
27+
28+
db: Database;
29+
>db : Symbol(db, Decl(service.ts, 5, 15))
30+
>Database : Symbol(Database, Decl(service.ts, 0, 8))
31+
32+
constructor(db: Database) { // no collision
33+
>db : Symbol(db, Decl(service.ts, 8, 16))
34+
>Database : Symbol(Database, Decl(service.ts, 0, 8))
35+
36+
this.db = db;
37+
>this.db : Symbol(db, Decl(service.ts, 5, 15))
38+
>this : Symbol(MyClass, Decl(service.ts, 3, 1))
39+
>db : Symbol(db, Decl(service.ts, 5, 15))
40+
>db : Symbol(db, Decl(service.ts, 8, 16))
41+
42+
this.db.doSomething();
43+
>this.db.doSomething : Symbol(Database.doSomething, Decl(db.ts, 0, 17))
44+
>this.db : Symbol(db, Decl(service.ts, 5, 15))
45+
>this : Symbol(MyClass, Decl(service.ts, 3, 1))
46+
>db : Symbol(db, Decl(service.ts, 5, 15))
47+
>doSomething : Symbol(Database.doSomething, Decl(db.ts, 0, 17))
48+
}
49+
}
50+
export {MyClass};
51+
>MyClass : Symbol(MyClass, Decl(service.ts, 13, 8))
52+
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
=== tests/cases/compiler/db.ts ===
2+
export class db {
3+
>db : db
4+
5+
public doSomething() {
6+
>doSomething : () => void
7+
}
8+
}
9+
10+
=== tests/cases/compiler/service.ts ===
11+
import {db as Database} from './db';
12+
>db : typeof Database
13+
>Database : typeof Database
14+
15+
function someDecorator(target) {
16+
>someDecorator : (target: any) => any
17+
>target : any
18+
19+
return target;
20+
>target : any
21+
}
22+
@someDecorator
23+
>someDecorator : (target: any) => any
24+
25+
class MyClass {
26+
>MyClass : MyClass
27+
28+
db: Database;
29+
>db : Database
30+
>Database : Database
31+
32+
constructor(db: Database) { // no collision
33+
>db : Database
34+
>Database : Database
35+
36+
this.db = db;
37+
>this.db = db : Database
38+
>this.db : Database
39+
>this : MyClass
40+
>db : Database
41+
>db : Database
42+
43+
this.db.doSomething();
44+
>this.db.doSomething() : void
45+
>this.db.doSomething : () => void
46+
>this.db : Database
47+
>this : MyClass
48+
>db : Database
49+
>doSomething : () => void
50+
}
51+
}
52+
export {MyClass};
53+
>MyClass : typeof MyClass
54+

0 commit comments

Comments
 (0)