Skip to content

Commit b4e0062

Browse files
committed
Merge branch 'master' into requireJson
2 parents 28a988d + 92ec114 commit b4e0062

242 files changed

Lines changed: 6205 additions & 4701 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.circleci/config.yml

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,10 @@
1-
defaultFilters: &defaultFilters
2-
filters:
3-
branches:
4-
only:
5-
- master
6-
- release-2.5
7-
- release-2.6
8-
- release-2.7
91
workflows:
102
version: 2
113
main:
124
jobs:
13-
- node9:
14-
<<: *defaultFilters
15-
- node8:
16-
<<: *defaultFilters
17-
- node6:
18-
<<: *defaultFilters
5+
- node9
6+
- node8
7+
- node6
198
nightly:
209
triggers:
2110
- schedule:
@@ -25,24 +14,20 @@ workflows:
2514
only: master
2615
jobs:
2716
- node9:
28-
<<: *defaultFilters
2917
context: nightlies
3018
- node8:
31-
<<: *defaultFilters
3219
context: nightlies
3320
- node6:
34-
<<: *defaultFilters
3521
context: nightlies
3622

3723
base: &base
3824
environment:
3925
- workerCount: 4
4026
- timeout: 400000
4127
steps:
42-
- checkout:
43-
post:
44-
- git submodule update --init --recursive
28+
- checkout
4529
- run: |
30+
git submodule update --init --recursive
4631
npm uninstall typescript --no-save
4732
npm uninstall tslint --no-save
4833
npm install

src/compiler/binder.ts

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ namespace ts {
119119
let languageVersion: ScriptTarget;
120120
let parent: Node;
121121
let container: Node;
122+
let containerContainer: Node; // Container one level up
122123
let blockScopeContainer: Node;
123124
let inferenceContainer: Node;
124125
let lastContainer: Node;
@@ -187,6 +188,7 @@ namespace ts {
187188
languageVersion = undefined;
188189
parent = undefined;
189190
container = undefined;
191+
containerContainer = undefined;
190192
blockScopeContainer = undefined;
191193
inferenceContainer = undefined;
192194
lastContainer = undefined;
@@ -224,13 +226,7 @@ namespace ts {
224226
symbol.flags |= symbolFlags;
225227

226228
node.symbol = symbol;
227-
228-
if (!symbol.declarations) {
229-
symbol.declarations = [node];
230-
}
231-
else {
232-
symbol.declarations.push(node);
233-
}
229+
symbol.declarations = append(symbol.declarations, node);
234230

235231
if (symbolFlags & SymbolFlags.HasExports && !symbol.exports) {
236232
symbol.exports = createSymbolTable();
@@ -490,8 +486,11 @@ namespace ts {
490486
// and block-container. Then after we pop out of processing the children, we restore
491487
// these saved values.
492488
const saveContainer = container;
489+
const saveContainerContainer = containerContainer;
493490
const savedBlockScopeContainer = blockScopeContainer;
494491

492+
containerContainer = container;
493+
495494
// Depending on what kind of node this is, we may have to adjust the current container
496495
// and block-container. If the current node is a container, then it is automatically
497496
// considered the current block-container as well. Also, for containers that we know
@@ -584,7 +583,9 @@ namespace ts {
584583
else {
585584
bindChildren(node);
586585
}
586+
587587
container = saveContainer;
588+
containerContainer = saveContainerContainer;
588589
blockScopeContainer = savedBlockScopeContainer;
589590
}
590591

@@ -2338,14 +2339,23 @@ namespace ts {
23382339

23392340
function bindThisPropertyAssignment(node: BinaryExpression | PropertyAccessExpression) {
23402341
Debug.assert(isInJavaScriptFile(node));
2341-
const container = getThisContainer(node, /*includeArrowFunctions*/ false);
2342-
switch (container.kind) {
2342+
const thisContainer = getThisContainer(node, /*includeArrowFunctions*/ false);
2343+
switch (thisContainer.kind) {
23432344
case SyntaxKind.FunctionDeclaration:
23442345
case SyntaxKind.FunctionExpression:
2346+
let constructorSymbol = thisContainer.symbol;
2347+
// For `f.prototype.m = function() { this.x = 0; }`, `this.x = 0` should modify `f`'s members, not the function expression.
2348+
if (isBinaryExpression(thisContainer.parent) && thisContainer.parent.operatorToken.kind === SyntaxKind.EqualsToken) {
2349+
const l = thisContainer.parent.left;
2350+
if (isPropertyAccessEntityNameExpression(l) && isPrototypeAccess(l.expression)) {
2351+
constructorSymbol = getJSInitializerSymbolFromName(l.expression.expression, containerContainer);
2352+
}
2353+
}
2354+
23452355
// Declare a 'member' if the container is an ES5 class or ES6 constructor
2346-
container.symbol.members = container.symbol.members || createSymbolTable();
2356+
constructorSymbol.members = constructorSymbol.members || createSymbolTable();
23472357
// It's acceptable for multiple 'this' assignments of the same identifier to occur
2348-
declareSymbol(container.symbol.members, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property);
2358+
declareSymbol(constructorSymbol.members, constructorSymbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property);
23492359
break;
23502360

23512361
case SyntaxKind.Constructor:
@@ -2355,23 +2365,26 @@ namespace ts {
23552365
case SyntaxKind.SetAccessor:
23562366
// this.foo assignment in a JavaScript class
23572367
// Bind this property to the containing class
2358-
const containingClass = container.parent;
2359-
const symbolTable = hasModifier(container, ModifierFlags.Static) ? containingClass.symbol.exports : containingClass.symbol.members;
2368+
const containingClass = thisContainer.parent;
2369+
const symbolTable = hasModifier(thisContainer, ModifierFlags.Static) ? containingClass.symbol.exports : containingClass.symbol.members;
23602370
declareSymbol(symbolTable, containingClass.symbol, node, SymbolFlags.Property, SymbolFlags.None, /*isReplaceableByMethod*/ true);
23612371
break;
2372+
2373+
default:
2374+
Debug.fail(Debug.showSyntaxKind(thisContainer));
23622375
}
23632376
}
23642377

23652378
function bindSpecialPropertyDeclaration(node: PropertyAccessExpression) {
23662379
if (node.expression.kind === SyntaxKind.ThisKeyword) {
23672380
bindThisPropertyAssignment(node);
23682381
}
2369-
else if (isEntityNameExpression(node) && node.parent.parent.kind === SyntaxKind.SourceFile) {
2370-
if (isPropertyAccessExpression(node.expression) && node.expression.name.escapedText === "prototype") {
2371-
bindPrototypePropertyAssignment(node as PropertyAccessEntityNameExpression, node.parent);
2382+
else if (isPropertyAccessEntityNameExpression(node) && node.parent.parent.kind === SyntaxKind.SourceFile) {
2383+
if (isPrototypeAccess(node.expression)) {
2384+
bindPrototypePropertyAssignment(node, node.parent);
23722385
}
23732386
else {
2374-
bindStaticPropertyAssignment(node as PropertyAccessEntityNameExpression);
2387+
bindStaticPropertyAssignment(node);
23752388
}
23762389
}
23772390
}
@@ -2428,17 +2441,16 @@ namespace ts {
24282441
bindPropertyAssignment(node.expression, node, /*isPrototypeProperty*/ false);
24292442
}
24302443

2444+
function getJSInitializerSymbolFromName(name: EntityNameExpression, lookupContainer?: Node): Symbol {
2445+
return getJSInitializerSymbol(lookupSymbolForPropertyAccess(name, lookupContainer));
2446+
}
2447+
24312448
function bindPropertyAssignment(name: EntityNameExpression, propertyAccess: PropertyAccessEntityNameExpression, isPrototypeProperty: boolean) {
2432-
let symbol = getJSInitializerSymbol(lookupSymbolForPropertyAccess(name));
2433-
let isToplevelNamespaceableInitializer: boolean;
2434-
if (isBinaryExpression(propertyAccess.parent)) {
2435-
const isPrototypeAssignment = isPropertyAccessExpression(propertyAccess.parent.left) && propertyAccess.parent.left.name.escapedText === "prototype";
2436-
isToplevelNamespaceableInitializer = propertyAccess.parent.parent.parent.kind === SyntaxKind.SourceFile &&
2437-
!!getJavascriptInitializer(propertyAccess.parent.right, isPrototypeAssignment);
2438-
}
2439-
else {
2440-
isToplevelNamespaceableInitializer = propertyAccess.parent.parent.kind === SyntaxKind.SourceFile;
2441-
}
2449+
let symbol = getJSInitializerSymbolFromName(name);
2450+
const isToplevelNamespaceableInitializer = isBinaryExpression(propertyAccess.parent)
2451+
? propertyAccess.parent.parent.parent.kind === SyntaxKind.SourceFile &&
2452+
!!getJavascriptInitializer(propertyAccess.parent.right, isPrototypeAccess(propertyAccess.parent.left))
2453+
: propertyAccess.parent.parent.kind === SyntaxKind.SourceFile;
24422454
if (!isPrototypeProperty && (!symbol || !(symbol.flags & SymbolFlags.Namespace)) && isToplevelNamespaceableInitializer) {
24432455
// make symbols or add declarations for intermediate containers
24442456
const flags = SymbolFlags.Module | SymbolFlags.JSContainer;
@@ -2469,9 +2481,9 @@ namespace ts {
24692481
declareSymbol(symbolTable, symbol, propertyAccess, symbolFlags, symbolExcludes);
24702482
}
24712483

2472-
function lookupSymbolForPropertyAccess(node: EntityNameExpression): Symbol | undefined {
2484+
function lookupSymbolForPropertyAccess(node: EntityNameExpression, lookupContainer: Node = container): Symbol | undefined {
24732485
if (isIdentifier(node)) {
2474-
return lookupSymbolForNameWorker(container, node.escapedText);
2486+
return lookupSymbolForNameWorker(lookupContainer, node.escapedText);
24752487
}
24762488
else {
24772489
const symbol = getJSInitializerSymbol(lookupSymbolForPropertyAccess(node.expression));
@@ -2496,7 +2508,7 @@ namespace ts {
24962508
function bindCallExpression(node: CallExpression) {
24972509
// We're only inspecting call expressions to detect CommonJS modules, so we can skip
24982510
// this check if we've already seen the module indicator
2499-
if (!file.commonJsModuleIndicator && isRequireCall(node, /*checkArgumentIsStringLiteral*/ false)) {
2511+
if (!file.commonJsModuleIndicator && isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ false)) {
25002512
setCommonJsModuleIndicator(node);
25012513
}
25022514
}

0 commit comments

Comments
 (0)