Skip to content

Commit e0e6224

Browse files
author
Max Schaefer
authored
Merge pull request github#1298 from asger-semmle/full-mode-fixes-rc120
TS: Backport full-mode fixes to rc/1.20
2 parents 11c1fc8 + 5ed3c50 commit e0e6224

File tree

12 files changed

+93
-5
lines changed

12 files changed

+93
-5
lines changed

javascript/extractor/lib/typescript/src/ast_extractor.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,21 @@ export function augmentAst(ast: AugmentedSourceFile, code: string, project: Proj
156156
}
157157
}
158158

159-
forEachNode(ast, (node: AugmentedNode) => {
159+
// Number of conditional type expressions the visitor is currently inside.
160+
// We disable type extraction inside such type expressions, to avoid complications
161+
// with `infer` types.
162+
let insideConditionalTypes = 0;
163+
164+
visitAstNode(ast);
165+
function visitAstNode(node: AugmentedNode) {
166+
if (node.kind === ts.SyntaxKind.ConditionalType) {
167+
++insideConditionalTypes;
168+
}
169+
ts.forEachChild(node, visitAstNode);
170+
if (node.kind === ts.SyntaxKind.ConditionalType) {
171+
--insideConditionalTypes;
172+
}
173+
160174
// fill in line/column info
161175
if ("pos" in node) {
162176
node.$pos = augmentPos(node.pos, true);
@@ -176,7 +190,7 @@ export function augmentAst(ast: AugmentedSourceFile, code: string, project: Proj
176190
}
177191
}
178192

179-
if (typeChecker != null) {
193+
if (typeChecker != null && insideConditionalTypes === 0) {
180194
if (isTypedNode(node)) {
181195
let type = typeChecker.getTypeAtLocation(node);
182196
if (type != null) {
@@ -247,7 +261,7 @@ export function augmentAst(ast: AugmentedSourceFile, code: string, project: Proj
247261
}
248262
}
249263
}
250-
});
264+
}
251265
}
252266

253267
type NamedNodeWithSymbol = AugmentedNode & (ts.ClassDeclaration | ts.InterfaceDeclaration

javascript/extractor/lib/typescript/src/main.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,9 @@ function handleOpenProjectCommand(command: OpenProjectCommand) {
372372
function getEffectiveExportTarget(symbol: ts.Symbol) {
373373
if (symbol.exports != null && symbol.exports.has(ts.InternalSymbolName.ExportEquals)) {
374374
let exportAlias = symbol.exports.get(ts.InternalSymbolName.ExportEquals);
375-
return typeChecker.getAliasedSymbol(exportAlias);
375+
if (exportAlias.flags & ts.SymbolFlags.Alias) {
376+
return typeChecker.getAliasedSymbol(exportAlias);
377+
}
376378
}
377379
return symbol;
378380
}

javascript/extractor/lib/typescript/src/type_table.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -819,8 +819,24 @@ export class TypeTable {
819819
this.isInShallowTypeContext = false;
820820
}
821821

822+
/**
823+
* Returns the properties of the given type, or `null` if the properties of this
824+
* type could not be computed.
825+
*/
826+
private tryGetProperties(type: ts.Type) {
827+
// Workaround for https://github.com/Microsoft/TypeScript/issues/30845
828+
// Should be safe to remove once that has been fixed.
829+
try {
830+
return type.getProperties();
831+
} catch (e) {
832+
return null;
833+
}
834+
}
835+
822836
private extractProperties(type: ts.Type, id: number) {
823-
for (let symbol of type.getProperties()) {
837+
let props = this.tryGetProperties(type);
838+
if (props == null) return;
839+
for (let symbol of props) {
824840
let propertyType = this.typeChecker.getTypeOfSymbolAtLocation(symbol, this.arbitraryAstNode);
825841
if (propertyType == null) continue;
826842
let propertyTypeId = this.getId(propertyType);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class Foo {}
2+
3+
declare module 'foo' {
4+
export = new Foo();
5+
}
6+
7+
declare module 'bar' {
8+
import * as baz from "baz";
9+
export = baz;
10+
}
11+
12+
declare module 'baz' {
13+
export class C {}
14+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
| "bar" in global scope |
2+
| C in module 'bar' |
3+
| Foo in global scope |
4+
| Foo in tst.ts |
5+
| module 'bar' |
6+
| module 'foo' |
7+
| tst.ts |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import javascript
2+
3+
from CanonicalName name
4+
select name
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"include": ["."],
3+
"compilerOptions": {
4+
"esModuleInterop": true
5+
}
6+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import self from "./tst";
2+
3+
class Foo {}
4+
5+
export = new Foo();
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| Success |
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import javascript
2+
3+
select "Success"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"include": ["."]
3+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
'use strict';
2+
3+
var _myGlobal = this;
4+
5+
module Test {
6+
var global = _myGlobal || {};
7+
8+
export class C {}
9+
10+
export function f(x: C) {
11+
global.field = x || {};
12+
}
13+
}

0 commit comments

Comments
 (0)